initial import from gnunet.git
This commit is contained in:
		
						commit
						1f59e703d8
					
				
							
								
								
									
										674
									
								
								COPYING
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										674
									
								
								COPYING
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,674 @@
 | 
			
		||||
                    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
                       Version 3, 29 June 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 General Public License is a free, copyleft license for
 | 
			
		||||
software and other kinds of works.
 | 
			
		||||
 | 
			
		||||
  The licenses for most software and other practical works are designed
 | 
			
		||||
to take away your freedom to share and change the works.  By contrast,
 | 
			
		||||
the GNU General Public License is 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.  We, the Free Software Foundation, use the
 | 
			
		||||
GNU General Public License for most of our software; it applies also to
 | 
			
		||||
any other work released this way by its authors.  You can apply it to
 | 
			
		||||
your programs, too.
 | 
			
		||||
 | 
			
		||||
  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.
 | 
			
		||||
 | 
			
		||||
  To protect your rights, we need to prevent others from denying you
 | 
			
		||||
these rights or asking you to surrender the rights.  Therefore, you have
 | 
			
		||||
certain responsibilities if you distribute copies of the software, or if
 | 
			
		||||
you modify it: responsibilities to respect the freedom of others.
 | 
			
		||||
 | 
			
		||||
  For example, if you distribute copies of such a program, whether
 | 
			
		||||
gratis or for a fee, you must pass on to the recipients the same
 | 
			
		||||
freedoms that you received.  You must make sure that they, too, receive
 | 
			
		||||
or can get the source code.  And you must show them these terms so they
 | 
			
		||||
know their rights.
 | 
			
		||||
 | 
			
		||||
  Developers that use the GNU GPL protect your rights with two steps:
 | 
			
		||||
(1) assert copyright on the software, and (2) offer you this License
 | 
			
		||||
giving you legal permission to copy, distribute and/or modify it.
 | 
			
		||||
 | 
			
		||||
  For the developers' and authors' protection, the GPL clearly explains
 | 
			
		||||
that there is no warranty for this free software.  For both users' and
 | 
			
		||||
authors' sake, the GPL requires that modified versions be marked as
 | 
			
		||||
changed, so that their problems will not be attributed erroneously to
 | 
			
		||||
authors of previous versions.
 | 
			
		||||
 | 
			
		||||
  Some devices are designed to deny users access to install or run
 | 
			
		||||
modified versions of the software inside them, although the manufacturer
 | 
			
		||||
can do so.  This is fundamentally incompatible with the aim of
 | 
			
		||||
protecting users' freedom to change the software.  The systematic
 | 
			
		||||
pattern of such abuse occurs in the area of products for individuals to
 | 
			
		||||
use, which is precisely where it is most unacceptable.  Therefore, we
 | 
			
		||||
have designed this version of the GPL to prohibit the practice for those
 | 
			
		||||
products.  If such problems arise substantially in other domains, we
 | 
			
		||||
stand ready to extend this provision to those domains in future versions
 | 
			
		||||
of the GPL, as needed to protect the freedom of users.
 | 
			
		||||
 | 
			
		||||
  Finally, every program is threatened constantly by software patents.
 | 
			
		||||
States should not allow patents to restrict development and use of
 | 
			
		||||
software on general-purpose computers, but in those that do, we wish to
 | 
			
		||||
avoid the special danger that patents applied to a free program could
 | 
			
		||||
make it effectively proprietary.  To prevent this, the GPL assures that
 | 
			
		||||
patents cannot be used to render the program non-free.
 | 
			
		||||
 | 
			
		||||
  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 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. Use with the GNU Affero General Public License.
 | 
			
		||||
 | 
			
		||||
  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 Affero 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 special requirements of the GNU Affero General Public License,
 | 
			
		||||
section 13, concerning interaction through a network will apply to the
 | 
			
		||||
combination as such.
 | 
			
		||||
 | 
			
		||||
  14. Revised Versions of this License.
 | 
			
		||||
 | 
			
		||||
  The Free Software Foundation may publish revised and/or new versions of
 | 
			
		||||
the GNU 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 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 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 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 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 General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU 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 the program does terminal interaction, make it output a short
 | 
			
		||||
notice like this when it starts in an interactive mode:
 | 
			
		||||
 | 
			
		||||
    <program>  Copyright (C) <year>  <name of author>
 | 
			
		||||
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 | 
			
		||||
    This is free software, and you are welcome to redistribute it
 | 
			
		||||
    under certain conditions; type `show c' for details.
 | 
			
		||||
 | 
			
		||||
The hypothetical commands `show w' and `show c' should show the appropriate
 | 
			
		||||
parts of the General Public License.  Of course, your program's commands
 | 
			
		||||
might be different; for a GUI interface, you would use an "about box".
 | 
			
		||||
 | 
			
		||||
  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 GPL, see
 | 
			
		||||
<http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
  The GNU General Public License does not permit incorporating your program
 | 
			
		||||
into proprietary programs.  If your program is a subroutine library, you
 | 
			
		||||
may consider it more useful to permit linking proprietary applications with
 | 
			
		||||
the library.  If this is what you want to do, use the GNU Lesser General
 | 
			
		||||
Public License instead of this License.  But first, please read
 | 
			
		||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
 | 
			
		||||
							
								
								
									
										14
									
								
								ChangeLog
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								ChangeLog
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
2012-03-07  gettextize  <bug-gnu-gettext@gnu.org>
 | 
			
		||||
 | 
			
		||||
	* m4/gettext.m4: New file, from gettext-0.18.1.
 | 
			
		||||
	* m4/iconv.m4: New file, from gettext-0.18.1.
 | 
			
		||||
	* m4/lib-ld.m4: New file, from gettext-0.18.1.
 | 
			
		||||
	* m4/lib-link.m4: New file, from gettext-0.18.1.
 | 
			
		||||
	* m4/lib-prefix.m4: New file, from gettext-0.18.1.
 | 
			
		||||
	* m4/nls.m4: New file, from gettext-0.18.1.
 | 
			
		||||
	* m4/po.m4: New file, from gettext-0.18.1.
 | 
			
		||||
	* m4/progtest.m4: New file, from gettext-0.18.1.
 | 
			
		||||
	* Makefile.am (SUBDIRS): Add po.
 | 
			
		||||
	* configure.ac (AC_OUTPUT): Add po/Makefile.in.
 | 
			
		||||
	(AM_GNU_GETTEXT_VERSION): Bump to 0.18.1.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										365
									
								
								INSTALL
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										365
									
								
								INSTALL
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,365 @@
 | 
			
		||||
Installation Instructions
 | 
			
		||||
*************************
 | 
			
		||||
 | 
			
		||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
 | 
			
		||||
2006, 2007, 2008, 2009 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 commands `./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.
 | 
			
		||||
 | 
			
		||||
   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 bug.  Until the bug is fixed you can use this workaround:
 | 
			
		||||
 | 
			
		||||
     CONFIG_SHELL=/bin/bash /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.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
# This Makefile.am is in the public domain
 | 
			
		||||
## Process this file with automake to produce Makefile.in
 | 
			
		||||
 | 
			
		||||
SUBDIRS = src po pkgconfig
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = config.rpath  \
 | 
			
		||||
  install-sh
 | 
			
		||||
 | 
			
		||||
ACLOCAL_AMFLAGS = -I m4
 | 
			
		||||
							
								
								
									
										8
									
								
								bootstrap
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										8
									
								
								bootstrap
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
libtoolize --automake --copy --force
 | 
			
		||||
aclocal -I m4
 | 
			
		||||
autoheader
 | 
			
		||||
autoconf
 | 
			
		||||
automake --add-missing --copy
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										672
									
								
								config.rpath
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										672
									
								
								config.rpath
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,672 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
# Output a system dependent set of variables, describing how to set the
 | 
			
		||||
# run time search path of shared libraries in an executable.
 | 
			
		||||
#
 | 
			
		||||
#   Copyright 1996-2010 Free Software Foundation, Inc.
 | 
			
		||||
#   Taken from GNU libtool, 2001
 | 
			
		||||
#   Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
 | 
			
		||||
#
 | 
			
		||||
#   This file is free software; the Free Software Foundation gives
 | 
			
		||||
#   unlimited permission to copy and/or distribute it, with or without
 | 
			
		||||
#   modifications, as long as this notice is preserved.
 | 
			
		||||
#
 | 
			
		||||
# The first argument passed to this file is the canonical host specification,
 | 
			
		||||
#    CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
 | 
			
		||||
# or
 | 
			
		||||
#    CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
 | 
			
		||||
# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
 | 
			
		||||
# should be set by the caller.
 | 
			
		||||
#
 | 
			
		||||
# The set of defined variables is at the end of this script.
 | 
			
		||||
 | 
			
		||||
# Known limitations:
 | 
			
		||||
# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
 | 
			
		||||
#   than 256 bytes, otherwise the compiler driver will dump core. The only
 | 
			
		||||
#   known workaround is to choose shorter directory names for the build
 | 
			
		||||
#   directory and/or the installation directory.
 | 
			
		||||
 | 
			
		||||
# All known linkers require a `.a' archive for static linking (except MSVC,
 | 
			
		||||
# which needs '.lib').
 | 
			
		||||
libext=a
 | 
			
		||||
shrext=.so
 | 
			
		||||
 | 
			
		||||
host="$1"
 | 
			
		||||
host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
 | 
			
		||||
host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
 | 
			
		||||
host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 | 
			
		||||
 | 
			
		||||
# Code taken from libtool.m4's _LT_CC_BASENAME.
 | 
			
		||||
 | 
			
		||||
for cc_temp in $CC""; do
 | 
			
		||||
  case $cc_temp in
 | 
			
		||||
    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
 | 
			
		||||
    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
 | 
			
		||||
    \-*) ;;
 | 
			
		||||
    *) break;;
 | 
			
		||||
  esac
 | 
			
		||||
done
 | 
			
		||||
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
 | 
			
		||||
 | 
			
		||||
# Code taken from libtool.m4's _LT_COMPILER_PIC.
 | 
			
		||||
 | 
			
		||||
wl=
 | 
			
		||||
if test "$GCC" = yes; then
 | 
			
		||||
  wl='-Wl,'
 | 
			
		||||
else
 | 
			
		||||
  case "$host_os" in
 | 
			
		||||
    aix*)
 | 
			
		||||
      wl='-Wl,'
 | 
			
		||||
      ;;
 | 
			
		||||
    darwin*)
 | 
			
		||||
      case $cc_basename in
 | 
			
		||||
        xlc*)
 | 
			
		||||
          wl='-Wl,'
 | 
			
		||||
          ;;
 | 
			
		||||
      esac
 | 
			
		||||
      ;;
 | 
			
		||||
    mingw* | cygwin* | pw32* | os2* | cegcc*)
 | 
			
		||||
      ;;
 | 
			
		||||
    hpux9* | hpux10* | hpux11*)
 | 
			
		||||
      wl='-Wl,'
 | 
			
		||||
      ;;
 | 
			
		||||
    irix5* | irix6* | nonstopux*)
 | 
			
		||||
      wl='-Wl,'
 | 
			
		||||
      ;;
 | 
			
		||||
    newsos6)
 | 
			
		||||
      ;;
 | 
			
		||||
    linux* | k*bsd*-gnu)
 | 
			
		||||
      case $cc_basename in
 | 
			
		||||
        ecc*)
 | 
			
		||||
          wl='-Wl,'
 | 
			
		||||
          ;;
 | 
			
		||||
        icc* | ifort*)
 | 
			
		||||
          wl='-Wl,'
 | 
			
		||||
          ;;
 | 
			
		||||
        lf95*)
 | 
			
		||||
          wl='-Wl,'
 | 
			
		||||
          ;;
 | 
			
		||||
        pgcc | pgf77 | pgf90)
 | 
			
		||||
          wl='-Wl,'
 | 
			
		||||
          ;;
 | 
			
		||||
        ccc*)
 | 
			
		||||
          wl='-Wl,'
 | 
			
		||||
          ;;
 | 
			
		||||
        como)
 | 
			
		||||
          wl='-lopt='
 | 
			
		||||
          ;;
 | 
			
		||||
        *)
 | 
			
		||||
          case `$CC -V 2>&1 | sed 5q` in
 | 
			
		||||
            *Sun\ C*)
 | 
			
		||||
              wl='-Wl,'
 | 
			
		||||
              ;;
 | 
			
		||||
          esac
 | 
			
		||||
          ;;
 | 
			
		||||
      esac
 | 
			
		||||
      ;;
 | 
			
		||||
    osf3* | osf4* | osf5*)
 | 
			
		||||
      wl='-Wl,'
 | 
			
		||||
      ;;
 | 
			
		||||
    rdos*)
 | 
			
		||||
      ;;
 | 
			
		||||
    solaris*)
 | 
			
		||||
      wl='-Wl,'
 | 
			
		||||
      ;;
 | 
			
		||||
    sunos4*)
 | 
			
		||||
      wl='-Qoption ld '
 | 
			
		||||
      ;;
 | 
			
		||||
    sysv4 | sysv4.2uw2* | sysv4.3*)
 | 
			
		||||
      wl='-Wl,'
 | 
			
		||||
      ;;
 | 
			
		||||
    sysv4*MP*)
 | 
			
		||||
      ;;
 | 
			
		||||
    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
 | 
			
		||||
      wl='-Wl,'
 | 
			
		||||
      ;;
 | 
			
		||||
    unicos*)
 | 
			
		||||
      wl='-Wl,'
 | 
			
		||||
      ;;
 | 
			
		||||
    uts4*)
 | 
			
		||||
      ;;
 | 
			
		||||
  esac
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
 | 
			
		||||
 | 
			
		||||
hardcode_libdir_flag_spec=
 | 
			
		||||
hardcode_libdir_separator=
 | 
			
		||||
hardcode_direct=no
 | 
			
		||||
hardcode_minus_L=no
 | 
			
		||||
 | 
			
		||||
case "$host_os" in
 | 
			
		||||
  cygwin* | mingw* | pw32* | cegcc*)
 | 
			
		||||
    # FIXME: the MSVC++ port hasn't been tested in a loooong time
 | 
			
		||||
    # When not using gcc, we currently assume that we are using
 | 
			
		||||
    # Microsoft Visual C++.
 | 
			
		||||
    if test "$GCC" != yes; then
 | 
			
		||||
      with_gnu_ld=no
 | 
			
		||||
    fi
 | 
			
		||||
    ;;
 | 
			
		||||
  interix*)
 | 
			
		||||
    # we just hope/assume this is gcc and not c89 (= MSVC++)
 | 
			
		||||
    with_gnu_ld=yes
 | 
			
		||||
    ;;
 | 
			
		||||
  openbsd*)
 | 
			
		||||
    with_gnu_ld=no
 | 
			
		||||
    ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
ld_shlibs=yes
 | 
			
		||||
if test "$with_gnu_ld" = yes; then
 | 
			
		||||
  # Set some defaults for GNU ld with shared library support. These
 | 
			
		||||
  # are reset later if shared libraries are not supported. Putting them
 | 
			
		||||
  # here allows them to be overridden if necessary.
 | 
			
		||||
  # Unlike libtool, we use -rpath here, not --rpath, since the documented
 | 
			
		||||
  # option of GNU ld is called -rpath, not --rpath.
 | 
			
		||||
  hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
 | 
			
		||||
  case "$host_os" in
 | 
			
		||||
    aix[3-9]*)
 | 
			
		||||
      # On AIX/PPC, the GNU linker is very broken
 | 
			
		||||
      if test "$host_cpu" != ia64; then
 | 
			
		||||
        ld_shlibs=no
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    amigaos*)
 | 
			
		||||
      hardcode_libdir_flag_spec='-L$libdir'
 | 
			
		||||
      hardcode_minus_L=yes
 | 
			
		||||
      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
 | 
			
		||||
      # that the semantics of dynamic libraries on AmigaOS, at least up
 | 
			
		||||
      # to version 4, is to share data among multiple programs linked
 | 
			
		||||
      # with the same dynamic library.  Since this doesn't match the
 | 
			
		||||
      # behavior of shared libraries on other platforms, we cannot use
 | 
			
		||||
      # them.
 | 
			
		||||
      ld_shlibs=no
 | 
			
		||||
      ;;
 | 
			
		||||
    beos*)
 | 
			
		||||
      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
 | 
			
		||||
        :
 | 
			
		||||
      else
 | 
			
		||||
        ld_shlibs=no
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    cygwin* | mingw* | pw32* | cegcc*)
 | 
			
		||||
      # hardcode_libdir_flag_spec is actually meaningless, as there is
 | 
			
		||||
      # no search path for DLLs.
 | 
			
		||||
      hardcode_libdir_flag_spec='-L$libdir'
 | 
			
		||||
      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
 | 
			
		||||
        :
 | 
			
		||||
      else
 | 
			
		||||
        ld_shlibs=no
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    interix[3-9]*)
 | 
			
		||||
      hardcode_direct=no
 | 
			
		||||
      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
 | 
			
		||||
      ;;
 | 
			
		||||
    gnu* | linux* | k*bsd*-gnu)
 | 
			
		||||
      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
 | 
			
		||||
        :
 | 
			
		||||
      else
 | 
			
		||||
        ld_shlibs=no
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    netbsd*)
 | 
			
		||||
      ;;
 | 
			
		||||
    solaris*)
 | 
			
		||||
      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
 | 
			
		||||
        ld_shlibs=no
 | 
			
		||||
      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
 | 
			
		||||
        :
 | 
			
		||||
      else
 | 
			
		||||
        ld_shlibs=no
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
 | 
			
		||||
      case `$LD -v 2>&1` in
 | 
			
		||||
        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
 | 
			
		||||
          ld_shlibs=no
 | 
			
		||||
          ;;
 | 
			
		||||
        *)
 | 
			
		||||
          if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
 | 
			
		||||
            hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
 | 
			
		||||
          else
 | 
			
		||||
            ld_shlibs=no
 | 
			
		||||
          fi
 | 
			
		||||
          ;;
 | 
			
		||||
      esac
 | 
			
		||||
      ;;
 | 
			
		||||
    sunos4*)
 | 
			
		||||
      hardcode_direct=yes
 | 
			
		||||
      ;;
 | 
			
		||||
    *)
 | 
			
		||||
      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
 | 
			
		||||
        :
 | 
			
		||||
      else
 | 
			
		||||
        ld_shlibs=no
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
  esac
 | 
			
		||||
  if test "$ld_shlibs" = no; then
 | 
			
		||||
    hardcode_libdir_flag_spec=
 | 
			
		||||
  fi
 | 
			
		||||
else
 | 
			
		||||
  case "$host_os" in
 | 
			
		||||
    aix3*)
 | 
			
		||||
      # Note: this linker hardcodes the directories in LIBPATH if there
 | 
			
		||||
      # are no directories specified by -L.
 | 
			
		||||
      hardcode_minus_L=yes
 | 
			
		||||
      if test "$GCC" = yes; then
 | 
			
		||||
        # Neither direct hardcoding nor static linking is supported with a
 | 
			
		||||
        # broken collect2.
 | 
			
		||||
        hardcode_direct=unsupported
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    aix[4-9]*)
 | 
			
		||||
      if test "$host_cpu" = ia64; then
 | 
			
		||||
        # On IA64, the linker does run time linking by default, so we don't
 | 
			
		||||
        # have to do anything special.
 | 
			
		||||
        aix_use_runtimelinking=no
 | 
			
		||||
      else
 | 
			
		||||
        aix_use_runtimelinking=no
 | 
			
		||||
        # Test if we are trying to use run time linking or normal
 | 
			
		||||
        # AIX style linking. If -brtl is somewhere in LDFLAGS, we
 | 
			
		||||
        # need to do runtime linking.
 | 
			
		||||
        case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
 | 
			
		||||
          for ld_flag in $LDFLAGS; do
 | 
			
		||||
            if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
 | 
			
		||||
              aix_use_runtimelinking=yes
 | 
			
		||||
              break
 | 
			
		||||
            fi
 | 
			
		||||
          done
 | 
			
		||||
          ;;
 | 
			
		||||
        esac
 | 
			
		||||
      fi
 | 
			
		||||
      hardcode_direct=yes
 | 
			
		||||
      hardcode_libdir_separator=':'
 | 
			
		||||
      if test "$GCC" = yes; then
 | 
			
		||||
        case $host_os in aix4.[012]|aix4.[012].*)
 | 
			
		||||
          collect2name=`${CC} -print-prog-name=collect2`
 | 
			
		||||
          if test -f "$collect2name" && \
 | 
			
		||||
            strings "$collect2name" | grep resolve_lib_name >/dev/null
 | 
			
		||||
          then
 | 
			
		||||
            # We have reworked collect2
 | 
			
		||||
            :
 | 
			
		||||
          else
 | 
			
		||||
            # We have old collect2
 | 
			
		||||
            hardcode_direct=unsupported
 | 
			
		||||
            hardcode_minus_L=yes
 | 
			
		||||
            hardcode_libdir_flag_spec='-L$libdir'
 | 
			
		||||
            hardcode_libdir_separator=
 | 
			
		||||
          fi
 | 
			
		||||
          ;;
 | 
			
		||||
        esac
 | 
			
		||||
      fi
 | 
			
		||||
      # Begin _LT_AC_SYS_LIBPATH_AIX.
 | 
			
		||||
      echo 'int main () { return 0; }' > conftest.c
 | 
			
		||||
      ${CC} ${LDFLAGS} conftest.c -o conftest
 | 
			
		||||
      aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
 | 
			
		||||
}'`
 | 
			
		||||
      if test -z "$aix_libpath"; then
 | 
			
		||||
        aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
 | 
			
		||||
}'`
 | 
			
		||||
      fi
 | 
			
		||||
      if test -z "$aix_libpath"; then
 | 
			
		||||
        aix_libpath="/usr/lib:/lib"
 | 
			
		||||
      fi
 | 
			
		||||
      rm -f conftest.c conftest
 | 
			
		||||
      # End _LT_AC_SYS_LIBPATH_AIX.
 | 
			
		||||
      if test "$aix_use_runtimelinking" = yes; then
 | 
			
		||||
        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
 | 
			
		||||
      else
 | 
			
		||||
        if test "$host_cpu" = ia64; then
 | 
			
		||||
          hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
 | 
			
		||||
        else
 | 
			
		||||
          hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
 | 
			
		||||
        fi
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    amigaos*)
 | 
			
		||||
      hardcode_libdir_flag_spec='-L$libdir'
 | 
			
		||||
      hardcode_minus_L=yes
 | 
			
		||||
      # see comment about different semantics on the GNU ld section
 | 
			
		||||
      ld_shlibs=no
 | 
			
		||||
      ;;
 | 
			
		||||
    bsdi[45]*)
 | 
			
		||||
      ;;
 | 
			
		||||
    cygwin* | mingw* | pw32* | cegcc*)
 | 
			
		||||
      # When not using gcc, we currently assume that we are using
 | 
			
		||||
      # Microsoft Visual C++.
 | 
			
		||||
      # hardcode_libdir_flag_spec is actually meaningless, as there is
 | 
			
		||||
      # no search path for DLLs.
 | 
			
		||||
      hardcode_libdir_flag_spec=' '
 | 
			
		||||
      libext=lib
 | 
			
		||||
      ;;
 | 
			
		||||
    darwin* | rhapsody*)
 | 
			
		||||
      hardcode_direct=no
 | 
			
		||||
      if test "$GCC" = yes ; then
 | 
			
		||||
        :
 | 
			
		||||
      else
 | 
			
		||||
        case $cc_basename in
 | 
			
		||||
          xlc*)
 | 
			
		||||
            ;;
 | 
			
		||||
          *)
 | 
			
		||||
            ld_shlibs=no
 | 
			
		||||
            ;;
 | 
			
		||||
        esac
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    dgux*)
 | 
			
		||||
      hardcode_libdir_flag_spec='-L$libdir'
 | 
			
		||||
      ;;
 | 
			
		||||
    freebsd1*)
 | 
			
		||||
      ld_shlibs=no
 | 
			
		||||
      ;;
 | 
			
		||||
    freebsd2.2*)
 | 
			
		||||
      hardcode_libdir_flag_spec='-R$libdir'
 | 
			
		||||
      hardcode_direct=yes
 | 
			
		||||
      ;;
 | 
			
		||||
    freebsd2*)
 | 
			
		||||
      hardcode_direct=yes
 | 
			
		||||
      hardcode_minus_L=yes
 | 
			
		||||
      ;;
 | 
			
		||||
    freebsd* | dragonfly*)
 | 
			
		||||
      hardcode_libdir_flag_spec='-R$libdir'
 | 
			
		||||
      hardcode_direct=yes
 | 
			
		||||
      ;;
 | 
			
		||||
    hpux9*)
 | 
			
		||||
      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
 | 
			
		||||
      hardcode_libdir_separator=:
 | 
			
		||||
      hardcode_direct=yes
 | 
			
		||||
      # hardcode_minus_L: Not really in the search PATH,
 | 
			
		||||
      # but as the default location of the library.
 | 
			
		||||
      hardcode_minus_L=yes
 | 
			
		||||
      ;;
 | 
			
		||||
    hpux10*)
 | 
			
		||||
      if test "$with_gnu_ld" = no; then
 | 
			
		||||
        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
 | 
			
		||||
        hardcode_libdir_separator=:
 | 
			
		||||
        hardcode_direct=yes
 | 
			
		||||
        # hardcode_minus_L: Not really in the search PATH,
 | 
			
		||||
        # but as the default location of the library.
 | 
			
		||||
        hardcode_minus_L=yes
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    hpux11*)
 | 
			
		||||
      if test "$with_gnu_ld" = no; then
 | 
			
		||||
        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
 | 
			
		||||
        hardcode_libdir_separator=:
 | 
			
		||||
        case $host_cpu in
 | 
			
		||||
          hppa*64*|ia64*)
 | 
			
		||||
            hardcode_direct=no
 | 
			
		||||
            ;;
 | 
			
		||||
          *)
 | 
			
		||||
            hardcode_direct=yes
 | 
			
		||||
            # hardcode_minus_L: Not really in the search PATH,
 | 
			
		||||
            # but as the default location of the library.
 | 
			
		||||
            hardcode_minus_L=yes
 | 
			
		||||
            ;;
 | 
			
		||||
        esac
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    irix5* | irix6* | nonstopux*)
 | 
			
		||||
      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
 | 
			
		||||
      hardcode_libdir_separator=:
 | 
			
		||||
      ;;
 | 
			
		||||
    netbsd*)
 | 
			
		||||
      hardcode_libdir_flag_spec='-R$libdir'
 | 
			
		||||
      hardcode_direct=yes
 | 
			
		||||
      ;;
 | 
			
		||||
    newsos6)
 | 
			
		||||
      hardcode_direct=yes
 | 
			
		||||
      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
 | 
			
		||||
      hardcode_libdir_separator=:
 | 
			
		||||
      ;;
 | 
			
		||||
    openbsd*)
 | 
			
		||||
      if test -f /usr/libexec/ld.so; then
 | 
			
		||||
        hardcode_direct=yes
 | 
			
		||||
        if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
 | 
			
		||||
          hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
 | 
			
		||||
        else
 | 
			
		||||
          case "$host_os" in
 | 
			
		||||
            openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
 | 
			
		||||
              hardcode_libdir_flag_spec='-R$libdir'
 | 
			
		||||
              ;;
 | 
			
		||||
            *)
 | 
			
		||||
              hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
 | 
			
		||||
              ;;
 | 
			
		||||
          esac
 | 
			
		||||
        fi
 | 
			
		||||
      else
 | 
			
		||||
        ld_shlibs=no
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    os2*)
 | 
			
		||||
      hardcode_libdir_flag_spec='-L$libdir'
 | 
			
		||||
      hardcode_minus_L=yes
 | 
			
		||||
      ;;
 | 
			
		||||
    osf3*)
 | 
			
		||||
      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
 | 
			
		||||
      hardcode_libdir_separator=:
 | 
			
		||||
      ;;
 | 
			
		||||
    osf4* | osf5*)
 | 
			
		||||
      if test "$GCC" = yes; then
 | 
			
		||||
        hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
 | 
			
		||||
      else
 | 
			
		||||
        # Both cc and cxx compiler support -rpath directly
 | 
			
		||||
        hardcode_libdir_flag_spec='-rpath $libdir'
 | 
			
		||||
      fi
 | 
			
		||||
      hardcode_libdir_separator=:
 | 
			
		||||
      ;;
 | 
			
		||||
    solaris*)
 | 
			
		||||
      hardcode_libdir_flag_spec='-R$libdir'
 | 
			
		||||
      ;;
 | 
			
		||||
    sunos4*)
 | 
			
		||||
      hardcode_libdir_flag_spec='-L$libdir'
 | 
			
		||||
      hardcode_direct=yes
 | 
			
		||||
      hardcode_minus_L=yes
 | 
			
		||||
      ;;
 | 
			
		||||
    sysv4)
 | 
			
		||||
      case $host_vendor in
 | 
			
		||||
        sni)
 | 
			
		||||
          hardcode_direct=yes # is this really true???
 | 
			
		||||
          ;;
 | 
			
		||||
        siemens)
 | 
			
		||||
          hardcode_direct=no
 | 
			
		||||
          ;;
 | 
			
		||||
        motorola)
 | 
			
		||||
          hardcode_direct=no #Motorola manual says yes, but my tests say they lie
 | 
			
		||||
          ;;
 | 
			
		||||
      esac
 | 
			
		||||
      ;;
 | 
			
		||||
    sysv4.3*)
 | 
			
		||||
      ;;
 | 
			
		||||
    sysv4*MP*)
 | 
			
		||||
      if test -d /usr/nec; then
 | 
			
		||||
        ld_shlibs=yes
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
 | 
			
		||||
      ;;
 | 
			
		||||
    sysv5* | sco3.2v5* | sco5v6*)
 | 
			
		||||
      hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
 | 
			
		||||
      hardcode_libdir_separator=':'
 | 
			
		||||
      ;;
 | 
			
		||||
    uts4*)
 | 
			
		||||
      hardcode_libdir_flag_spec='-L$libdir'
 | 
			
		||||
      ;;
 | 
			
		||||
    *)
 | 
			
		||||
      ld_shlibs=no
 | 
			
		||||
      ;;
 | 
			
		||||
  esac
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Check dynamic linker characteristics
 | 
			
		||||
# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
 | 
			
		||||
# Unlike libtool.m4, here we don't care about _all_ names of the library, but
 | 
			
		||||
# only about the one the linker finds when passed -lNAME. This is the last
 | 
			
		||||
# element of library_names_spec in libtool.m4, or possibly two of them if the
 | 
			
		||||
# linker has special search rules.
 | 
			
		||||
library_names_spec=      # the last element of library_names_spec in libtool.m4
 | 
			
		||||
libname_spec='lib$name'
 | 
			
		||||
case "$host_os" in
 | 
			
		||||
  aix3*)
 | 
			
		||||
    library_names_spec='$libname.a'
 | 
			
		||||
    ;;
 | 
			
		||||
  aix[4-9]*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  amigaos*)
 | 
			
		||||
    library_names_spec='$libname.a'
 | 
			
		||||
    ;;
 | 
			
		||||
  beos*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  bsdi[45]*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  cygwin* | mingw* | pw32* | cegcc*)
 | 
			
		||||
    shrext=.dll
 | 
			
		||||
    library_names_spec='$libname.dll.a $libname.lib'
 | 
			
		||||
    ;;
 | 
			
		||||
  darwin* | rhapsody*)
 | 
			
		||||
    shrext=.dylib
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  dgux*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  freebsd1*)
 | 
			
		||||
    ;;
 | 
			
		||||
  freebsd* | dragonfly*)
 | 
			
		||||
    case "$host_os" in
 | 
			
		||||
      freebsd[123]*)
 | 
			
		||||
        library_names_spec='$libname$shrext$versuffix' ;;
 | 
			
		||||
      *)
 | 
			
		||||
        library_names_spec='$libname$shrext' ;;
 | 
			
		||||
    esac
 | 
			
		||||
    ;;
 | 
			
		||||
  gnu*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  hpux9* | hpux10* | hpux11*)
 | 
			
		||||
    case $host_cpu in
 | 
			
		||||
      ia64*)
 | 
			
		||||
        shrext=.so
 | 
			
		||||
        ;;
 | 
			
		||||
      hppa*64*)
 | 
			
		||||
        shrext=.sl
 | 
			
		||||
        ;;
 | 
			
		||||
      *)
 | 
			
		||||
        shrext=.sl
 | 
			
		||||
        ;;
 | 
			
		||||
    esac
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  interix[3-9]*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  irix5* | irix6* | nonstopux*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    case "$host_os" in
 | 
			
		||||
      irix5* | nonstopux*)
 | 
			
		||||
        libsuff= shlibsuff=
 | 
			
		||||
        ;;
 | 
			
		||||
      *)
 | 
			
		||||
        case $LD in
 | 
			
		||||
          *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
 | 
			
		||||
          *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
 | 
			
		||||
          *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
 | 
			
		||||
          *) libsuff= shlibsuff= ;;
 | 
			
		||||
        esac
 | 
			
		||||
        ;;
 | 
			
		||||
    esac
 | 
			
		||||
    ;;
 | 
			
		||||
  linux*oldld* | linux*aout* | linux*coff*)
 | 
			
		||||
    ;;
 | 
			
		||||
  linux* | k*bsd*-gnu)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  knetbsd*-gnu)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  netbsd*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  newsos6)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  nto-qnx*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  openbsd*)
 | 
			
		||||
    library_names_spec='$libname$shrext$versuffix'
 | 
			
		||||
    ;;
 | 
			
		||||
  os2*)
 | 
			
		||||
    libname_spec='$name'
 | 
			
		||||
    shrext=.dll
 | 
			
		||||
    library_names_spec='$libname.a'
 | 
			
		||||
    ;;
 | 
			
		||||
  osf3* | osf4* | osf5*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  rdos*)
 | 
			
		||||
    ;;
 | 
			
		||||
  solaris*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  sunos4*)
 | 
			
		||||
    library_names_spec='$libname$shrext$versuffix'
 | 
			
		||||
    ;;
 | 
			
		||||
  sysv4 | sysv4.3*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  sysv4*MP*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
  uts4*)
 | 
			
		||||
    library_names_spec='$libname$shrext'
 | 
			
		||||
    ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
 | 
			
		||||
escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
 | 
			
		||||
shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
 | 
			
		||||
escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
 | 
			
		||||
escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
 | 
			
		||||
escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
 | 
			
		||||
 | 
			
		||||
LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
 | 
			
		||||
 | 
			
		||||
# How to pass a linker flag through the compiler.
 | 
			
		||||
wl="$escaped_wl"
 | 
			
		||||
 | 
			
		||||
# Static library suffix (normally "a").
 | 
			
		||||
libext="$libext"
 | 
			
		||||
 | 
			
		||||
# Shared library suffix (normally "so").
 | 
			
		||||
shlibext="$shlibext"
 | 
			
		||||
 | 
			
		||||
# Format of library name prefix.
 | 
			
		||||
libname_spec="$escaped_libname_spec"
 | 
			
		||||
 | 
			
		||||
# Library names that the linker finds when passed -lNAME.
 | 
			
		||||
library_names_spec="$escaped_library_names_spec"
 | 
			
		||||
 | 
			
		||||
# Flag to hardcode \$libdir into a binary during linking.
 | 
			
		||||
# This must work even if \$libdir does not exist.
 | 
			
		||||
hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
 | 
			
		||||
 | 
			
		||||
# Whether we need a single -rpath flag with a separated argument.
 | 
			
		||||
hardcode_libdir_separator="$hardcode_libdir_separator"
 | 
			
		||||
 | 
			
		||||
# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
 | 
			
		||||
# resulting binary.
 | 
			
		||||
hardcode_direct="$hardcode_direct"
 | 
			
		||||
 | 
			
		||||
# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
 | 
			
		||||
# resulting binary.
 | 
			
		||||
hardcode_minus_L="$hardcode_minus_L"
 | 
			
		||||
 | 
			
		||||
EOF
 | 
			
		||||
							
								
								
									
										221
									
								
								configure.ac
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								configure.ac
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,221 @@
 | 
			
		||||
# This file is part of GNUnet.
 | 
			
		||||
# (C) 2001-2019 Christian Grothoff (and other contributing authors)
 | 
			
		||||
#
 | 
			
		||||
# GNUnet 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 2, or (at your
 | 
			
		||||
# option) any later version.
 | 
			
		||||
#
 | 
			
		||||
# GNUnet 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 GNUnet; see the file COPYING.  If not, write to the
 | 
			
		||||
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 | 
			
		||||
# Boston, MA 02110-1301, USA.
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# Process this file with autoconf to produce a configure script.
 | 
			
		||||
#
 | 
			
		||||
AC_PREREQ(2.61)
 | 
			
		||||
AC_INIT([gnunet-secushare],[0.0.0],[bug-gnunet@gnu.org])
 | 
			
		||||
AM_INIT_AUTOMAKE([gnunet-secushare], [0.0.0])
 | 
			
		||||
AM_CONFIG_HEADER(gnunet_secushare_config.h)
 | 
			
		||||
 | 
			
		||||
AH_TOP([#define _GNU_SOURCE  1])
 | 
			
		||||
 | 
			
		||||
AC_ISC_POSIX
 | 
			
		||||
AC_PROG_AWK
 | 
			
		||||
AC_PROG_CC
 | 
			
		||||
 | 
			
		||||
AC_PROG_MKDIR_P
 | 
			
		||||
AC_PROG_CPP
 | 
			
		||||
AC_PROG_INSTALL
 | 
			
		||||
AC_PROG_LN_S
 | 
			
		||||
AC_PROG_MAKE_SET
 | 
			
		||||
AC_LIBTOOL_WIN32_DLL
 | 
			
		||||
AC_PROG_CC
 | 
			
		||||
AM_PROG_CC_STDC
 | 
			
		||||
AC_HEADER_STDC
 | 
			
		||||
AC_CANONICAL_HOST
 | 
			
		||||
 | 
			
		||||
# dynamic libraries/plugins
 | 
			
		||||
AC_DISABLE_STATIC
 | 
			
		||||
AC_PROG_LIBTOOL
 | 
			
		||||
 | 
			
		||||
AC_SYS_LARGEFILE
 | 
			
		||||
AC_FUNC_FSEEKO
 | 
			
		||||
 | 
			
		||||
CFLAGS="-Wall $CFLAGS"
 | 
			
		||||
# use '-fno-strict-aliasing', but only if the compiler can take it
 | 
			
		||||
if gcc -fno-strict-aliasing -S -o /dev/null -xc /dev/null >/dev/null 2>&1;
 | 
			
		||||
then
 | 
			
		||||
 CFLAGS="-fno-strict-aliasing $CFLAGS"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Check system type
 | 
			
		||||
case "$host_os" in
 | 
			
		||||
*darwin* | *rhapsody* | *macosx*)
 | 
			
		||||
     AC_DEFINE_UNQUOTED(OSX,1,[This is an OS X system])
 | 
			
		||||
     CFLAGS="-no-cpp-precomp $CFLAGS"
 | 
			
		||||
     LDFLAGS="-flat_namespace -undefined suppress $LDFLAGS"
 | 
			
		||||
     ;;
 | 
			
		||||
linux*)
 | 
			
		||||
     AC_DEFINE_UNQUOTED(LINUX,1,[This is a Linux system])
 | 
			
		||||
     ;;
 | 
			
		||||
freebsd*)
 | 
			
		||||
     AC_DEFINE_UNQUOTED(SOMEBSD,1,[This is a BSD system])
 | 
			
		||||
     AC_DEFINE_UNQUOTED(FREEBSD,1,[This is a FreeBSD system])
 | 
			
		||||
     ;;
 | 
			
		||||
openbsd*)
 | 
			
		||||
     AC_DEFINE_UNQUOTED(SOMEBSD,1,[This is a BSD system])
 | 
			
		||||
     AC_DEFINE_UNQUOTED(OPENBSD,1,[This is an OpenBSD system])
 | 
			
		||||
     ;;
 | 
			
		||||
netbsd*)
 | 
			
		||||
     AC_DEFINE_UNQUOTED(SOMEBSD,1,[This is a BSD system])
 | 
			
		||||
     AC_DEFINE_UNQUOTED(NETBSD,1,[This is a NetBSD system])
 | 
			
		||||
     ;;
 | 
			
		||||
*solaris*)
 | 
			
		||||
     AC_DEFINE_UNQUOTED(SOLARIS,1,[This is a Solaris system])
 | 
			
		||||
     AC_DEFINE_UNQUOTED(_REENTRANT,1,[Need with solaris or errno doesnt work])
 | 
			
		||||
     build_target="solaris"
 | 
			
		||||
     ;;
 | 
			
		||||
*arm-linux*)
 | 
			
		||||
     AC_DEFINE_UNQUOTED(LINUX,1,[This is a Linux system])
 | 
			
		||||
     ;;
 | 
			
		||||
*cygwin*)
 | 
			
		||||
     AC_DEFINE_UNQUOTED(CYGWIN,1,[This is a Cygwin system])
 | 
			
		||||
     AC_DEFINE_UNQUOTED(WINDOWS,1,[This is a Windows system])
 | 
			
		||||
     AC_CHECK_LIB(intl, gettext)
 | 
			
		||||
     LDFLAGS="$LDFLAGS -no-undefined"
 | 
			
		||||
     build_target="cygwin"
 | 
			
		||||
     ;;
 | 
			
		||||
*mingw*)
 | 
			
		||||
     AC_DEFINE_UNQUOTED(MINGW,1,[This is a MinGW system])
 | 
			
		||||
     AC_DEFINE_UNQUOTED(WINDOWS,1,[This is a Windows system])
 | 
			
		||||
     AC_DEFINE_UNQUOTED(_WIN32,1,[This is a Windows system])
 | 
			
		||||
     AC_CHECK_LIB(intl, gettext)
 | 
			
		||||
     LDFLAGS="$LDFLAGS -no-undefined -Wl,--export-all-symbols -lws2_32"
 | 
			
		||||
     CFLAGS="-mms-bitfields $CFLAGS"
 | 
			
		||||
     build_target="mingw"
 | 
			
		||||
     ;;
 | 
			
		||||
*)
 | 
			
		||||
     AC_MSG_RESULT(Unrecognised OS $host_os)
 | 
			
		||||
     AC_DEFINE_UNQUOTED(OTHEROS,1,[Some strange OS])
 | 
			
		||||
;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
AM_CONDITIONAL(MINGW,   test "$build_target" = "mingw")
 | 
			
		||||
 | 
			
		||||
# check for gettext
 | 
			
		||||
AM_GNU_GETTEXT_VERSION([0.18.1])
 | 
			
		||||
AM_GNU_GETTEXT([external])
 | 
			
		||||
 | 
			
		||||
AC_CHECK_HEADERS([errno.h stdio.h unistd.h locale.h sys/stat.h sys/types.h langinfo.h libintl.h unistd.h stddef.h argz.h sys/socket.h netinet/in.h stdarg.h])
 | 
			
		||||
 | 
			
		||||
# test for GNUnet core
 | 
			
		||||
gnunet=0
 | 
			
		||||
lookin=${prefix}
 | 
			
		||||
backup_LDFLAGS="$LDFLAGS"
 | 
			
		||||
backup_CPPFLAGS="$CPPFLAGS"
 | 
			
		||||
GNUNET_LDFLAGS=""
 | 
			
		||||
GNUNET_CPPFLAGS=""
 | 
			
		||||
AC_MSG_CHECKING(for GNUnet core)
 | 
			
		||||
AC_ARG_WITH(gnunet,
 | 
			
		||||
   [  --with-gnunet=PFX       Base of GNUnet installation],
 | 
			
		||||
   [AC_MSG_RESULT([$with_gnunet])
 | 
			
		||||
    case $with_gnunet in
 | 
			
		||||
      no)
 | 
			
		||||
        lookin=""
 | 
			
		||||
        ;;
 | 
			
		||||
      yes)
 | 
			
		||||
        lookin="${prefix}"
 | 
			
		||||
        ;;
 | 
			
		||||
      *)
 | 
			
		||||
        lookin="$with_gnunet"
 | 
			
		||||
        ;;
 | 
			
		||||
    esac
 | 
			
		||||
   ],
 | 
			
		||||
   [
 | 
			
		||||
     AC_MSG_RESULT([--with-gnunet not specified])
 | 
			
		||||
     PKG_CHECK_MODULES([GNUNET], [gnunetutil >= 0.9.0], gnunet=1)
 | 
			
		||||
   ]
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if test "x$gnunet" == "x0" -a ! "x$lookin" == "x"
 | 
			
		||||
then
 | 
			
		||||
  AC_MSG_CHECKING(for GNUnet util library in $lookin)
 | 
			
		||||
  GNUNET_LDFLAGS="-L${lookin}/lib"
 | 
			
		||||
  GNUNET_CPPFLAGS="-I${lookin}/include"
 | 
			
		||||
  LDFLAGS="$GNUNET_LDFLAGS $backup_LDFLAGS"
 | 
			
		||||
  CPPFLAGS="$GNUNET_CPPFLAGS $backup_CPPFLAGS"
 | 
			
		||||
  AC_CHECK_HEADERS([gnunet/gnunet_util_lib.h],
 | 
			
		||||
    AC_CHECK_LIB([gnunetutil], [GNUNET_xfree_],
 | 
			
		||||
      [
 | 
			
		||||
        gnunet=1
 | 
			
		||||
        EXT_LIB_PATH="-L${lookin}/lib $EXT_LIB_PATH"
 | 
			
		||||
      ]
 | 
			
		||||
    ),,[#include <gnunet/platform.h>]
 | 
			
		||||
  )
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test "x$gnunet" == "x0"
 | 
			
		||||
then
 | 
			
		||||
  AC_MSG_ERROR([gnunet-ext requires GNUnet])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Linker hardening options
 | 
			
		||||
# Currently these options are ELF specific - you can't use this with MacOSX
 | 
			
		||||
AC_ARG_ENABLE(linker-hardening,
 | 
			
		||||
  AS_HELP_STRING(--enable-linker-hardening, enable linker security fixups),
 | 
			
		||||
[if test x$enableval = xyes; then
 | 
			
		||||
   LDFLAGS="$LDFLAGS -z relro -z now"
 | 
			
		||||
fi])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extra_logging=GNUNET_NO
 | 
			
		||||
AC_ARG_ENABLE([logging],
 | 
			
		||||
   AS_HELP_STRING([--enable-logging@<:@=value@:>@],[Enable logging calls. Possible values: yes,no,verbose,veryverbose ('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=GNUNET_YES]
 | 
			
		||||
          [test "x$enableval" = "xveryverbose"], [extra_logging=\(GNUNET_YES+1\)])
 | 
			
		||||
   ], [])
 | 
			
		||||
AC_DEFINE_UNQUOTED([GNUNET_EXTRA_LOGGING],[$extra_logging],[1 if extra logging is enabled, 2 for very verbose extra logging, 0 otherwise])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
AC_SUBST(GNUNET_CPPFLAGS)
 | 
			
		||||
AC_SUBST(GNUNET_LDFLAGS)
 | 
			
		||||
LDFLAGS="$backup_LDFLAGS"
 | 
			
		||||
CPPFLAGS="$backup_CPPFLAGS"
 | 
			
		||||
 | 
			
		||||
AC_DEFINE_DIR([PACKAGE_DATA], [datarootdir], [The directory for installing read-only architecture-independent data])
 | 
			
		||||
 | 
			
		||||
# Set PACKAGE_SOURCE_DIR in gnunet_ext_config.h.
 | 
			
		||||
packagesrcdir=`cd $srcdir && pwd`
 | 
			
		||||
AC_DEFINE_UNQUOTED(PACKAGE_SOURCE_DIR, "${packagesrcdir}", [source dir])
 | 
			
		||||
 | 
			
		||||
AC_OUTPUT([ po/Makefile.in
 | 
			
		||||
Makefile
 | 
			
		||||
pkgconfig/Makefile
 | 
			
		||||
src/Makefile
 | 
			
		||||
src/include/Makefile
 | 
			
		||||
src/multicast/Makefile
 | 
			
		||||
src/multicast/multicast.conf
 | 
			
		||||
src/psycutil/Makefile
 | 
			
		||||
src/psyc/Makefile
 | 
			
		||||
src/psyc/psyc.conf
 | 
			
		||||
src/psycstore/Makefile
 | 
			
		||||
src/psycstore/psycstore.conf
 | 
			
		||||
src/social/Makefile
 | 
			
		||||
src/social/social.conf
 | 
			
		||||
pkgconfig/gnunetmulticast.pc
 | 
			
		||||
pkgconfig/gnunetpsyc.pc
 | 
			
		||||
pkgconfig/gnunetpsycstore.pc
 | 
			
		||||
pkgconfig/gnunetsocial.pc
 | 
			
		||||
])
 | 
			
		||||
							
								
								
									
										35
									
								
								m4/ac_define_dir.m4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								m4/ac_define_dir.m4
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
dnl @synopsis AC_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION])
 | 
			
		||||
dnl
 | 
			
		||||
dnl This macro _AC_DEFINEs VARNAME to the expansion of the DIR
 | 
			
		||||
dnl variable, taking care of fixing up ${prefix} and such.
 | 
			
		||||
dnl
 | 
			
		||||
dnl VARNAME is offered as both a C preprocessor symbol, and an output
 | 
			
		||||
dnl variable.
 | 
			
		||||
dnl
 | 
			
		||||
dnl Note that the 3 argument form is only supported with autoconf 2.13
 | 
			
		||||
dnl and later (i.e. only where _AC_DEFINE supports 3 arguments).
 | 
			
		||||
dnl
 | 
			
		||||
dnl Examples:
 | 
			
		||||
dnl
 | 
			
		||||
dnl    AC_DEFINE_DIR(DATADIR, datadir)
 | 
			
		||||
dnl    AC_DEFINE_DIR(PROG_PATH, bindir, [Location of installed binaries])
 | 
			
		||||
dnl
 | 
			
		||||
dnl @category Misc
 | 
			
		||||
dnl @author Stepan Kasal <kasal@ucw.cz>
 | 
			
		||||
dnl @author Andreas Schwab <schwab@suse.de>
 | 
			
		||||
dnl @author Guido Draheim <guidod@gmx.de>
 | 
			
		||||
dnl @author Alexandre Oliva
 | 
			
		||||
dnl @version 2005-01-17
 | 
			
		||||
dnl @license AllPermissive
 | 
			
		||||
 | 
			
		||||
AC_DEFUN([AC_DEFINE_DIR], [
 | 
			
		||||
  prefix_NONE=
 | 
			
		||||
  exec_prefix_NONE=
 | 
			
		||||
  test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix
 | 
			
		||||
  test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix
 | 
			
		||||
  eval ac_define_dir="\"[$]$2\""
 | 
			
		||||
  AC_SUBST($1, "$ac_define_dir")
 | 
			
		||||
  AC_DEFINE_UNQUOTED($1, "$ac_define_dir", [$3])
 | 
			
		||||
  test "$prefix_NONE" && prefix=NONE
 | 
			
		||||
  test "$exec_prefix_NONE" && exec_prefix=NONE
 | 
			
		||||
])
 | 
			
		||||
							
								
								
									
										383
									
								
								m4/gettext.m4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										383
									
								
								m4/gettext.m4
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,383 @@
 | 
			
		||||
# gettext.m4 serial 63 (gettext-0.18)
 | 
			
		||||
dnl Copyright (C) 1995-2010 Free Software Foundation, Inc.
 | 
			
		||||
dnl This file is free software; the Free Software Foundation
 | 
			
		||||
dnl gives unlimited permission to copy and/or distribute it,
 | 
			
		||||
dnl with or without modifications, as long as this notice is preserved.
 | 
			
		||||
dnl
 | 
			
		||||
dnl This file can can be used in projects which are not available under
 | 
			
		||||
dnl the GNU General Public License or the GNU Library General Public
 | 
			
		||||
dnl License but which still want to provide support for the GNU gettext
 | 
			
		||||
dnl functionality.
 | 
			
		||||
dnl Please note that the actual code of the GNU gettext library is covered
 | 
			
		||||
dnl by the GNU Library General Public License, and the rest of the GNU
 | 
			
		||||
dnl gettext package package is covered by the GNU General Public License.
 | 
			
		||||
dnl They are *not* in the public domain.
 | 
			
		||||
 | 
			
		||||
dnl Authors:
 | 
			
		||||
dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
 | 
			
		||||
dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2006, 2008-2010.
 | 
			
		||||
 | 
			
		||||
dnl Macro to add for using GNU gettext.
 | 
			
		||||
 | 
			
		||||
dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]).
 | 
			
		||||
dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The
 | 
			
		||||
dnl    default (if it is not specified or empty) is 'no-libtool'.
 | 
			
		||||
dnl    INTLSYMBOL should be 'external' for packages with no intl directory,
 | 
			
		||||
dnl    and 'no-libtool' or 'use-libtool' for packages with an intl directory.
 | 
			
		||||
dnl    If INTLSYMBOL is 'use-libtool', then a libtool library
 | 
			
		||||
dnl    $(top_builddir)/intl/libintl.la will be created (shared and/or static,
 | 
			
		||||
dnl    depending on --{enable,disable}-{shared,static} and on the presence of
 | 
			
		||||
dnl    AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library
 | 
			
		||||
dnl    $(top_builddir)/intl/libintl.a will be created.
 | 
			
		||||
dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext
 | 
			
		||||
dnl    implementations (in libc or libintl) without the ngettext() function
 | 
			
		||||
dnl    will be ignored.  If NEEDSYMBOL is specified and is
 | 
			
		||||
dnl    'need-formatstring-macros', then GNU gettext implementations that don't
 | 
			
		||||
dnl    support the ISO C 99 <inttypes.h> formatstring macros will be ignored.
 | 
			
		||||
dnl INTLDIR is used to find the intl libraries.  If empty,
 | 
			
		||||
dnl    the value `$(top_builddir)/intl/' is used.
 | 
			
		||||
dnl
 | 
			
		||||
dnl The result of the configuration is one of three cases:
 | 
			
		||||
dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled
 | 
			
		||||
dnl    and used.
 | 
			
		||||
dnl    Catalog format: GNU --> install in $(datadir)
 | 
			
		||||
dnl    Catalog extension: .mo after installation, .gmo in source tree
 | 
			
		||||
dnl 2) GNU gettext has been found in the system's C library.
 | 
			
		||||
dnl    Catalog format: GNU --> install in $(datadir)
 | 
			
		||||
dnl    Catalog extension: .mo after installation, .gmo in source tree
 | 
			
		||||
dnl 3) No internationalization, always use English msgid.
 | 
			
		||||
dnl    Catalog format: none
 | 
			
		||||
dnl    Catalog extension: none
 | 
			
		||||
dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur.
 | 
			
		||||
dnl The use of .gmo is historical (it was needed to avoid overwriting the
 | 
			
		||||
dnl GNU format catalogs when building on a platform with an X/Open gettext),
 | 
			
		||||
dnl but we keep it in order not to force irrelevant filename changes on the
 | 
			
		||||
dnl maintainers.
 | 
			
		||||
dnl
 | 
			
		||||
AC_DEFUN([AM_GNU_GETTEXT],
 | 
			
		||||
[
 | 
			
		||||
  dnl Argument checking.
 | 
			
		||||
  ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], ,
 | 
			
		||||
    [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
 | 
			
		||||
])])])])])
 | 
			
		||||
  ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old],
 | 
			
		||||
    [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])])
 | 
			
		||||
  ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], ,
 | 
			
		||||
    [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
 | 
			
		||||
])])])])
 | 
			
		||||
  define([gt_included_intl],
 | 
			
		||||
    ifelse([$1], [external],
 | 
			
		||||
      ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]),
 | 
			
		||||
      [yes]))
 | 
			
		||||
  define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], []))
 | 
			
		||||
  gt_NEEDS_INIT
 | 
			
		||||
  AM_GNU_GETTEXT_NEED([$2])
 | 
			
		||||
 | 
			
		||||
  AC_REQUIRE([AM_PO_SUBDIRS])dnl
 | 
			
		||||
  ifelse(gt_included_intl, yes, [
 | 
			
		||||
    AC_REQUIRE([AM_INTL_SUBDIR])dnl
 | 
			
		||||
  ])
 | 
			
		||||
 | 
			
		||||
  dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
 | 
			
		||||
  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
 | 
			
		||||
  AC_REQUIRE([AC_LIB_RPATH])
 | 
			
		||||
 | 
			
		||||
  dnl Sometimes libintl requires libiconv, so first search for libiconv.
 | 
			
		||||
  dnl Ideally we would do this search only after the
 | 
			
		||||
  dnl      if test "$USE_NLS" = "yes"; then
 | 
			
		||||
  dnl        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
 | 
			
		||||
  dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT
 | 
			
		||||
  dnl the configure script would need to contain the same shell code
 | 
			
		||||
  dnl again, outside any 'if'. There are two solutions:
 | 
			
		||||
  dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'.
 | 
			
		||||
  dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE.
 | 
			
		||||
  dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not
 | 
			
		||||
  dnl documented, we avoid it.
 | 
			
		||||
  ifelse(gt_included_intl, yes, , [
 | 
			
		||||
    AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
 | 
			
		||||
  ])
 | 
			
		||||
 | 
			
		||||
  dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation.
 | 
			
		||||
  gt_INTL_MACOSX
 | 
			
		||||
 | 
			
		||||
  dnl Set USE_NLS.
 | 
			
		||||
  AC_REQUIRE([AM_NLS])
 | 
			
		||||
 | 
			
		||||
  ifelse(gt_included_intl, yes, [
 | 
			
		||||
    BUILD_INCLUDED_LIBINTL=no
 | 
			
		||||
    USE_INCLUDED_LIBINTL=no
 | 
			
		||||
  ])
 | 
			
		||||
  LIBINTL=
 | 
			
		||||
  LTLIBINTL=
 | 
			
		||||
  POSUB=
 | 
			
		||||
 | 
			
		||||
  dnl Add a version number to the cache macros.
 | 
			
		||||
  case " $gt_needs " in
 | 
			
		||||
    *" need-formatstring-macros "*) gt_api_version=3 ;;
 | 
			
		||||
    *" need-ngettext "*) gt_api_version=2 ;;
 | 
			
		||||
    *) gt_api_version=1 ;;
 | 
			
		||||
  esac
 | 
			
		||||
  gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc"
 | 
			
		||||
  gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl"
 | 
			
		||||
 | 
			
		||||
  dnl If we use NLS figure out what method
 | 
			
		||||
  if test "$USE_NLS" = "yes"; then
 | 
			
		||||
    gt_use_preinstalled_gnugettext=no
 | 
			
		||||
    ifelse(gt_included_intl, yes, [
 | 
			
		||||
      AC_MSG_CHECKING([whether included gettext is requested])
 | 
			
		||||
      AC_ARG_WITH([included-gettext],
 | 
			
		||||
        [  --with-included-gettext use the GNU gettext library included here],
 | 
			
		||||
        nls_cv_force_use_gnu_gettext=$withval,
 | 
			
		||||
        nls_cv_force_use_gnu_gettext=no)
 | 
			
		||||
      AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext])
 | 
			
		||||
 | 
			
		||||
      nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
 | 
			
		||||
      if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
 | 
			
		||||
    ])
 | 
			
		||||
        dnl User does not insist on using GNU NLS library.  Figure out what
 | 
			
		||||
        dnl to use.  If GNU gettext is available we use this.  Else we have
 | 
			
		||||
        dnl to fall back to GNU NLS library.
 | 
			
		||||
 | 
			
		||||
        if test $gt_api_version -ge 3; then
 | 
			
		||||
          gt_revision_test_code='
 | 
			
		||||
#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
 | 
			
		||||
#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
 | 
			
		||||
#endif
 | 
			
		||||
changequote(,)dnl
 | 
			
		||||
typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
 | 
			
		||||
changequote([,])dnl
 | 
			
		||||
'
 | 
			
		||||
        else
 | 
			
		||||
          gt_revision_test_code=
 | 
			
		||||
        fi
 | 
			
		||||
        if test $gt_api_version -ge 2; then
 | 
			
		||||
          gt_expression_test_code=' + * ngettext ("", "", 0)'
 | 
			
		||||
        else
 | 
			
		||||
          gt_expression_test_code=
 | 
			
		||||
        fi
 | 
			
		||||
 | 
			
		||||
        AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc],
 | 
			
		||||
         [AC_TRY_LINK([#include <libintl.h>
 | 
			
		||||
$gt_revision_test_code
 | 
			
		||||
extern int _nl_msg_cat_cntr;
 | 
			
		||||
extern int *_nl_domain_bindings;],
 | 
			
		||||
            [bindtextdomain ("", "");
 | 
			
		||||
return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings],
 | 
			
		||||
            [eval "$gt_func_gnugettext_libc=yes"],
 | 
			
		||||
            [eval "$gt_func_gnugettext_libc=no"])])
 | 
			
		||||
 | 
			
		||||
        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
 | 
			
		||||
          dnl Sometimes libintl requires libiconv, so first search for libiconv.
 | 
			
		||||
          ifelse(gt_included_intl, yes, , [
 | 
			
		||||
            AM_ICONV_LINK
 | 
			
		||||
          ])
 | 
			
		||||
          dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL
 | 
			
		||||
          dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv])
 | 
			
		||||
          dnl because that would add "-liconv" to LIBINTL and LTLIBINTL
 | 
			
		||||
          dnl even if libiconv doesn't exist.
 | 
			
		||||
          AC_LIB_LINKFLAGS_BODY([intl])
 | 
			
		||||
          AC_CACHE_CHECK([for GNU gettext in libintl],
 | 
			
		||||
            [$gt_func_gnugettext_libintl],
 | 
			
		||||
           [gt_save_CPPFLAGS="$CPPFLAGS"
 | 
			
		||||
            CPPFLAGS="$CPPFLAGS $INCINTL"
 | 
			
		||||
            gt_save_LIBS="$LIBS"
 | 
			
		||||
            LIBS="$LIBS $LIBINTL"
 | 
			
		||||
            dnl Now see whether libintl exists and does not depend on libiconv.
 | 
			
		||||
            AC_TRY_LINK([#include <libintl.h>
 | 
			
		||||
$gt_revision_test_code
 | 
			
		||||
extern int _nl_msg_cat_cntr;
 | 
			
		||||
extern
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
"C"
 | 
			
		||||
#endif
 | 
			
		||||
const char *_nl_expand_alias (const char *);],
 | 
			
		||||
              [bindtextdomain ("", "");
 | 
			
		||||
return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
 | 
			
		||||
              [eval "$gt_func_gnugettext_libintl=yes"],
 | 
			
		||||
              [eval "$gt_func_gnugettext_libintl=no"])
 | 
			
		||||
            dnl Now see whether libintl exists and depends on libiconv.
 | 
			
		||||
            if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then
 | 
			
		||||
              LIBS="$LIBS $LIBICONV"
 | 
			
		||||
              AC_TRY_LINK([#include <libintl.h>
 | 
			
		||||
$gt_revision_test_code
 | 
			
		||||
extern int _nl_msg_cat_cntr;
 | 
			
		||||
extern
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
"C"
 | 
			
		||||
#endif
 | 
			
		||||
const char *_nl_expand_alias (const char *);],
 | 
			
		||||
                [bindtextdomain ("", "");
 | 
			
		||||
return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
 | 
			
		||||
               [LIBINTL="$LIBINTL $LIBICONV"
 | 
			
		||||
                LTLIBINTL="$LTLIBINTL $LTLIBICONV"
 | 
			
		||||
                eval "$gt_func_gnugettext_libintl=yes"
 | 
			
		||||
               ])
 | 
			
		||||
            fi
 | 
			
		||||
            CPPFLAGS="$gt_save_CPPFLAGS"
 | 
			
		||||
            LIBS="$gt_save_LIBS"])
 | 
			
		||||
        fi
 | 
			
		||||
 | 
			
		||||
        dnl If an already present or preinstalled GNU gettext() is found,
 | 
			
		||||
        dnl use it.  But if this macro is used in GNU gettext, and GNU
 | 
			
		||||
        dnl gettext is already preinstalled in libintl, we update this
 | 
			
		||||
        dnl libintl.  (Cf. the install rule in intl/Makefile.in.)
 | 
			
		||||
        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \
 | 
			
		||||
           || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \
 | 
			
		||||
                && test "$PACKAGE" != gettext-runtime \
 | 
			
		||||
                && test "$PACKAGE" != gettext-tools; }; then
 | 
			
		||||
          gt_use_preinstalled_gnugettext=yes
 | 
			
		||||
        else
 | 
			
		||||
          dnl Reset the values set by searching for libintl.
 | 
			
		||||
          LIBINTL=
 | 
			
		||||
          LTLIBINTL=
 | 
			
		||||
          INCINTL=
 | 
			
		||||
        fi
 | 
			
		||||
 | 
			
		||||
    ifelse(gt_included_intl, yes, [
 | 
			
		||||
        if test "$gt_use_preinstalled_gnugettext" != "yes"; then
 | 
			
		||||
          dnl GNU gettext is not found in the C library.
 | 
			
		||||
          dnl Fall back on included GNU gettext library.
 | 
			
		||||
          nls_cv_use_gnu_gettext=yes
 | 
			
		||||
        fi
 | 
			
		||||
      fi
 | 
			
		||||
 | 
			
		||||
      if test "$nls_cv_use_gnu_gettext" = "yes"; then
 | 
			
		||||
        dnl Mark actions used to generate GNU NLS library.
 | 
			
		||||
        BUILD_INCLUDED_LIBINTL=yes
 | 
			
		||||
        USE_INCLUDED_LIBINTL=yes
 | 
			
		||||
        LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD"
 | 
			
		||||
        LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD"
 | 
			
		||||
        LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
 | 
			
		||||
      fi
 | 
			
		||||
 | 
			
		||||
      CATOBJEXT=
 | 
			
		||||
      if test "$gt_use_preinstalled_gnugettext" = "yes" \
 | 
			
		||||
         || test "$nls_cv_use_gnu_gettext" = "yes"; then
 | 
			
		||||
        dnl Mark actions to use GNU gettext tools.
 | 
			
		||||
        CATOBJEXT=.gmo
 | 
			
		||||
      fi
 | 
			
		||||
    ])
 | 
			
		||||
 | 
			
		||||
    if test -n "$INTL_MACOSX_LIBS"; then
 | 
			
		||||
      if test "$gt_use_preinstalled_gnugettext" = "yes" \
 | 
			
		||||
         || test "$nls_cv_use_gnu_gettext" = "yes"; then
 | 
			
		||||
        dnl Some extra flags are needed during linking.
 | 
			
		||||
        LIBINTL="$LIBINTL $INTL_MACOSX_LIBS"
 | 
			
		||||
        LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS"
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    if test "$gt_use_preinstalled_gnugettext" = "yes" \
 | 
			
		||||
       || test "$nls_cv_use_gnu_gettext" = "yes"; then
 | 
			
		||||
      AC_DEFINE([ENABLE_NLS], [1],
 | 
			
		||||
        [Define to 1 if translation of program messages to the user's native language
 | 
			
		||||
   is requested.])
 | 
			
		||||
    else
 | 
			
		||||
      USE_NLS=no
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  AC_MSG_CHECKING([whether to use NLS])
 | 
			
		||||
  AC_MSG_RESULT([$USE_NLS])
 | 
			
		||||
  if test "$USE_NLS" = "yes"; then
 | 
			
		||||
    AC_MSG_CHECKING([where the gettext function comes from])
 | 
			
		||||
    if test "$gt_use_preinstalled_gnugettext" = "yes"; then
 | 
			
		||||
      if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
 | 
			
		||||
        gt_source="external libintl"
 | 
			
		||||
      else
 | 
			
		||||
        gt_source="libc"
 | 
			
		||||
      fi
 | 
			
		||||
    else
 | 
			
		||||
      gt_source="included intl directory"
 | 
			
		||||
    fi
 | 
			
		||||
    AC_MSG_RESULT([$gt_source])
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if test "$USE_NLS" = "yes"; then
 | 
			
		||||
 | 
			
		||||
    if test "$gt_use_preinstalled_gnugettext" = "yes"; then
 | 
			
		||||
      if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
 | 
			
		||||
        AC_MSG_CHECKING([how to link with libintl])
 | 
			
		||||
        AC_MSG_RESULT([$LIBINTL])
 | 
			
		||||
        AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL])
 | 
			
		||||
      fi
 | 
			
		||||
 | 
			
		||||
      dnl For backward compatibility. Some packages may be using this.
 | 
			
		||||
      AC_DEFINE([HAVE_GETTEXT], [1],
 | 
			
		||||
       [Define if the GNU gettext() function is already present or preinstalled.])
 | 
			
		||||
      AC_DEFINE([HAVE_DCGETTEXT], [1],
 | 
			
		||||
       [Define if the GNU dcgettext() function is already present or preinstalled.])
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    dnl We need to process the po/ directory.
 | 
			
		||||
    POSUB=po
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  ifelse(gt_included_intl, yes, [
 | 
			
		||||
    dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL
 | 
			
		||||
    dnl to 'yes' because some of the testsuite requires it.
 | 
			
		||||
    if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then
 | 
			
		||||
      BUILD_INCLUDED_LIBINTL=yes
 | 
			
		||||
    fi
 | 
			
		||||
 | 
			
		||||
    dnl Make all variables we use known to autoconf.
 | 
			
		||||
    AC_SUBST([BUILD_INCLUDED_LIBINTL])
 | 
			
		||||
    AC_SUBST([USE_INCLUDED_LIBINTL])
 | 
			
		||||
    AC_SUBST([CATOBJEXT])
 | 
			
		||||
 | 
			
		||||
    dnl For backward compatibility. Some configure.ins may be using this.
 | 
			
		||||
    nls_cv_header_intl=
 | 
			
		||||
    nls_cv_header_libgt=
 | 
			
		||||
 | 
			
		||||
    dnl For backward compatibility. Some Makefiles may be using this.
 | 
			
		||||
    DATADIRNAME=share
 | 
			
		||||
    AC_SUBST([DATADIRNAME])
 | 
			
		||||
 | 
			
		||||
    dnl For backward compatibility. Some Makefiles may be using this.
 | 
			
		||||
    INSTOBJEXT=.mo
 | 
			
		||||
    AC_SUBST([INSTOBJEXT])
 | 
			
		||||
 | 
			
		||||
    dnl For backward compatibility. Some Makefiles may be using this.
 | 
			
		||||
    GENCAT=gencat
 | 
			
		||||
    AC_SUBST([GENCAT])
 | 
			
		||||
 | 
			
		||||
    dnl For backward compatibility. Some Makefiles may be using this.
 | 
			
		||||
    INTLOBJS=
 | 
			
		||||
    if test "$USE_INCLUDED_LIBINTL" = yes; then
 | 
			
		||||
      INTLOBJS="\$(GETTOBJS)"
 | 
			
		||||
    fi
 | 
			
		||||
    AC_SUBST([INTLOBJS])
 | 
			
		||||
 | 
			
		||||
    dnl Enable libtool support if the surrounding package wishes it.
 | 
			
		||||
    INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix
 | 
			
		||||
    AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX])
 | 
			
		||||
  ])
 | 
			
		||||
 | 
			
		||||
  dnl For backward compatibility. Some Makefiles may be using this.
 | 
			
		||||
  INTLLIBS="$LIBINTL"
 | 
			
		||||
  AC_SUBST([INTLLIBS])
 | 
			
		||||
 | 
			
		||||
  dnl Make all documented variables known to autoconf.
 | 
			
		||||
  AC_SUBST([LIBINTL])
 | 
			
		||||
  AC_SUBST([LTLIBINTL])
 | 
			
		||||
  AC_SUBST([POSUB])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized.
 | 
			
		||||
m4_define([gt_NEEDS_INIT],
 | 
			
		||||
[
 | 
			
		||||
  m4_divert_text([DEFAULTS], [gt_needs=])
 | 
			
		||||
  m4_define([gt_NEEDS_INIT], [])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL])
 | 
			
		||||
AC_DEFUN([AM_GNU_GETTEXT_NEED],
 | 
			
		||||
[
 | 
			
		||||
  m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version])
 | 
			
		||||
AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])
 | 
			
		||||
							
								
								
									
										214
									
								
								m4/iconv.m4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								m4/iconv.m4
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,214 @@
 | 
			
		||||
# iconv.m4 serial 11 (gettext-0.18.1)
 | 
			
		||||
dnl Copyright (C) 2000-2002, 2007-2010 Free Software Foundation, Inc.
 | 
			
		||||
dnl This file is free software; the Free Software Foundation
 | 
			
		||||
dnl gives unlimited permission to copy and/or distribute it,
 | 
			
		||||
dnl with or without modifications, as long as this notice is preserved.
 | 
			
		||||
 | 
			
		||||
dnl From Bruno Haible.
 | 
			
		||||
 | 
			
		||||
AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
 | 
			
		||||
[
 | 
			
		||||
  dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
 | 
			
		||||
  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
 | 
			
		||||
  AC_REQUIRE([AC_LIB_RPATH])
 | 
			
		||||
 | 
			
		||||
  dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
 | 
			
		||||
  dnl accordingly.
 | 
			
		||||
  AC_LIB_LINKFLAGS_BODY([iconv])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
AC_DEFUN([AM_ICONV_LINK],
 | 
			
		||||
[
 | 
			
		||||
  dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
 | 
			
		||||
  dnl those with the standalone portable GNU libiconv installed).
 | 
			
		||||
  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
 | 
			
		||||
 | 
			
		||||
  dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
 | 
			
		||||
  dnl accordingly.
 | 
			
		||||
  AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
 | 
			
		||||
 | 
			
		||||
  dnl Add $INCICONV to CPPFLAGS before performing the following checks,
 | 
			
		||||
  dnl because if the user has installed libiconv and not disabled its use
 | 
			
		||||
  dnl via --without-libiconv-prefix, he wants to use it. The first
 | 
			
		||||
  dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed.
 | 
			
		||||
  am_save_CPPFLAGS="$CPPFLAGS"
 | 
			
		||||
  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
 | 
			
		||||
 | 
			
		||||
  AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
 | 
			
		||||
    am_cv_func_iconv="no, consider installing GNU libiconv"
 | 
			
		||||
    am_cv_lib_iconv=no
 | 
			
		||||
    AC_TRY_LINK([#include <stdlib.h>
 | 
			
		||||
#include <iconv.h>],
 | 
			
		||||
      [iconv_t cd = iconv_open("","");
 | 
			
		||||
       iconv(cd,NULL,NULL,NULL,NULL);
 | 
			
		||||
       iconv_close(cd);],
 | 
			
		||||
      [am_cv_func_iconv=yes])
 | 
			
		||||
    if test "$am_cv_func_iconv" != yes; then
 | 
			
		||||
      am_save_LIBS="$LIBS"
 | 
			
		||||
      LIBS="$LIBS $LIBICONV"
 | 
			
		||||
      AC_TRY_LINK([#include <stdlib.h>
 | 
			
		||||
#include <iconv.h>],
 | 
			
		||||
        [iconv_t cd = iconv_open("","");
 | 
			
		||||
         iconv(cd,NULL,NULL,NULL,NULL);
 | 
			
		||||
         iconv_close(cd);],
 | 
			
		||||
        [am_cv_lib_iconv=yes]
 | 
			
		||||
        [am_cv_func_iconv=yes])
 | 
			
		||||
      LIBS="$am_save_LIBS"
 | 
			
		||||
    fi
 | 
			
		||||
  ])
 | 
			
		||||
  if test "$am_cv_func_iconv" = yes; then
 | 
			
		||||
    AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
 | 
			
		||||
      dnl This tests against bugs in AIX 5.1, HP-UX 11.11, Solaris 10.
 | 
			
		||||
      am_save_LIBS="$LIBS"
 | 
			
		||||
      if test $am_cv_lib_iconv = yes; then
 | 
			
		||||
        LIBS="$LIBS $LIBICONV"
 | 
			
		||||
      fi
 | 
			
		||||
      AC_TRY_RUN([
 | 
			
		||||
#include <iconv.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
int main ()
 | 
			
		||||
{
 | 
			
		||||
  /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
 | 
			
		||||
     returns.  */
 | 
			
		||||
  {
 | 
			
		||||
    iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
 | 
			
		||||
    if (cd_utf8_to_88591 != (iconv_t)(-1))
 | 
			
		||||
      {
 | 
			
		||||
        static const char input[] = "\342\202\254"; /* EURO SIGN */
 | 
			
		||||
        char buf[10];
 | 
			
		||||
        const char *inptr = input;
 | 
			
		||||
        size_t inbytesleft = strlen (input);
 | 
			
		||||
        char *outptr = buf;
 | 
			
		||||
        size_t outbytesleft = sizeof (buf);
 | 
			
		||||
        size_t res = iconv (cd_utf8_to_88591,
 | 
			
		||||
                            (char **) &inptr, &inbytesleft,
 | 
			
		||||
                            &outptr, &outbytesleft);
 | 
			
		||||
        if (res == 0)
 | 
			
		||||
          return 1;
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
  /* Test against Solaris 10 bug: Failures are not distinguishable from
 | 
			
		||||
     successful returns.  */
 | 
			
		||||
  {
 | 
			
		||||
    iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
 | 
			
		||||
    if (cd_ascii_to_88591 != (iconv_t)(-1))
 | 
			
		||||
      {
 | 
			
		||||
        static const char input[] = "\263";
 | 
			
		||||
        char buf[10];
 | 
			
		||||
        const char *inptr = input;
 | 
			
		||||
        size_t inbytesleft = strlen (input);
 | 
			
		||||
        char *outptr = buf;
 | 
			
		||||
        size_t outbytesleft = sizeof (buf);
 | 
			
		||||
        size_t res = iconv (cd_ascii_to_88591,
 | 
			
		||||
                            (char **) &inptr, &inbytesleft,
 | 
			
		||||
                            &outptr, &outbytesleft);
 | 
			
		||||
        if (res == 0)
 | 
			
		||||
          return 1;
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
#if 0 /* This bug could be worked around by the caller.  */
 | 
			
		||||
  /* Test against HP-UX 11.11 bug: Positive return value instead of 0.  */
 | 
			
		||||
  {
 | 
			
		||||
    iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
 | 
			
		||||
    if (cd_88591_to_utf8 != (iconv_t)(-1))
 | 
			
		||||
      {
 | 
			
		||||
        static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
 | 
			
		||||
        char buf[50];
 | 
			
		||||
        const char *inptr = input;
 | 
			
		||||
        size_t inbytesleft = strlen (input);
 | 
			
		||||
        char *outptr = buf;
 | 
			
		||||
        size_t outbytesleft = sizeof (buf);
 | 
			
		||||
        size_t res = iconv (cd_88591_to_utf8,
 | 
			
		||||
                            (char **) &inptr, &inbytesleft,
 | 
			
		||||
                            &outptr, &outbytesleft);
 | 
			
		||||
        if ((int)res > 0)
 | 
			
		||||
          return 1;
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
  /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
 | 
			
		||||
     provided.  */
 | 
			
		||||
  if (/* Try standardized names.  */
 | 
			
		||||
      iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
 | 
			
		||||
      /* Try IRIX, OSF/1 names.  */
 | 
			
		||||
      && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
 | 
			
		||||
      /* Try AIX names.  */
 | 
			
		||||
      && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
 | 
			
		||||
      /* Try HP-UX names.  */
 | 
			
		||||
      && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
 | 
			
		||||
    return 1;
 | 
			
		||||
  return 0;
 | 
			
		||||
}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no],
 | 
			
		||||
        [case "$host_os" in
 | 
			
		||||
           aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
 | 
			
		||||
           *)            am_cv_func_iconv_works="guessing yes" ;;
 | 
			
		||||
         esac])
 | 
			
		||||
      LIBS="$am_save_LIBS"
 | 
			
		||||
    ])
 | 
			
		||||
    case "$am_cv_func_iconv_works" in
 | 
			
		||||
      *no) am_func_iconv=no am_cv_lib_iconv=no ;;
 | 
			
		||||
      *)   am_func_iconv=yes ;;
 | 
			
		||||
    esac
 | 
			
		||||
  else
 | 
			
		||||
    am_func_iconv=no am_cv_lib_iconv=no
 | 
			
		||||
  fi
 | 
			
		||||
  if test "$am_func_iconv" = yes; then
 | 
			
		||||
    AC_DEFINE([HAVE_ICONV], [1],
 | 
			
		||||
      [Define if you have the iconv() function and it works.])
 | 
			
		||||
  fi
 | 
			
		||||
  if test "$am_cv_lib_iconv" = yes; then
 | 
			
		||||
    AC_MSG_CHECKING([how to link with libiconv])
 | 
			
		||||
    AC_MSG_RESULT([$LIBICONV])
 | 
			
		||||
  else
 | 
			
		||||
    dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
 | 
			
		||||
    dnl either.
 | 
			
		||||
    CPPFLAGS="$am_save_CPPFLAGS"
 | 
			
		||||
    LIBICONV=
 | 
			
		||||
    LTLIBICONV=
 | 
			
		||||
  fi
 | 
			
		||||
  AC_SUBST([LIBICONV])
 | 
			
		||||
  AC_SUBST([LTLIBICONV])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
 | 
			
		||||
dnl avoid warnings like
 | 
			
		||||
dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
 | 
			
		||||
dnl This is tricky because of the way 'aclocal' is implemented:
 | 
			
		||||
dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
 | 
			
		||||
dnl   Otherwise aclocal's initial scan pass would miss the macro definition.
 | 
			
		||||
dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
 | 
			
		||||
dnl   Otherwise aclocal would emit many "Use of uninitialized value $1"
 | 
			
		||||
dnl   warnings.
 | 
			
		||||
m4_define([gl_iconv_AC_DEFUN],
 | 
			
		||||
  m4_version_prereq([2.64],
 | 
			
		||||
    [[AC_DEFUN_ONCE(
 | 
			
		||||
        [$1], [$2])]],
 | 
			
		||||
    [[AC_DEFUN(
 | 
			
		||||
        [$1], [$2])]]))
 | 
			
		||||
gl_iconv_AC_DEFUN([AM_ICONV],
 | 
			
		||||
[
 | 
			
		||||
  AM_ICONV_LINK
 | 
			
		||||
  if test "$am_cv_func_iconv" = yes; then
 | 
			
		||||
    AC_MSG_CHECKING([for iconv declaration])
 | 
			
		||||
    AC_CACHE_VAL([am_cv_proto_iconv], [
 | 
			
		||||
      AC_TRY_COMPILE([
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <iconv.h>
 | 
			
		||||
extern
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
"C"
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(__STDC__) || defined(__cplusplus)
 | 
			
		||||
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
 | 
			
		||||
#else
 | 
			
		||||
size_t iconv();
 | 
			
		||||
#endif
 | 
			
		||||
], [], [am_cv_proto_iconv_arg1=""], [am_cv_proto_iconv_arg1="const"])
 | 
			
		||||
      am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
 | 
			
		||||
    am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
 | 
			
		||||
    AC_MSG_RESULT([
 | 
			
		||||
         $am_cv_proto_iconv])
 | 
			
		||||
    AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
 | 
			
		||||
      [Define as const if the declaration of iconv() needs const.])
 | 
			
		||||
  fi
 | 
			
		||||
])
 | 
			
		||||
							
								
								
									
										110
									
								
								m4/lib-ld.m4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								m4/lib-ld.m4
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,110 @@
 | 
			
		||||
# lib-ld.m4 serial 4 (gettext-0.18)
 | 
			
		||||
dnl Copyright (C) 1996-2003, 2009-2010 Free Software Foundation, Inc.
 | 
			
		||||
dnl This file is free software; the Free Software Foundation
 | 
			
		||||
dnl gives unlimited permission to copy and/or distribute it,
 | 
			
		||||
dnl with or without modifications, as long as this notice is preserved.
 | 
			
		||||
 | 
			
		||||
dnl Subroutines of libtool.m4,
 | 
			
		||||
dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
 | 
			
		||||
dnl with libtool.m4.
 | 
			
		||||
 | 
			
		||||
dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
 | 
			
		||||
AC_DEFUN([AC_LIB_PROG_LD_GNU],
 | 
			
		||||
[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld],
 | 
			
		||||
[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
 | 
			
		||||
case `$LD -v 2>&1 </dev/null` in
 | 
			
		||||
*GNU* | *'with BFD'*)
 | 
			
		||||
  acl_cv_prog_gnu_ld=yes ;;
 | 
			
		||||
*)
 | 
			
		||||
  acl_cv_prog_gnu_ld=no ;;
 | 
			
		||||
esac])
 | 
			
		||||
with_gnu_ld=$acl_cv_prog_gnu_ld
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl From libtool-1.4. Sets the variable LD.
 | 
			
		||||
AC_DEFUN([AC_LIB_PROG_LD],
 | 
			
		||||
[AC_ARG_WITH([gnu-ld],
 | 
			
		||||
[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
 | 
			
		||||
test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
 | 
			
		||||
AC_REQUIRE([AC_PROG_CC])dnl
 | 
			
		||||
AC_REQUIRE([AC_CANONICAL_HOST])dnl
 | 
			
		||||
# Prepare PATH_SEPARATOR.
 | 
			
		||||
# The user is always right.
 | 
			
		||||
if test "${PATH_SEPARATOR+set}" != set; then
 | 
			
		||||
  echo "#! /bin/sh" >conf$$.sh
 | 
			
		||||
  echo  "exit 0"   >>conf$$.sh
 | 
			
		||||
  chmod +x conf$$.sh
 | 
			
		||||
  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
 | 
			
		||||
    PATH_SEPARATOR=';'
 | 
			
		||||
  else
 | 
			
		||||
    PATH_SEPARATOR=:
 | 
			
		||||
  fi
 | 
			
		||||
  rm -f conf$$.sh
 | 
			
		||||
fi
 | 
			
		||||
ac_prog=ld
 | 
			
		||||
if test "$GCC" = yes; then
 | 
			
		||||
  # Check if gcc -print-prog-name=ld gives a path.
 | 
			
		||||
  AC_MSG_CHECKING([for ld used by GCC])
 | 
			
		||||
  case $host in
 | 
			
		||||
  *-*-mingw*)
 | 
			
		||||
    # gcc leaves a trailing carriage return which upsets mingw
 | 
			
		||||
    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
 | 
			
		||||
  *)
 | 
			
		||||
    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
 | 
			
		||||
  esac
 | 
			
		||||
  case $ac_prog in
 | 
			
		||||
    # Accept absolute paths.
 | 
			
		||||
    [[\\/]* | [A-Za-z]:[\\/]*)]
 | 
			
		||||
      [re_direlt='/[^/][^/]*/\.\./']
 | 
			
		||||
      # Canonicalize the path of ld
 | 
			
		||||
      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
 | 
			
		||||
      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
 | 
			
		||||
        ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
 | 
			
		||||
      done
 | 
			
		||||
      test -z "$LD" && LD="$ac_prog"
 | 
			
		||||
      ;;
 | 
			
		||||
  "")
 | 
			
		||||
    # If it fails, then pretend we aren't using GCC.
 | 
			
		||||
    ac_prog=ld
 | 
			
		||||
    ;;
 | 
			
		||||
  *)
 | 
			
		||||
    # If it is relative, then search for the first ld in PATH.
 | 
			
		||||
    with_gnu_ld=unknown
 | 
			
		||||
    ;;
 | 
			
		||||
  esac
 | 
			
		||||
elif test "$with_gnu_ld" = yes; then
 | 
			
		||||
  AC_MSG_CHECKING([for GNU ld])
 | 
			
		||||
else
 | 
			
		||||
  AC_MSG_CHECKING([for non-GNU ld])
 | 
			
		||||
fi
 | 
			
		||||
AC_CACHE_VAL([acl_cv_path_LD],
 | 
			
		||||
[if test -z "$LD"; then
 | 
			
		||||
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
 | 
			
		||||
  for ac_dir in $PATH; do
 | 
			
		||||
    test -z "$ac_dir" && ac_dir=.
 | 
			
		||||
    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
 | 
			
		||||
      acl_cv_path_LD="$ac_dir/$ac_prog"
 | 
			
		||||
      # Check to see if the program is GNU ld.  I'd rather use --version,
 | 
			
		||||
      # but apparently some GNU ld's only accept -v.
 | 
			
		||||
      # Break only if it was the GNU/non-GNU ld that we prefer.
 | 
			
		||||
      case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
 | 
			
		||||
      *GNU* | *'with BFD'*)
 | 
			
		||||
        test "$with_gnu_ld" != no && break ;;
 | 
			
		||||
      *)
 | 
			
		||||
        test "$with_gnu_ld" != yes && break ;;
 | 
			
		||||
      esac
 | 
			
		||||
    fi
 | 
			
		||||
  done
 | 
			
		||||
  IFS="$ac_save_ifs"
 | 
			
		||||
else
 | 
			
		||||
  acl_cv_path_LD="$LD" # Let the user override the test with a path.
 | 
			
		||||
fi])
 | 
			
		||||
LD="$acl_cv_path_LD"
 | 
			
		||||
if test -n "$LD"; then
 | 
			
		||||
  AC_MSG_RESULT([$LD])
 | 
			
		||||
else
 | 
			
		||||
  AC_MSG_RESULT([no])
 | 
			
		||||
fi
 | 
			
		||||
test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
 | 
			
		||||
AC_LIB_PROG_LD_GNU
 | 
			
		||||
])
 | 
			
		||||
							
								
								
									
										774
									
								
								m4/lib-link.m4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										774
									
								
								m4/lib-link.m4
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,774 @@
 | 
			
		||||
# lib-link.m4 serial 21 (gettext-0.18)
 | 
			
		||||
dnl Copyright (C) 2001-2010 Free Software Foundation, Inc.
 | 
			
		||||
dnl This file is free software; the Free Software Foundation
 | 
			
		||||
dnl gives unlimited permission to copy and/or distribute it,
 | 
			
		||||
dnl with or without modifications, as long as this notice is preserved.
 | 
			
		||||
 | 
			
		||||
dnl From Bruno Haible.
 | 
			
		||||
 | 
			
		||||
AC_PREREQ([2.54])
 | 
			
		||||
 | 
			
		||||
dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
 | 
			
		||||
dnl the libraries corresponding to explicit and implicit dependencies.
 | 
			
		||||
dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
 | 
			
		||||
dnl augments the CPPFLAGS variable.
 | 
			
		||||
dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
 | 
			
		||||
dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
 | 
			
		||||
AC_DEFUN([AC_LIB_LINKFLAGS],
 | 
			
		||||
[
 | 
			
		||||
  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
 | 
			
		||||
  AC_REQUIRE([AC_LIB_RPATH])
 | 
			
		||||
  pushdef([Name],[translit([$1],[./-], [___])])
 | 
			
		||||
  pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
 | 
			
		||||
                                [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
 | 
			
		||||
  AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
 | 
			
		||||
    AC_LIB_LINKFLAGS_BODY([$1], [$2])
 | 
			
		||||
    ac_cv_lib[]Name[]_libs="$LIB[]NAME"
 | 
			
		||||
    ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
 | 
			
		||||
    ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
 | 
			
		||||
    ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
 | 
			
		||||
  ])
 | 
			
		||||
  LIB[]NAME="$ac_cv_lib[]Name[]_libs"
 | 
			
		||||
  LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
 | 
			
		||||
  INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
 | 
			
		||||
  LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
 | 
			
		||||
  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
 | 
			
		||||
  AC_SUBST([LIB]NAME)
 | 
			
		||||
  AC_SUBST([LTLIB]NAME)
 | 
			
		||||
  AC_SUBST([LIB]NAME[_PREFIX])
 | 
			
		||||
  dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
 | 
			
		||||
  dnl results of this search when this library appears as a dependency.
 | 
			
		||||
  HAVE_LIB[]NAME=yes
 | 
			
		||||
  popdef([NAME])
 | 
			
		||||
  popdef([Name])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message])
 | 
			
		||||
dnl searches for libname and the libraries corresponding to explicit and
 | 
			
		||||
dnl implicit dependencies, together with the specified include files and
 | 
			
		||||
dnl the ability to compile and link the specified testcode. The missing-message
 | 
			
		||||
dnl defaults to 'no' and may contain additional hints for the user.
 | 
			
		||||
dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME}
 | 
			
		||||
dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and
 | 
			
		||||
dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
 | 
			
		||||
dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
 | 
			
		||||
dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
 | 
			
		||||
dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
 | 
			
		||||
AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
 | 
			
		||||
[
 | 
			
		||||
  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
 | 
			
		||||
  AC_REQUIRE([AC_LIB_RPATH])
 | 
			
		||||
  pushdef([Name],[translit([$1],[./-], [___])])
 | 
			
		||||
  pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
 | 
			
		||||
                                [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
 | 
			
		||||
 | 
			
		||||
  dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
 | 
			
		||||
  dnl accordingly.
 | 
			
		||||
  AC_LIB_LINKFLAGS_BODY([$1], [$2])
 | 
			
		||||
 | 
			
		||||
  dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
 | 
			
		||||
  dnl because if the user has installed lib[]Name and not disabled its use
 | 
			
		||||
  dnl via --without-lib[]Name-prefix, he wants to use it.
 | 
			
		||||
  ac_save_CPPFLAGS="$CPPFLAGS"
 | 
			
		||||
  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
 | 
			
		||||
 | 
			
		||||
  AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
 | 
			
		||||
    ac_save_LIBS="$LIBS"
 | 
			
		||||
    dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS,
 | 
			
		||||
    dnl because these -l options might require -L options that are present in
 | 
			
		||||
    dnl LIBS. -l options benefit only from the -L options listed before it.
 | 
			
		||||
    dnl Otherwise, add it to the front of LIBS, because it may be a static
 | 
			
		||||
    dnl library that depends on another static library that is present in LIBS.
 | 
			
		||||
    dnl Static libraries benefit only from the static libraries listed after
 | 
			
		||||
    dnl it.
 | 
			
		||||
    case " $LIB[]NAME" in
 | 
			
		||||
      *" -l"*) LIBS="$LIBS $LIB[]NAME" ;;
 | 
			
		||||
      *)       LIBS="$LIB[]NAME $LIBS" ;;
 | 
			
		||||
    esac
 | 
			
		||||
    AC_TRY_LINK([$3], [$4],
 | 
			
		||||
      [ac_cv_lib[]Name=yes],
 | 
			
		||||
      [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
 | 
			
		||||
    LIBS="$ac_save_LIBS"
 | 
			
		||||
  ])
 | 
			
		||||
  if test "$ac_cv_lib[]Name" = yes; then
 | 
			
		||||
    HAVE_LIB[]NAME=yes
 | 
			
		||||
    AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.])
 | 
			
		||||
    AC_MSG_CHECKING([how to link with lib[]$1])
 | 
			
		||||
    AC_MSG_RESULT([$LIB[]NAME])
 | 
			
		||||
  else
 | 
			
		||||
    HAVE_LIB[]NAME=no
 | 
			
		||||
    dnl If $LIB[]NAME didn't lead to a usable library, we don't need
 | 
			
		||||
    dnl $INC[]NAME either.
 | 
			
		||||
    CPPFLAGS="$ac_save_CPPFLAGS"
 | 
			
		||||
    LIB[]NAME=
 | 
			
		||||
    LTLIB[]NAME=
 | 
			
		||||
    LIB[]NAME[]_PREFIX=
 | 
			
		||||
  fi
 | 
			
		||||
  AC_SUBST([HAVE_LIB]NAME)
 | 
			
		||||
  AC_SUBST([LIB]NAME)
 | 
			
		||||
  AC_SUBST([LTLIB]NAME)
 | 
			
		||||
  AC_SUBST([LIB]NAME[_PREFIX])
 | 
			
		||||
  popdef([NAME])
 | 
			
		||||
  popdef([Name])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl Determine the platform dependent parameters needed to use rpath:
 | 
			
		||||
dnl   acl_libext,
 | 
			
		||||
dnl   acl_shlibext,
 | 
			
		||||
dnl   acl_hardcode_libdir_flag_spec,
 | 
			
		||||
dnl   acl_hardcode_libdir_separator,
 | 
			
		||||
dnl   acl_hardcode_direct,
 | 
			
		||||
dnl   acl_hardcode_minus_L.
 | 
			
		||||
AC_DEFUN([AC_LIB_RPATH],
 | 
			
		||||
[
 | 
			
		||||
  dnl Tell automake >= 1.10 to complain if config.rpath is missing.
 | 
			
		||||
  m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
 | 
			
		||||
  AC_REQUIRE([AC_PROG_CC])                dnl we use $CC, $GCC, $LDFLAGS
 | 
			
		||||
  AC_REQUIRE([AC_LIB_PROG_LD])            dnl we use $LD, $with_gnu_ld
 | 
			
		||||
  AC_REQUIRE([AC_CANONICAL_HOST])         dnl we use $host
 | 
			
		||||
  AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
 | 
			
		||||
  AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [
 | 
			
		||||
    CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
 | 
			
		||||
    ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
 | 
			
		||||
    . ./conftest.sh
 | 
			
		||||
    rm -f ./conftest.sh
 | 
			
		||||
    acl_cv_rpath=done
 | 
			
		||||
  ])
 | 
			
		||||
  wl="$acl_cv_wl"
 | 
			
		||||
  acl_libext="$acl_cv_libext"
 | 
			
		||||
  acl_shlibext="$acl_cv_shlibext"
 | 
			
		||||
  acl_libname_spec="$acl_cv_libname_spec"
 | 
			
		||||
  acl_library_names_spec="$acl_cv_library_names_spec"
 | 
			
		||||
  acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
 | 
			
		||||
  acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
 | 
			
		||||
  acl_hardcode_direct="$acl_cv_hardcode_direct"
 | 
			
		||||
  acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
 | 
			
		||||
  dnl Determine whether the user wants rpath handling at all.
 | 
			
		||||
  AC_ARG_ENABLE([rpath],
 | 
			
		||||
    [  --disable-rpath         do not hardcode runtime library paths],
 | 
			
		||||
    :, enable_rpath=yes)
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl AC_LIB_FROMPACKAGE(name, package)
 | 
			
		||||
dnl declares that libname comes from the given package. The configure file
 | 
			
		||||
dnl will then not have a --with-libname-prefix option but a
 | 
			
		||||
dnl --with-package-prefix option. Several libraries can come from the same
 | 
			
		||||
dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
 | 
			
		||||
dnl macro call that searches for libname.
 | 
			
		||||
AC_DEFUN([AC_LIB_FROMPACKAGE],
 | 
			
		||||
[
 | 
			
		||||
  pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
 | 
			
		||||
                                [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
 | 
			
		||||
  define([acl_frompackage_]NAME, [$2])
 | 
			
		||||
  popdef([NAME])
 | 
			
		||||
  pushdef([PACK],[$2])
 | 
			
		||||
  pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
 | 
			
		||||
                                  [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
 | 
			
		||||
  define([acl_libsinpackage_]PACKUP,
 | 
			
		||||
    m4_ifdef([acl_libsinpackage_]PACKUP, [acl_libsinpackage_]PACKUP[[, ]],)[lib$1])
 | 
			
		||||
  popdef([PACKUP])
 | 
			
		||||
  popdef([PACK])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
 | 
			
		||||
dnl the libraries corresponding to explicit and implicit dependencies.
 | 
			
		||||
dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
 | 
			
		||||
dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
 | 
			
		||||
dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
 | 
			
		||||
AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
 | 
			
		||||
[
 | 
			
		||||
  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
 | 
			
		||||
  pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
 | 
			
		||||
                                [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
 | 
			
		||||
  pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
 | 
			
		||||
  pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
 | 
			
		||||
                                  [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
 | 
			
		||||
  pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
 | 
			
		||||
  dnl Autoconf >= 2.61 supports dots in --with options.
 | 
			
		||||
  pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit(PACK,[.],[_])],PACK)])
 | 
			
		||||
  dnl By default, look in $includedir and $libdir.
 | 
			
		||||
  use_additional=yes
 | 
			
		||||
  AC_LIB_WITH_FINAL_PREFIX([
 | 
			
		||||
    eval additional_includedir=\"$includedir\"
 | 
			
		||||
    eval additional_libdir=\"$libdir\"
 | 
			
		||||
  ])
 | 
			
		||||
  AC_ARG_WITH(P_A_C_K[-prefix],
 | 
			
		||||
[[  --with-]]P_A_C_K[[-prefix[=DIR]  search for ]PACKLIBS[ in DIR/include and DIR/lib
 | 
			
		||||
  --without-]]P_A_C_K[[-prefix     don't search for ]PACKLIBS[ in includedir and libdir]],
 | 
			
		||||
[
 | 
			
		||||
    if test "X$withval" = "Xno"; then
 | 
			
		||||
      use_additional=no
 | 
			
		||||
    else
 | 
			
		||||
      if test "X$withval" = "X"; then
 | 
			
		||||
        AC_LIB_WITH_FINAL_PREFIX([
 | 
			
		||||
          eval additional_includedir=\"$includedir\"
 | 
			
		||||
          eval additional_libdir=\"$libdir\"
 | 
			
		||||
        ])
 | 
			
		||||
      else
 | 
			
		||||
        additional_includedir="$withval/include"
 | 
			
		||||
        additional_libdir="$withval/$acl_libdirstem"
 | 
			
		||||
        if test "$acl_libdirstem2" != "$acl_libdirstem" \
 | 
			
		||||
           && ! test -d "$withval/$acl_libdirstem"; then
 | 
			
		||||
          additional_libdir="$withval/$acl_libdirstem2"
 | 
			
		||||
        fi
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
])
 | 
			
		||||
  dnl Search the library and its dependencies in $additional_libdir and
 | 
			
		||||
  dnl $LDFLAGS. Using breadth-first-seach.
 | 
			
		||||
  LIB[]NAME=
 | 
			
		||||
  LTLIB[]NAME=
 | 
			
		||||
  INC[]NAME=
 | 
			
		||||
  LIB[]NAME[]_PREFIX=
 | 
			
		||||
  dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been
 | 
			
		||||
  dnl computed. So it has to be reset here.
 | 
			
		||||
  HAVE_LIB[]NAME=
 | 
			
		||||
  rpathdirs=
 | 
			
		||||
  ltrpathdirs=
 | 
			
		||||
  names_already_handled=
 | 
			
		||||
  names_next_round='$1 $2'
 | 
			
		||||
  while test -n "$names_next_round"; do
 | 
			
		||||
    names_this_round="$names_next_round"
 | 
			
		||||
    names_next_round=
 | 
			
		||||
    for name in $names_this_round; do
 | 
			
		||||
      already_handled=
 | 
			
		||||
      for n in $names_already_handled; do
 | 
			
		||||
        if test "$n" = "$name"; then
 | 
			
		||||
          already_handled=yes
 | 
			
		||||
          break
 | 
			
		||||
        fi
 | 
			
		||||
      done
 | 
			
		||||
      if test -z "$already_handled"; then
 | 
			
		||||
        names_already_handled="$names_already_handled $name"
 | 
			
		||||
        dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
 | 
			
		||||
        dnl or AC_LIB_HAVE_LINKFLAGS call.
 | 
			
		||||
        uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
 | 
			
		||||
        eval value=\"\$HAVE_LIB$uppername\"
 | 
			
		||||
        if test -n "$value"; then
 | 
			
		||||
          if test "$value" = yes; then
 | 
			
		||||
            eval value=\"\$LIB$uppername\"
 | 
			
		||||
            test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
 | 
			
		||||
            eval value=\"\$LTLIB$uppername\"
 | 
			
		||||
            test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
 | 
			
		||||
          else
 | 
			
		||||
            dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
 | 
			
		||||
            dnl that this library doesn't exist. So just drop it.
 | 
			
		||||
            :
 | 
			
		||||
          fi
 | 
			
		||||
        else
 | 
			
		||||
          dnl Search the library lib$name in $additional_libdir and $LDFLAGS
 | 
			
		||||
          dnl and the already constructed $LIBNAME/$LTLIBNAME.
 | 
			
		||||
          found_dir=
 | 
			
		||||
          found_la=
 | 
			
		||||
          found_so=
 | 
			
		||||
          found_a=
 | 
			
		||||
          eval libname=\"$acl_libname_spec\"    # typically: libname=lib$name
 | 
			
		||||
          if test -n "$acl_shlibext"; then
 | 
			
		||||
            shrext=".$acl_shlibext"             # typically: shrext=.so
 | 
			
		||||
          else
 | 
			
		||||
            shrext=
 | 
			
		||||
          fi
 | 
			
		||||
          if test $use_additional = yes; then
 | 
			
		||||
            dir="$additional_libdir"
 | 
			
		||||
            dnl The same code as in the loop below:
 | 
			
		||||
            dnl First look for a shared library.
 | 
			
		||||
            if test -n "$acl_shlibext"; then
 | 
			
		||||
              if test -f "$dir/$libname$shrext"; then
 | 
			
		||||
                found_dir="$dir"
 | 
			
		||||
                found_so="$dir/$libname$shrext"
 | 
			
		||||
              else
 | 
			
		||||
                if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
 | 
			
		||||
                  ver=`(cd "$dir" && \
 | 
			
		||||
                        for f in "$libname$shrext".*; do echo "$f"; done \
 | 
			
		||||
                        | sed -e "s,^$libname$shrext\\\\.,," \
 | 
			
		||||
                        | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
 | 
			
		||||
                        | sed 1q ) 2>/dev/null`
 | 
			
		||||
                  if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
 | 
			
		||||
                    found_dir="$dir"
 | 
			
		||||
                    found_so="$dir/$libname$shrext.$ver"
 | 
			
		||||
                  fi
 | 
			
		||||
                else
 | 
			
		||||
                  eval library_names=\"$acl_library_names_spec\"
 | 
			
		||||
                  for f in $library_names; do
 | 
			
		||||
                    if test -f "$dir/$f"; then
 | 
			
		||||
                      found_dir="$dir"
 | 
			
		||||
                      found_so="$dir/$f"
 | 
			
		||||
                      break
 | 
			
		||||
                    fi
 | 
			
		||||
                  done
 | 
			
		||||
                fi
 | 
			
		||||
              fi
 | 
			
		||||
            fi
 | 
			
		||||
            dnl Then look for a static library.
 | 
			
		||||
            if test "X$found_dir" = "X"; then
 | 
			
		||||
              if test -f "$dir/$libname.$acl_libext"; then
 | 
			
		||||
                found_dir="$dir"
 | 
			
		||||
                found_a="$dir/$libname.$acl_libext"
 | 
			
		||||
              fi
 | 
			
		||||
            fi
 | 
			
		||||
            if test "X$found_dir" != "X"; then
 | 
			
		||||
              if test -f "$dir/$libname.la"; then
 | 
			
		||||
                found_la="$dir/$libname.la"
 | 
			
		||||
              fi
 | 
			
		||||
            fi
 | 
			
		||||
          fi
 | 
			
		||||
          if test "X$found_dir" = "X"; then
 | 
			
		||||
            for x in $LDFLAGS $LTLIB[]NAME; do
 | 
			
		||||
              AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
 | 
			
		||||
              case "$x" in
 | 
			
		||||
                -L*)
 | 
			
		||||
                  dir=`echo "X$x" | sed -e 's/^X-L//'`
 | 
			
		||||
                  dnl First look for a shared library.
 | 
			
		||||
                  if test -n "$acl_shlibext"; then
 | 
			
		||||
                    if test -f "$dir/$libname$shrext"; then
 | 
			
		||||
                      found_dir="$dir"
 | 
			
		||||
                      found_so="$dir/$libname$shrext"
 | 
			
		||||
                    else
 | 
			
		||||
                      if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
 | 
			
		||||
                        ver=`(cd "$dir" && \
 | 
			
		||||
                              for f in "$libname$shrext".*; do echo "$f"; done \
 | 
			
		||||
                              | sed -e "s,^$libname$shrext\\\\.,," \
 | 
			
		||||
                              | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
 | 
			
		||||
                              | sed 1q ) 2>/dev/null`
 | 
			
		||||
                        if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
 | 
			
		||||
                          found_dir="$dir"
 | 
			
		||||
                          found_so="$dir/$libname$shrext.$ver"
 | 
			
		||||
                        fi
 | 
			
		||||
                      else
 | 
			
		||||
                        eval library_names=\"$acl_library_names_spec\"
 | 
			
		||||
                        for f in $library_names; do
 | 
			
		||||
                          if test -f "$dir/$f"; then
 | 
			
		||||
                            found_dir="$dir"
 | 
			
		||||
                            found_so="$dir/$f"
 | 
			
		||||
                            break
 | 
			
		||||
                          fi
 | 
			
		||||
                        done
 | 
			
		||||
                      fi
 | 
			
		||||
                    fi
 | 
			
		||||
                  fi
 | 
			
		||||
                  dnl Then look for a static library.
 | 
			
		||||
                  if test "X$found_dir" = "X"; then
 | 
			
		||||
                    if test -f "$dir/$libname.$acl_libext"; then
 | 
			
		||||
                      found_dir="$dir"
 | 
			
		||||
                      found_a="$dir/$libname.$acl_libext"
 | 
			
		||||
                    fi
 | 
			
		||||
                  fi
 | 
			
		||||
                  if test "X$found_dir" != "X"; then
 | 
			
		||||
                    if test -f "$dir/$libname.la"; then
 | 
			
		||||
                      found_la="$dir/$libname.la"
 | 
			
		||||
                    fi
 | 
			
		||||
                  fi
 | 
			
		||||
                  ;;
 | 
			
		||||
              esac
 | 
			
		||||
              if test "X$found_dir" != "X"; then
 | 
			
		||||
                break
 | 
			
		||||
              fi
 | 
			
		||||
            done
 | 
			
		||||
          fi
 | 
			
		||||
          if test "X$found_dir" != "X"; then
 | 
			
		||||
            dnl Found the library.
 | 
			
		||||
            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
 | 
			
		||||
            if test "X$found_so" != "X"; then
 | 
			
		||||
              dnl Linking with a shared library. We attempt to hardcode its
 | 
			
		||||
              dnl directory into the executable's runpath, unless it's the
 | 
			
		||||
              dnl standard /usr/lib.
 | 
			
		||||
              if test "$enable_rpath" = no \
 | 
			
		||||
                 || test "X$found_dir" = "X/usr/$acl_libdirstem" \
 | 
			
		||||
                 || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
 | 
			
		||||
                dnl No hardcoding is needed.
 | 
			
		||||
                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
 | 
			
		||||
              else
 | 
			
		||||
                dnl Use an explicit option to hardcode DIR into the resulting
 | 
			
		||||
                dnl binary.
 | 
			
		||||
                dnl Potentially add DIR to ltrpathdirs.
 | 
			
		||||
                dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
 | 
			
		||||
                haveit=
 | 
			
		||||
                for x in $ltrpathdirs; do
 | 
			
		||||
                  if test "X$x" = "X$found_dir"; then
 | 
			
		||||
                    haveit=yes
 | 
			
		||||
                    break
 | 
			
		||||
                  fi
 | 
			
		||||
                done
 | 
			
		||||
                if test -z "$haveit"; then
 | 
			
		||||
                  ltrpathdirs="$ltrpathdirs $found_dir"
 | 
			
		||||
                fi
 | 
			
		||||
                dnl The hardcoding into $LIBNAME is system dependent.
 | 
			
		||||
                if test "$acl_hardcode_direct" = yes; then
 | 
			
		||||
                  dnl Using DIR/libNAME.so during linking hardcodes DIR into the
 | 
			
		||||
                  dnl resulting binary.
 | 
			
		||||
                  LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
 | 
			
		||||
                else
 | 
			
		||||
                  if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
 | 
			
		||||
                    dnl Use an explicit option to hardcode DIR into the resulting
 | 
			
		||||
                    dnl binary.
 | 
			
		||||
                    LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
 | 
			
		||||
                    dnl Potentially add DIR to rpathdirs.
 | 
			
		||||
                    dnl The rpathdirs will be appended to $LIBNAME at the end.
 | 
			
		||||
                    haveit=
 | 
			
		||||
                    for x in $rpathdirs; do
 | 
			
		||||
                      if test "X$x" = "X$found_dir"; then
 | 
			
		||||
                        haveit=yes
 | 
			
		||||
                        break
 | 
			
		||||
                      fi
 | 
			
		||||
                    done
 | 
			
		||||
                    if test -z "$haveit"; then
 | 
			
		||||
                      rpathdirs="$rpathdirs $found_dir"
 | 
			
		||||
                    fi
 | 
			
		||||
                  else
 | 
			
		||||
                    dnl Rely on "-L$found_dir".
 | 
			
		||||
                    dnl But don't add it if it's already contained in the LDFLAGS
 | 
			
		||||
                    dnl or the already constructed $LIBNAME
 | 
			
		||||
                    haveit=
 | 
			
		||||
                    for x in $LDFLAGS $LIB[]NAME; do
 | 
			
		||||
                      AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
 | 
			
		||||
                      if test "X$x" = "X-L$found_dir"; then
 | 
			
		||||
                        haveit=yes
 | 
			
		||||
                        break
 | 
			
		||||
                      fi
 | 
			
		||||
                    done
 | 
			
		||||
                    if test -z "$haveit"; then
 | 
			
		||||
                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
 | 
			
		||||
                    fi
 | 
			
		||||
                    if test "$acl_hardcode_minus_L" != no; then
 | 
			
		||||
                      dnl FIXME: Not sure whether we should use
 | 
			
		||||
                      dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
 | 
			
		||||
                      dnl here.
 | 
			
		||||
                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
 | 
			
		||||
                    else
 | 
			
		||||
                      dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH
 | 
			
		||||
                      dnl here, because this doesn't fit in flags passed to the
 | 
			
		||||
                      dnl compiler. So give up. No hardcoding. This affects only
 | 
			
		||||
                      dnl very old systems.
 | 
			
		||||
                      dnl FIXME: Not sure whether we should use
 | 
			
		||||
                      dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
 | 
			
		||||
                      dnl here.
 | 
			
		||||
                      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
 | 
			
		||||
                    fi
 | 
			
		||||
                  fi
 | 
			
		||||
                fi
 | 
			
		||||
              fi
 | 
			
		||||
            else
 | 
			
		||||
              if test "X$found_a" != "X"; then
 | 
			
		||||
                dnl Linking with a static library.
 | 
			
		||||
                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
 | 
			
		||||
              else
 | 
			
		||||
                dnl We shouldn't come here, but anyway it's good to have a
 | 
			
		||||
                dnl fallback.
 | 
			
		||||
                LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
 | 
			
		||||
              fi
 | 
			
		||||
            fi
 | 
			
		||||
            dnl Assume the include files are nearby.
 | 
			
		||||
            additional_includedir=
 | 
			
		||||
            case "$found_dir" in
 | 
			
		||||
              */$acl_libdirstem | */$acl_libdirstem/)
 | 
			
		||||
                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
 | 
			
		||||
                if test "$name" = '$1'; then
 | 
			
		||||
                  LIB[]NAME[]_PREFIX="$basedir"
 | 
			
		||||
                fi
 | 
			
		||||
                additional_includedir="$basedir/include"
 | 
			
		||||
                ;;
 | 
			
		||||
              */$acl_libdirstem2 | */$acl_libdirstem2/)
 | 
			
		||||
                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
 | 
			
		||||
                if test "$name" = '$1'; then
 | 
			
		||||
                  LIB[]NAME[]_PREFIX="$basedir"
 | 
			
		||||
                fi
 | 
			
		||||
                additional_includedir="$basedir/include"
 | 
			
		||||
                ;;
 | 
			
		||||
            esac
 | 
			
		||||
            if test "X$additional_includedir" != "X"; then
 | 
			
		||||
              dnl Potentially add $additional_includedir to $INCNAME.
 | 
			
		||||
              dnl But don't add it
 | 
			
		||||
              dnl   1. if it's the standard /usr/include,
 | 
			
		||||
              dnl   2. if it's /usr/local/include and we are using GCC on Linux,
 | 
			
		||||
              dnl   3. if it's already present in $CPPFLAGS or the already
 | 
			
		||||
              dnl      constructed $INCNAME,
 | 
			
		||||
              dnl   4. if it doesn't exist as a directory.
 | 
			
		||||
              if test "X$additional_includedir" != "X/usr/include"; then
 | 
			
		||||
                haveit=
 | 
			
		||||
                if test "X$additional_includedir" = "X/usr/local/include"; then
 | 
			
		||||
                  if test -n "$GCC"; then
 | 
			
		||||
                    case $host_os in
 | 
			
		||||
                      linux* | gnu* | k*bsd*-gnu) haveit=yes;;
 | 
			
		||||
                    esac
 | 
			
		||||
                  fi
 | 
			
		||||
                fi
 | 
			
		||||
                if test -z "$haveit"; then
 | 
			
		||||
                  for x in $CPPFLAGS $INC[]NAME; do
 | 
			
		||||
                    AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
 | 
			
		||||
                    if test "X$x" = "X-I$additional_includedir"; then
 | 
			
		||||
                      haveit=yes
 | 
			
		||||
                      break
 | 
			
		||||
                    fi
 | 
			
		||||
                  done
 | 
			
		||||
                  if test -z "$haveit"; then
 | 
			
		||||
                    if test -d "$additional_includedir"; then
 | 
			
		||||
                      dnl Really add $additional_includedir to $INCNAME.
 | 
			
		||||
                      INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
 | 
			
		||||
                    fi
 | 
			
		||||
                  fi
 | 
			
		||||
                fi
 | 
			
		||||
              fi
 | 
			
		||||
            fi
 | 
			
		||||
            dnl Look for dependencies.
 | 
			
		||||
            if test -n "$found_la"; then
 | 
			
		||||
              dnl Read the .la file. It defines the variables
 | 
			
		||||
              dnl dlname, library_names, old_library, dependency_libs, current,
 | 
			
		||||
              dnl age, revision, installed, dlopen, dlpreopen, libdir.
 | 
			
		||||
              save_libdir="$libdir"
 | 
			
		||||
              case "$found_la" in
 | 
			
		||||
                */* | *\\*) . "$found_la" ;;
 | 
			
		||||
                *) . "./$found_la" ;;
 | 
			
		||||
              esac
 | 
			
		||||
              libdir="$save_libdir"
 | 
			
		||||
              dnl We use only dependency_libs.
 | 
			
		||||
              for dep in $dependency_libs; do
 | 
			
		||||
                case "$dep" in
 | 
			
		||||
                  -L*)
 | 
			
		||||
                    additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
 | 
			
		||||
                    dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
 | 
			
		||||
                    dnl But don't add it
 | 
			
		||||
                    dnl   1. if it's the standard /usr/lib,
 | 
			
		||||
                    dnl   2. if it's /usr/local/lib and we are using GCC on Linux,
 | 
			
		||||
                    dnl   3. if it's already present in $LDFLAGS or the already
 | 
			
		||||
                    dnl      constructed $LIBNAME,
 | 
			
		||||
                    dnl   4. if it doesn't exist as a directory.
 | 
			
		||||
                    if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
 | 
			
		||||
                       && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
 | 
			
		||||
                      haveit=
 | 
			
		||||
                      if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
 | 
			
		||||
                         || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
 | 
			
		||||
                        if test -n "$GCC"; then
 | 
			
		||||
                          case $host_os in
 | 
			
		||||
                            linux* | gnu* | k*bsd*-gnu) haveit=yes;;
 | 
			
		||||
                          esac
 | 
			
		||||
                        fi
 | 
			
		||||
                      fi
 | 
			
		||||
                      if test -z "$haveit"; then
 | 
			
		||||
                        haveit=
 | 
			
		||||
                        for x in $LDFLAGS $LIB[]NAME; do
 | 
			
		||||
                          AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
 | 
			
		||||
                          if test "X$x" = "X-L$additional_libdir"; then
 | 
			
		||||
                            haveit=yes
 | 
			
		||||
                            break
 | 
			
		||||
                          fi
 | 
			
		||||
                        done
 | 
			
		||||
                        if test -z "$haveit"; then
 | 
			
		||||
                          if test -d "$additional_libdir"; then
 | 
			
		||||
                            dnl Really add $additional_libdir to $LIBNAME.
 | 
			
		||||
                            LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
 | 
			
		||||
                          fi
 | 
			
		||||
                        fi
 | 
			
		||||
                        haveit=
 | 
			
		||||
                        for x in $LDFLAGS $LTLIB[]NAME; do
 | 
			
		||||
                          AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
 | 
			
		||||
                          if test "X$x" = "X-L$additional_libdir"; then
 | 
			
		||||
                            haveit=yes
 | 
			
		||||
                            break
 | 
			
		||||
                          fi
 | 
			
		||||
                        done
 | 
			
		||||
                        if test -z "$haveit"; then
 | 
			
		||||
                          if test -d "$additional_libdir"; then
 | 
			
		||||
                            dnl Really add $additional_libdir to $LTLIBNAME.
 | 
			
		||||
                            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
 | 
			
		||||
                          fi
 | 
			
		||||
                        fi
 | 
			
		||||
                      fi
 | 
			
		||||
                    fi
 | 
			
		||||
                    ;;
 | 
			
		||||
                  -R*)
 | 
			
		||||
                    dir=`echo "X$dep" | sed -e 's/^X-R//'`
 | 
			
		||||
                    if test "$enable_rpath" != no; then
 | 
			
		||||
                      dnl Potentially add DIR to rpathdirs.
 | 
			
		||||
                      dnl The rpathdirs will be appended to $LIBNAME at the end.
 | 
			
		||||
                      haveit=
 | 
			
		||||
                      for x in $rpathdirs; do
 | 
			
		||||
                        if test "X$x" = "X$dir"; then
 | 
			
		||||
                          haveit=yes
 | 
			
		||||
                          break
 | 
			
		||||
                        fi
 | 
			
		||||
                      done
 | 
			
		||||
                      if test -z "$haveit"; then
 | 
			
		||||
                        rpathdirs="$rpathdirs $dir"
 | 
			
		||||
                      fi
 | 
			
		||||
                      dnl Potentially add DIR to ltrpathdirs.
 | 
			
		||||
                      dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
 | 
			
		||||
                      haveit=
 | 
			
		||||
                      for x in $ltrpathdirs; do
 | 
			
		||||
                        if test "X$x" = "X$dir"; then
 | 
			
		||||
                          haveit=yes
 | 
			
		||||
                          break
 | 
			
		||||
                        fi
 | 
			
		||||
                      done
 | 
			
		||||
                      if test -z "$haveit"; then
 | 
			
		||||
                        ltrpathdirs="$ltrpathdirs $dir"
 | 
			
		||||
                      fi
 | 
			
		||||
                    fi
 | 
			
		||||
                    ;;
 | 
			
		||||
                  -l*)
 | 
			
		||||
                    dnl Handle this in the next round.
 | 
			
		||||
                    names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
 | 
			
		||||
                    ;;
 | 
			
		||||
                  *.la)
 | 
			
		||||
                    dnl Handle this in the next round. Throw away the .la's
 | 
			
		||||
                    dnl directory; it is already contained in a preceding -L
 | 
			
		||||
                    dnl option.
 | 
			
		||||
                    names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
 | 
			
		||||
                    ;;
 | 
			
		||||
                  *)
 | 
			
		||||
                    dnl Most likely an immediate library name.
 | 
			
		||||
                    LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
 | 
			
		||||
                    LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
 | 
			
		||||
                    ;;
 | 
			
		||||
                esac
 | 
			
		||||
              done
 | 
			
		||||
            fi
 | 
			
		||||
          else
 | 
			
		||||
            dnl Didn't find the library; assume it is in the system directories
 | 
			
		||||
            dnl known to the linker and runtime loader. (All the system
 | 
			
		||||
            dnl directories known to the linker should also be known to the
 | 
			
		||||
            dnl runtime loader, otherwise the system is severely misconfigured.)
 | 
			
		||||
            LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
 | 
			
		||||
            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
 | 
			
		||||
          fi
 | 
			
		||||
        fi
 | 
			
		||||
      fi
 | 
			
		||||
    done
 | 
			
		||||
  done
 | 
			
		||||
  if test "X$rpathdirs" != "X"; then
 | 
			
		||||
    if test -n "$acl_hardcode_libdir_separator"; then
 | 
			
		||||
      dnl Weird platform: only the last -rpath option counts, the user must
 | 
			
		||||
      dnl pass all path elements in one option. We can arrange that for a
 | 
			
		||||
      dnl single library, but not when more than one $LIBNAMEs are used.
 | 
			
		||||
      alldirs=
 | 
			
		||||
      for found_dir in $rpathdirs; do
 | 
			
		||||
        alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
 | 
			
		||||
      done
 | 
			
		||||
      dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
 | 
			
		||||
      acl_save_libdir="$libdir"
 | 
			
		||||
      libdir="$alldirs"
 | 
			
		||||
      eval flag=\"$acl_hardcode_libdir_flag_spec\"
 | 
			
		||||
      libdir="$acl_save_libdir"
 | 
			
		||||
      LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
 | 
			
		||||
    else
 | 
			
		||||
      dnl The -rpath options are cumulative.
 | 
			
		||||
      for found_dir in $rpathdirs; do
 | 
			
		||||
        acl_save_libdir="$libdir"
 | 
			
		||||
        libdir="$found_dir"
 | 
			
		||||
        eval flag=\"$acl_hardcode_libdir_flag_spec\"
 | 
			
		||||
        libdir="$acl_save_libdir"
 | 
			
		||||
        LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
 | 
			
		||||
      done
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
  if test "X$ltrpathdirs" != "X"; then
 | 
			
		||||
    dnl When using libtool, the option that works for both libraries and
 | 
			
		||||
    dnl executables is -R. The -R options are cumulative.
 | 
			
		||||
    for found_dir in $ltrpathdirs; do
 | 
			
		||||
      LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
 | 
			
		||||
    done
 | 
			
		||||
  fi
 | 
			
		||||
  popdef([P_A_C_K])
 | 
			
		||||
  popdef([PACKLIBS])
 | 
			
		||||
  popdef([PACKUP])
 | 
			
		||||
  popdef([PACK])
 | 
			
		||||
  popdef([NAME])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
 | 
			
		||||
dnl unless already present in VAR.
 | 
			
		||||
dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
 | 
			
		||||
dnl contains two or three consecutive elements that belong together.
 | 
			
		||||
AC_DEFUN([AC_LIB_APPENDTOVAR],
 | 
			
		||||
[
 | 
			
		||||
  for element in [$2]; do
 | 
			
		||||
    haveit=
 | 
			
		||||
    for x in $[$1]; do
 | 
			
		||||
      AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
 | 
			
		||||
      if test "X$x" = "X$element"; then
 | 
			
		||||
        haveit=yes
 | 
			
		||||
        break
 | 
			
		||||
      fi
 | 
			
		||||
    done
 | 
			
		||||
    if test -z "$haveit"; then
 | 
			
		||||
      [$1]="${[$1]}${[$1]:+ }$element"
 | 
			
		||||
    fi
 | 
			
		||||
  done
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl For those cases where a variable contains several -L and -l options
 | 
			
		||||
dnl referring to unknown libraries and directories, this macro determines the
 | 
			
		||||
dnl necessary additional linker options for the runtime path.
 | 
			
		||||
dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
 | 
			
		||||
dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
 | 
			
		||||
dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
 | 
			
		||||
dnl otherwise linking without libtool is assumed.
 | 
			
		||||
AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
 | 
			
		||||
[
 | 
			
		||||
  AC_REQUIRE([AC_LIB_RPATH])
 | 
			
		||||
  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
 | 
			
		||||
  $1=
 | 
			
		||||
  if test "$enable_rpath" != no; then
 | 
			
		||||
    if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
 | 
			
		||||
      dnl Use an explicit option to hardcode directories into the resulting
 | 
			
		||||
      dnl binary.
 | 
			
		||||
      rpathdirs=
 | 
			
		||||
      next=
 | 
			
		||||
      for opt in $2; do
 | 
			
		||||
        if test -n "$next"; then
 | 
			
		||||
          dir="$next"
 | 
			
		||||
          dnl No need to hardcode the standard /usr/lib.
 | 
			
		||||
          if test "X$dir" != "X/usr/$acl_libdirstem" \
 | 
			
		||||
             && test "X$dir" != "X/usr/$acl_libdirstem2"; then
 | 
			
		||||
            rpathdirs="$rpathdirs $dir"
 | 
			
		||||
          fi
 | 
			
		||||
          next=
 | 
			
		||||
        else
 | 
			
		||||
          case $opt in
 | 
			
		||||
            -L) next=yes ;;
 | 
			
		||||
            -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
 | 
			
		||||
                 dnl No need to hardcode the standard /usr/lib.
 | 
			
		||||
                 if test "X$dir" != "X/usr/$acl_libdirstem" \
 | 
			
		||||
                    && test "X$dir" != "X/usr/$acl_libdirstem2"; then
 | 
			
		||||
                   rpathdirs="$rpathdirs $dir"
 | 
			
		||||
                 fi
 | 
			
		||||
                 next= ;;
 | 
			
		||||
            *) next= ;;
 | 
			
		||||
          esac
 | 
			
		||||
        fi
 | 
			
		||||
      done
 | 
			
		||||
      if test "X$rpathdirs" != "X"; then
 | 
			
		||||
        if test -n ""$3""; then
 | 
			
		||||
          dnl libtool is used for linking. Use -R options.
 | 
			
		||||
          for dir in $rpathdirs; do
 | 
			
		||||
            $1="${$1}${$1:+ }-R$dir"
 | 
			
		||||
          done
 | 
			
		||||
        else
 | 
			
		||||
          dnl The linker is used for linking directly.
 | 
			
		||||
          if test -n "$acl_hardcode_libdir_separator"; then
 | 
			
		||||
            dnl Weird platform: only the last -rpath option counts, the user
 | 
			
		||||
            dnl must pass all path elements in one option.
 | 
			
		||||
            alldirs=
 | 
			
		||||
            for dir in $rpathdirs; do
 | 
			
		||||
              alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
 | 
			
		||||
            done
 | 
			
		||||
            acl_save_libdir="$libdir"
 | 
			
		||||
            libdir="$alldirs"
 | 
			
		||||
            eval flag=\"$acl_hardcode_libdir_flag_spec\"
 | 
			
		||||
            libdir="$acl_save_libdir"
 | 
			
		||||
            $1="$flag"
 | 
			
		||||
          else
 | 
			
		||||
            dnl The -rpath options are cumulative.
 | 
			
		||||
            for dir in $rpathdirs; do
 | 
			
		||||
              acl_save_libdir="$libdir"
 | 
			
		||||
              libdir="$dir"
 | 
			
		||||
              eval flag=\"$acl_hardcode_libdir_flag_spec\"
 | 
			
		||||
              libdir="$acl_save_libdir"
 | 
			
		||||
              $1="${$1}${$1:+ }$flag"
 | 
			
		||||
            done
 | 
			
		||||
          fi
 | 
			
		||||
        fi
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
  AC_SUBST([$1])
 | 
			
		||||
])
 | 
			
		||||
							
								
								
									
										224
									
								
								m4/lib-prefix.m4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								m4/lib-prefix.m4
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,224 @@
 | 
			
		||||
# lib-prefix.m4 serial 7 (gettext-0.18)
 | 
			
		||||
dnl Copyright (C) 2001-2005, 2008-2010 Free Software Foundation, Inc.
 | 
			
		||||
dnl This file is free software; the Free Software Foundation
 | 
			
		||||
dnl gives unlimited permission to copy and/or distribute it,
 | 
			
		||||
dnl with or without modifications, as long as this notice is preserved.
 | 
			
		||||
 | 
			
		||||
dnl From Bruno Haible.
 | 
			
		||||
 | 
			
		||||
dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
 | 
			
		||||
dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
 | 
			
		||||
dnl require excessive bracketing.
 | 
			
		||||
ifdef([AC_HELP_STRING],
 | 
			
		||||
[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
 | 
			
		||||
[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
 | 
			
		||||
 | 
			
		||||
dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
 | 
			
		||||
dnl to access previously installed libraries. The basic assumption is that
 | 
			
		||||
dnl a user will want packages to use other packages he previously installed
 | 
			
		||||
dnl with the same --prefix option.
 | 
			
		||||
dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
 | 
			
		||||
dnl libraries, but is otherwise very convenient.
 | 
			
		||||
AC_DEFUN([AC_LIB_PREFIX],
 | 
			
		||||
[
 | 
			
		||||
  AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
 | 
			
		||||
  AC_REQUIRE([AC_PROG_CC])
 | 
			
		||||
  AC_REQUIRE([AC_CANONICAL_HOST])
 | 
			
		||||
  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
 | 
			
		||||
  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
 | 
			
		||||
  dnl By default, look in $includedir and $libdir.
 | 
			
		||||
  use_additional=yes
 | 
			
		||||
  AC_LIB_WITH_FINAL_PREFIX([
 | 
			
		||||
    eval additional_includedir=\"$includedir\"
 | 
			
		||||
    eval additional_libdir=\"$libdir\"
 | 
			
		||||
  ])
 | 
			
		||||
  AC_LIB_ARG_WITH([lib-prefix],
 | 
			
		||||
[  --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
 | 
			
		||||
  --without-lib-prefix    don't search for libraries in includedir and libdir],
 | 
			
		||||
[
 | 
			
		||||
    if test "X$withval" = "Xno"; then
 | 
			
		||||
      use_additional=no
 | 
			
		||||
    else
 | 
			
		||||
      if test "X$withval" = "X"; then
 | 
			
		||||
        AC_LIB_WITH_FINAL_PREFIX([
 | 
			
		||||
          eval additional_includedir=\"$includedir\"
 | 
			
		||||
          eval additional_libdir=\"$libdir\"
 | 
			
		||||
        ])
 | 
			
		||||
      else
 | 
			
		||||
        additional_includedir="$withval/include"
 | 
			
		||||
        additional_libdir="$withval/$acl_libdirstem"
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
])
 | 
			
		||||
  if test $use_additional = yes; then
 | 
			
		||||
    dnl Potentially add $additional_includedir to $CPPFLAGS.
 | 
			
		||||
    dnl But don't add it
 | 
			
		||||
    dnl   1. if it's the standard /usr/include,
 | 
			
		||||
    dnl   2. if it's already present in $CPPFLAGS,
 | 
			
		||||
    dnl   3. if it's /usr/local/include and we are using GCC on Linux,
 | 
			
		||||
    dnl   4. if it doesn't exist as a directory.
 | 
			
		||||
    if test "X$additional_includedir" != "X/usr/include"; then
 | 
			
		||||
      haveit=
 | 
			
		||||
      for x in $CPPFLAGS; do
 | 
			
		||||
        AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
 | 
			
		||||
        if test "X$x" = "X-I$additional_includedir"; then
 | 
			
		||||
          haveit=yes
 | 
			
		||||
          break
 | 
			
		||||
        fi
 | 
			
		||||
      done
 | 
			
		||||
      if test -z "$haveit"; then
 | 
			
		||||
        if test "X$additional_includedir" = "X/usr/local/include"; then
 | 
			
		||||
          if test -n "$GCC"; then
 | 
			
		||||
            case $host_os in
 | 
			
		||||
              linux* | gnu* | k*bsd*-gnu) haveit=yes;;
 | 
			
		||||
            esac
 | 
			
		||||
          fi
 | 
			
		||||
        fi
 | 
			
		||||
        if test -z "$haveit"; then
 | 
			
		||||
          if test -d "$additional_includedir"; then
 | 
			
		||||
            dnl Really add $additional_includedir to $CPPFLAGS.
 | 
			
		||||
            CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
 | 
			
		||||
          fi
 | 
			
		||||
        fi
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
    dnl Potentially add $additional_libdir to $LDFLAGS.
 | 
			
		||||
    dnl But don't add it
 | 
			
		||||
    dnl   1. if it's the standard /usr/lib,
 | 
			
		||||
    dnl   2. if it's already present in $LDFLAGS,
 | 
			
		||||
    dnl   3. if it's /usr/local/lib and we are using GCC on Linux,
 | 
			
		||||
    dnl   4. if it doesn't exist as a directory.
 | 
			
		||||
    if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
 | 
			
		||||
      haveit=
 | 
			
		||||
      for x in $LDFLAGS; do
 | 
			
		||||
        AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
 | 
			
		||||
        if test "X$x" = "X-L$additional_libdir"; then
 | 
			
		||||
          haveit=yes
 | 
			
		||||
          break
 | 
			
		||||
        fi
 | 
			
		||||
      done
 | 
			
		||||
      if test -z "$haveit"; then
 | 
			
		||||
        if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
 | 
			
		||||
          if test -n "$GCC"; then
 | 
			
		||||
            case $host_os in
 | 
			
		||||
              linux*) haveit=yes;;
 | 
			
		||||
            esac
 | 
			
		||||
          fi
 | 
			
		||||
        fi
 | 
			
		||||
        if test -z "$haveit"; then
 | 
			
		||||
          if test -d "$additional_libdir"; then
 | 
			
		||||
            dnl Really add $additional_libdir to $LDFLAGS.
 | 
			
		||||
            LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
 | 
			
		||||
          fi
 | 
			
		||||
        fi
 | 
			
		||||
      fi
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
 | 
			
		||||
dnl acl_final_exec_prefix, containing the values to which $prefix and
 | 
			
		||||
dnl $exec_prefix will expand at the end of the configure script.
 | 
			
		||||
AC_DEFUN([AC_LIB_PREPARE_PREFIX],
 | 
			
		||||
[
 | 
			
		||||
  dnl Unfortunately, prefix and exec_prefix get only finally determined
 | 
			
		||||
  dnl at the end of configure.
 | 
			
		||||
  if test "X$prefix" = "XNONE"; then
 | 
			
		||||
    acl_final_prefix="$ac_default_prefix"
 | 
			
		||||
  else
 | 
			
		||||
    acl_final_prefix="$prefix"
 | 
			
		||||
  fi
 | 
			
		||||
  if test "X$exec_prefix" = "XNONE"; then
 | 
			
		||||
    acl_final_exec_prefix='${prefix}'
 | 
			
		||||
  else
 | 
			
		||||
    acl_final_exec_prefix="$exec_prefix"
 | 
			
		||||
  fi
 | 
			
		||||
  acl_save_prefix="$prefix"
 | 
			
		||||
  prefix="$acl_final_prefix"
 | 
			
		||||
  eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
 | 
			
		||||
  prefix="$acl_save_prefix"
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
 | 
			
		||||
dnl variables prefix and exec_prefix bound to the values they will have
 | 
			
		||||
dnl at the end of the configure script.
 | 
			
		||||
AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
 | 
			
		||||
[
 | 
			
		||||
  acl_save_prefix="$prefix"
 | 
			
		||||
  prefix="$acl_final_prefix"
 | 
			
		||||
  acl_save_exec_prefix="$exec_prefix"
 | 
			
		||||
  exec_prefix="$acl_final_exec_prefix"
 | 
			
		||||
  $1
 | 
			
		||||
  exec_prefix="$acl_save_exec_prefix"
 | 
			
		||||
  prefix="$acl_save_prefix"
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl AC_LIB_PREPARE_MULTILIB creates
 | 
			
		||||
dnl - a variable acl_libdirstem, containing the basename of the libdir, either
 | 
			
		||||
dnl   "lib" or "lib64" or "lib/64",
 | 
			
		||||
dnl - a variable acl_libdirstem2, as a secondary possible value for
 | 
			
		||||
dnl   acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
 | 
			
		||||
dnl   "lib/amd64".
 | 
			
		||||
AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
 | 
			
		||||
[
 | 
			
		||||
  dnl There is no formal standard regarding lib and lib64.
 | 
			
		||||
  dnl On glibc systems, the current practice is that on a system supporting
 | 
			
		||||
  dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
 | 
			
		||||
  dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
 | 
			
		||||
  dnl the compiler's default mode by looking at the compiler's library search
 | 
			
		||||
  dnl path. If at least one of its elements ends in /lib64 or points to a
 | 
			
		||||
  dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
 | 
			
		||||
  dnl Otherwise we use the default, namely "lib".
 | 
			
		||||
  dnl On Solaris systems, the current practice is that on a system supporting
 | 
			
		||||
  dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
 | 
			
		||||
  dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
 | 
			
		||||
  dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
 | 
			
		||||
  AC_REQUIRE([AC_CANONICAL_HOST])
 | 
			
		||||
  acl_libdirstem=lib
 | 
			
		||||
  acl_libdirstem2=
 | 
			
		||||
  case "$host_os" in
 | 
			
		||||
    solaris*)
 | 
			
		||||
      dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment
 | 
			
		||||
      dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
 | 
			
		||||
      dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link."
 | 
			
		||||
      dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
 | 
			
		||||
      dnl symlink is missing, so we set acl_libdirstem2 too.
 | 
			
		||||
      AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
 | 
			
		||||
        [AC_EGREP_CPP([sixtyfour bits], [
 | 
			
		||||
#ifdef _LP64
 | 
			
		||||
sixtyfour bits
 | 
			
		||||
#endif
 | 
			
		||||
           ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
 | 
			
		||||
        ])
 | 
			
		||||
      if test $gl_cv_solaris_64bit = yes; then
 | 
			
		||||
        acl_libdirstem=lib/64
 | 
			
		||||
        case "$host_cpu" in
 | 
			
		||||
          sparc*)        acl_libdirstem2=lib/sparcv9 ;;
 | 
			
		||||
          i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
 | 
			
		||||
        esac
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
    *)
 | 
			
		||||
      searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
 | 
			
		||||
      if test -n "$searchpath"; then
 | 
			
		||||
        acl_save_IFS="${IFS= 	}"; IFS=":"
 | 
			
		||||
        for searchdir in $searchpath; do
 | 
			
		||||
          if test -d "$searchdir"; then
 | 
			
		||||
            case "$searchdir" in
 | 
			
		||||
              */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
 | 
			
		||||
              */../ | */.. )
 | 
			
		||||
                # Better ignore directories of this form. They are misleading.
 | 
			
		||||
                ;;
 | 
			
		||||
              *) searchdir=`cd "$searchdir" && pwd`
 | 
			
		||||
                 case "$searchdir" in
 | 
			
		||||
                   */lib64 ) acl_libdirstem=lib64 ;;
 | 
			
		||||
                 esac ;;
 | 
			
		||||
            esac
 | 
			
		||||
          fi
 | 
			
		||||
        done
 | 
			
		||||
        IFS="$acl_save_IFS"
 | 
			
		||||
      fi
 | 
			
		||||
      ;;
 | 
			
		||||
  esac
 | 
			
		||||
  test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
 | 
			
		||||
])
 | 
			
		||||
							
								
								
									
										8387
									
								
								m4/libtool.m4
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8387
									
								
								m4/libtool.m4
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										437
									
								
								m4/ltoptions.m4
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										437
									
								
								m4/ltoptions.m4
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,437 @@
 | 
			
		||||
# Helper functions for option handling.                    -*- Autoconf -*-
 | 
			
		||||
#
 | 
			
		||||
#   Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
 | 
			
		||||
#   Foundation, Inc.
 | 
			
		||||
#   Written by Gary V. Vaughan, 2004
 | 
			
		||||
#
 | 
			
		||||
# This file is free software; the Free Software Foundation gives
 | 
			
		||||
# unlimited permission to copy and/or distribute it, with or without
 | 
			
		||||
# modifications, as long as this notice is preserved.
 | 
			
		||||
 | 
			
		||||
# serial 8 ltoptions.m4
 | 
			
		||||
 | 
			
		||||
# This is to help aclocal find these macros, as it can't see m4_define.
 | 
			
		||||
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
 | 
			
		||||
# ------------------------------------------
 | 
			
		||||
m4_define([_LT_MANGLE_OPTION],
 | 
			
		||||
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
 | 
			
		||||
# ---------------------------------------
 | 
			
		||||
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
 | 
			
		||||
# matching handler defined, dispatch to it.  Other OPTION-NAMEs are
 | 
			
		||||
# saved as a flag.
 | 
			
		||||
m4_define([_LT_SET_OPTION],
 | 
			
		||||
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
 | 
			
		||||
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
 | 
			
		||||
        _LT_MANGLE_DEFUN([$1], [$2]),
 | 
			
		||||
    [m4_warning([Unknown $1 option '$2'])])[]dnl
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
 | 
			
		||||
# ------------------------------------------------------------
 | 
			
		||||
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
 | 
			
		||||
m4_define([_LT_IF_OPTION],
 | 
			
		||||
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
 | 
			
		||||
# -------------------------------------------------------
 | 
			
		||||
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
 | 
			
		||||
# are set.
 | 
			
		||||
m4_define([_LT_UNLESS_OPTIONS],
 | 
			
		||||
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
 | 
			
		||||
	    [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
 | 
			
		||||
		      [m4_define([$0_found])])])[]dnl
 | 
			
		||||
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
 | 
			
		||||
])[]dnl
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
 | 
			
		||||
# ----------------------------------------
 | 
			
		||||
# OPTION-LIST is a space-separated list of Libtool options associated
 | 
			
		||||
# with MACRO-NAME.  If any OPTION has a matching handler declared with
 | 
			
		||||
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
 | 
			
		||||
# the unknown option and exit.
 | 
			
		||||
m4_defun([_LT_SET_OPTIONS],
 | 
			
		||||
[# Set options
 | 
			
		||||
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
 | 
			
		||||
    [_LT_SET_OPTION([$1], _LT_Option)])
 | 
			
		||||
 | 
			
		||||
m4_if([$1],[LT_INIT],[
 | 
			
		||||
  dnl
 | 
			
		||||
  dnl Simply set some default values (i.e off) if boolean options were not
 | 
			
		||||
  dnl specified:
 | 
			
		||||
  _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
 | 
			
		||||
  ])
 | 
			
		||||
  _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
 | 
			
		||||
  ])
 | 
			
		||||
  dnl
 | 
			
		||||
  dnl If no reference was made to various pairs of opposing options, then
 | 
			
		||||
  dnl we run the default mode handler for the pair.  For example, if neither
 | 
			
		||||
  dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
 | 
			
		||||
  dnl archives by default:
 | 
			
		||||
  _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
 | 
			
		||||
  _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
 | 
			
		||||
  _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
 | 
			
		||||
  _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
 | 
			
		||||
		   [_LT_ENABLE_FAST_INSTALL])
 | 
			
		||||
  _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
 | 
			
		||||
		   [_LT_WITH_AIX_SONAME([aix])])
 | 
			
		||||
  ])
 | 
			
		||||
])# _LT_SET_OPTIONS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## --------------------------------- ##
 | 
			
		||||
## Macros to handle LT_INIT options. ##
 | 
			
		||||
## --------------------------------- ##
 | 
			
		||||
 | 
			
		||||
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
 | 
			
		||||
# -----------------------------------------
 | 
			
		||||
m4_define([_LT_MANGLE_DEFUN],
 | 
			
		||||
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
 | 
			
		||||
# -----------------------------------------------
 | 
			
		||||
m4_define([LT_OPTION_DEFINE],
 | 
			
		||||
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
 | 
			
		||||
])# LT_OPTION_DEFINE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# dlopen
 | 
			
		||||
# ------
 | 
			
		||||
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
AU_DEFUN([AC_LIBTOOL_DLOPEN],
 | 
			
		||||
[_LT_SET_OPTION([LT_INIT], [dlopen])
 | 
			
		||||
AC_DIAGNOSE([obsolete],
 | 
			
		||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
 | 
			
		||||
put the 'dlopen' option into LT_INIT's first parameter.])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl aclocal-1.4 backwards compatibility:
 | 
			
		||||
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# win32-dll
 | 
			
		||||
# ---------
 | 
			
		||||
# Declare package support for building win32 dll's.
 | 
			
		||||
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
 | 
			
		||||
[enable_win32_dll=yes
 | 
			
		||||
 | 
			
		||||
case $host in
 | 
			
		||||
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
 | 
			
		||||
  AC_CHECK_TOOL(AS, as, false)
 | 
			
		||||
  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
 | 
			
		||||
  AC_CHECK_TOOL(OBJDUMP, objdump, false)
 | 
			
		||||
  ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
test -z "$AS" && AS=as
 | 
			
		||||
_LT_DECL([], [AS],      [1], [Assembler program])dnl
 | 
			
		||||
 | 
			
		||||
test -z "$DLLTOOL" && DLLTOOL=dlltool
 | 
			
		||||
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
 | 
			
		||||
 | 
			
		||||
test -z "$OBJDUMP" && OBJDUMP=objdump
 | 
			
		||||
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
 | 
			
		||||
])# win32-dll
 | 
			
		||||
 | 
			
		||||
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
 | 
			
		||||
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
 | 
			
		||||
_LT_SET_OPTION([LT_INIT], [win32-dll])
 | 
			
		||||
AC_DIAGNOSE([obsolete],
 | 
			
		||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
 | 
			
		||||
put the 'win32-dll' option into LT_INIT's first parameter.])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl aclocal-1.4 backwards compatibility:
 | 
			
		||||
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# _LT_ENABLE_SHARED([DEFAULT])
 | 
			
		||||
# ----------------------------
 | 
			
		||||
# implement the --enable-shared flag, and supports the 'shared' and
 | 
			
		||||
# 'disable-shared' LT_INIT options.
 | 
			
		||||
# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
 | 
			
		||||
m4_define([_LT_ENABLE_SHARED],
 | 
			
		||||
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
 | 
			
		||||
AC_ARG_ENABLE([shared],
 | 
			
		||||
    [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
 | 
			
		||||
	[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
 | 
			
		||||
    [p=${PACKAGE-default}
 | 
			
		||||
    case $enableval in
 | 
			
		||||
    yes) enable_shared=yes ;;
 | 
			
		||||
    no) enable_shared=no ;;
 | 
			
		||||
    *)
 | 
			
		||||
      enable_shared=no
 | 
			
		||||
      # Look at the argument we got.  We use all the common list separators.
 | 
			
		||||
      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
 | 
			
		||||
      for pkg in $enableval; do
 | 
			
		||||
	IFS=$lt_save_ifs
 | 
			
		||||
	if test "X$pkg" = "X$p"; then
 | 
			
		||||
	  enable_shared=yes
 | 
			
		||||
	fi
 | 
			
		||||
      done
 | 
			
		||||
      IFS=$lt_save_ifs
 | 
			
		||||
      ;;
 | 
			
		||||
    esac],
 | 
			
		||||
    [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
 | 
			
		||||
 | 
			
		||||
    _LT_DECL([build_libtool_libs], [enable_shared], [0],
 | 
			
		||||
	[Whether or not to build shared libraries])
 | 
			
		||||
])# _LT_ENABLE_SHARED
 | 
			
		||||
 | 
			
		||||
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
 | 
			
		||||
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
 | 
			
		||||
 | 
			
		||||
# Old names:
 | 
			
		||||
AC_DEFUN([AC_ENABLE_SHARED],
 | 
			
		||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
AC_DEFUN([AC_DISABLE_SHARED],
 | 
			
		||||
[_LT_SET_OPTION([LT_INIT], [disable-shared])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
 | 
			
		||||
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
 | 
			
		||||
 | 
			
		||||
dnl aclocal-1.4 backwards compatibility:
 | 
			
		||||
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
 | 
			
		||||
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# _LT_ENABLE_STATIC([DEFAULT])
 | 
			
		||||
# ----------------------------
 | 
			
		||||
# implement the --enable-static flag, and support the 'static' and
 | 
			
		||||
# 'disable-static' LT_INIT options.
 | 
			
		||||
# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
 | 
			
		||||
m4_define([_LT_ENABLE_STATIC],
 | 
			
		||||
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
 | 
			
		||||
AC_ARG_ENABLE([static],
 | 
			
		||||
    [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
 | 
			
		||||
	[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
 | 
			
		||||
    [p=${PACKAGE-default}
 | 
			
		||||
    case $enableval in
 | 
			
		||||
    yes) enable_static=yes ;;
 | 
			
		||||
    no) enable_static=no ;;
 | 
			
		||||
    *)
 | 
			
		||||
     enable_static=no
 | 
			
		||||
      # Look at the argument we got.  We use all the common list separators.
 | 
			
		||||
      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
 | 
			
		||||
      for pkg in $enableval; do
 | 
			
		||||
	IFS=$lt_save_ifs
 | 
			
		||||
	if test "X$pkg" = "X$p"; then
 | 
			
		||||
	  enable_static=yes
 | 
			
		||||
	fi
 | 
			
		||||
      done
 | 
			
		||||
      IFS=$lt_save_ifs
 | 
			
		||||
      ;;
 | 
			
		||||
    esac],
 | 
			
		||||
    [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
 | 
			
		||||
 | 
			
		||||
    _LT_DECL([build_old_libs], [enable_static], [0],
 | 
			
		||||
	[Whether or not to build static libraries])
 | 
			
		||||
])# _LT_ENABLE_STATIC
 | 
			
		||||
 | 
			
		||||
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
 | 
			
		||||
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
 | 
			
		||||
 | 
			
		||||
# Old names:
 | 
			
		||||
AC_DEFUN([AC_ENABLE_STATIC],
 | 
			
		||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
AC_DEFUN([AC_DISABLE_STATIC],
 | 
			
		||||
[_LT_SET_OPTION([LT_INIT], [disable-static])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
 | 
			
		||||
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
 | 
			
		||||
 | 
			
		||||
dnl aclocal-1.4 backwards compatibility:
 | 
			
		||||
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
 | 
			
		||||
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
 | 
			
		||||
# ----------------------------------
 | 
			
		||||
# implement the --enable-fast-install flag, and support the 'fast-install'
 | 
			
		||||
# and 'disable-fast-install' LT_INIT options.
 | 
			
		||||
# DEFAULT is either 'yes' or 'no'.  If omitted, it defaults to 'yes'.
 | 
			
		||||
m4_define([_LT_ENABLE_FAST_INSTALL],
 | 
			
		||||
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
 | 
			
		||||
AC_ARG_ENABLE([fast-install],
 | 
			
		||||
    [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
 | 
			
		||||
    [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
 | 
			
		||||
    [p=${PACKAGE-default}
 | 
			
		||||
    case $enableval in
 | 
			
		||||
    yes) enable_fast_install=yes ;;
 | 
			
		||||
    no) enable_fast_install=no ;;
 | 
			
		||||
    *)
 | 
			
		||||
      enable_fast_install=no
 | 
			
		||||
      # Look at the argument we got.  We use all the common list separators.
 | 
			
		||||
      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
 | 
			
		||||
      for pkg in $enableval; do
 | 
			
		||||
	IFS=$lt_save_ifs
 | 
			
		||||
	if test "X$pkg" = "X$p"; then
 | 
			
		||||
	  enable_fast_install=yes
 | 
			
		||||
	fi
 | 
			
		||||
      done
 | 
			
		||||
      IFS=$lt_save_ifs
 | 
			
		||||
      ;;
 | 
			
		||||
    esac],
 | 
			
		||||
    [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
 | 
			
		||||
 | 
			
		||||
_LT_DECL([fast_install], [enable_fast_install], [0],
 | 
			
		||||
	 [Whether or not to optimize for fast installation])dnl
 | 
			
		||||
])# _LT_ENABLE_FAST_INSTALL
 | 
			
		||||
 | 
			
		||||
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
 | 
			
		||||
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
 | 
			
		||||
 | 
			
		||||
# Old names:
 | 
			
		||||
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
 | 
			
		||||
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
 | 
			
		||||
AC_DIAGNOSE([obsolete],
 | 
			
		||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
 | 
			
		||||
the 'fast-install' option into LT_INIT's first parameter.])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
 | 
			
		||||
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
 | 
			
		||||
AC_DIAGNOSE([obsolete],
 | 
			
		||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
 | 
			
		||||
the 'disable-fast-install' option into LT_INIT's first parameter.])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl aclocal-1.4 backwards compatibility:
 | 
			
		||||
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
 | 
			
		||||
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# _LT_WITH_AIX_SONAME([DEFAULT])
 | 
			
		||||
# ----------------------------------
 | 
			
		||||
# implement the --with-aix-soname flag, and support the `aix-soname=aix'
 | 
			
		||||
# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
 | 
			
		||||
# is either `aix', `both' or `svr4'.  If omitted, it defaults to `aix'.
 | 
			
		||||
m4_define([_LT_WITH_AIX_SONAME],
 | 
			
		||||
[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
 | 
			
		||||
shared_archive_member_spec=
 | 
			
		||||
case $host,$enable_shared in
 | 
			
		||||
power*-*-aix[[5-9]]*,yes)
 | 
			
		||||
  AC_MSG_CHECKING([which variant of shared library versioning to provide])
 | 
			
		||||
  AC_ARG_WITH([aix-soname],
 | 
			
		||||
    [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
 | 
			
		||||
      [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
 | 
			
		||||
    [case $withval in
 | 
			
		||||
    aix|svr4|both)
 | 
			
		||||
      ;;
 | 
			
		||||
    *)
 | 
			
		||||
      AC_MSG_ERROR([Unknown argument to --with-aix-soname])
 | 
			
		||||
      ;;
 | 
			
		||||
    esac
 | 
			
		||||
    lt_cv_with_aix_soname=$with_aix_soname],
 | 
			
		||||
    [AC_CACHE_VAL([lt_cv_with_aix_soname],
 | 
			
		||||
      [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
 | 
			
		||||
    with_aix_soname=$lt_cv_with_aix_soname])
 | 
			
		||||
  AC_MSG_RESULT([$with_aix_soname])
 | 
			
		||||
  if test aix != "$with_aix_soname"; then
 | 
			
		||||
    # For the AIX way of multilib, we name the shared archive member
 | 
			
		||||
    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
 | 
			
		||||
    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
 | 
			
		||||
    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
 | 
			
		||||
    # the AIX toolchain works better with OBJECT_MODE set (default 32).
 | 
			
		||||
    if test 64 = "${OBJECT_MODE-32}"; then
 | 
			
		||||
      shared_archive_member_spec=shr_64
 | 
			
		||||
    else
 | 
			
		||||
      shared_archive_member_spec=shr
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
  ;;
 | 
			
		||||
*)
 | 
			
		||||
  with_aix_soname=aix
 | 
			
		||||
  ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
_LT_DECL([], [shared_archive_member_spec], [0],
 | 
			
		||||
    [Shared archive member basename, for filename based shared library versioning on AIX])dnl
 | 
			
		||||
])# _LT_WITH_AIX_SONAME
 | 
			
		||||
 | 
			
		||||
LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
 | 
			
		||||
LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
 | 
			
		||||
LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# _LT_WITH_PIC([MODE])
 | 
			
		||||
# --------------------
 | 
			
		||||
# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
 | 
			
		||||
# LT_INIT options.
 | 
			
		||||
# MODE is either 'yes' or 'no'.  If omitted, it defaults to 'both'.
 | 
			
		||||
m4_define([_LT_WITH_PIC],
 | 
			
		||||
[AC_ARG_WITH([pic],
 | 
			
		||||
    [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
 | 
			
		||||
	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
 | 
			
		||||
    [lt_p=${PACKAGE-default}
 | 
			
		||||
    case $withval in
 | 
			
		||||
    yes|no) pic_mode=$withval ;;
 | 
			
		||||
    *)
 | 
			
		||||
      pic_mode=default
 | 
			
		||||
      # Look at the argument we got.  We use all the common list separators.
 | 
			
		||||
      lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
 | 
			
		||||
      for lt_pkg in $withval; do
 | 
			
		||||
	IFS=$lt_save_ifs
 | 
			
		||||
	if test "X$lt_pkg" = "X$lt_p"; then
 | 
			
		||||
	  pic_mode=yes
 | 
			
		||||
	fi
 | 
			
		||||
      done
 | 
			
		||||
      IFS=$lt_save_ifs
 | 
			
		||||
      ;;
 | 
			
		||||
    esac],
 | 
			
		||||
    [pic_mode=m4_default([$1], [default])])
 | 
			
		||||
 | 
			
		||||
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
 | 
			
		||||
])# _LT_WITH_PIC
 | 
			
		||||
 | 
			
		||||
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
 | 
			
		||||
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
 | 
			
		||||
 | 
			
		||||
# Old name:
 | 
			
		||||
AU_DEFUN([AC_LIBTOOL_PICMODE],
 | 
			
		||||
[_LT_SET_OPTION([LT_INIT], [pic-only])
 | 
			
		||||
AC_DIAGNOSE([obsolete],
 | 
			
		||||
[$0: Remove this warning and the call to _LT_SET_OPTION when you
 | 
			
		||||
put the 'pic-only' option into LT_INIT's first parameter.])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl aclocal-1.4 backwards compatibility:
 | 
			
		||||
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
 | 
			
		||||
 | 
			
		||||
## ----------------- ##
 | 
			
		||||
## LTDL_INIT Options ##
 | 
			
		||||
## ----------------- ##
 | 
			
		||||
 | 
			
		||||
m4_define([_LTDL_MODE], [])
 | 
			
		||||
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
 | 
			
		||||
		 [m4_define([_LTDL_MODE], [nonrecursive])])
 | 
			
		||||
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
 | 
			
		||||
		 [m4_define([_LTDL_MODE], [recursive])])
 | 
			
		||||
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
 | 
			
		||||
		 [m4_define([_LTDL_MODE], [subproject])])
 | 
			
		||||
 | 
			
		||||
m4_define([_LTDL_TYPE], [])
 | 
			
		||||
LT_OPTION_DEFINE([LTDL_INIT], [installable],
 | 
			
		||||
		 [m4_define([_LTDL_TYPE], [installable])])
 | 
			
		||||
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
 | 
			
		||||
		 [m4_define([_LTDL_TYPE], [convenience])])
 | 
			
		||||
							
								
								
									
										124
									
								
								m4/ltsugar.m4
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								m4/ltsugar.m4
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,124 @@
 | 
			
		||||
# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
 | 
			
		||||
#
 | 
			
		||||
# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
 | 
			
		||||
# Foundation, Inc.
 | 
			
		||||
# Written by Gary V. Vaughan, 2004
 | 
			
		||||
#
 | 
			
		||||
# This file is free software; the Free Software Foundation gives
 | 
			
		||||
# unlimited permission to copy and/or distribute it, with or without
 | 
			
		||||
# modifications, as long as this notice is preserved.
 | 
			
		||||
 | 
			
		||||
# serial 6 ltsugar.m4
 | 
			
		||||
 | 
			
		||||
# This is to help aclocal find these macros, as it can't see m4_define.
 | 
			
		||||
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# lt_join(SEP, ARG1, [ARG2...])
 | 
			
		||||
# -----------------------------
 | 
			
		||||
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
 | 
			
		||||
# associated separator.
 | 
			
		||||
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
 | 
			
		||||
# versions in m4sugar had bugs.
 | 
			
		||||
m4_define([lt_join],
 | 
			
		||||
[m4_if([$#], [1], [],
 | 
			
		||||
       [$#], [2], [[$2]],
 | 
			
		||||
       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
 | 
			
		||||
m4_define([_lt_join],
 | 
			
		||||
[m4_if([$#$2], [2], [],
 | 
			
		||||
       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# lt_car(LIST)
 | 
			
		||||
# lt_cdr(LIST)
 | 
			
		||||
# ------------
 | 
			
		||||
# Manipulate m4 lists.
 | 
			
		||||
# These macros are necessary as long as will still need to support
 | 
			
		||||
# Autoconf-2.59, which quotes differently.
 | 
			
		||||
m4_define([lt_car], [[$1]])
 | 
			
		||||
m4_define([lt_cdr],
 | 
			
		||||
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
 | 
			
		||||
       [$#], 1, [],
 | 
			
		||||
       [m4_dquote(m4_shift($@))])])
 | 
			
		||||
m4_define([lt_unquote], $1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
 | 
			
		||||
# ------------------------------------------
 | 
			
		||||
# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
 | 
			
		||||
# Note that neither SEPARATOR nor STRING are expanded; they are appended
 | 
			
		||||
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
 | 
			
		||||
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
 | 
			
		||||
# than defined and empty).
 | 
			
		||||
#
 | 
			
		||||
# This macro is needed until we can rely on Autoconf 2.62, since earlier
 | 
			
		||||
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
 | 
			
		||||
m4_define([lt_append],
 | 
			
		||||
[m4_define([$1],
 | 
			
		||||
	   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
 | 
			
		||||
# ----------------------------------------------------------
 | 
			
		||||
# Produce a SEP delimited list of all paired combinations of elements of
 | 
			
		||||
# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list
 | 
			
		||||
# has the form PREFIXmINFIXSUFFIXn.
 | 
			
		||||
# Needed until we can rely on m4_combine added in Autoconf 2.62.
 | 
			
		||||
m4_define([lt_combine],
 | 
			
		||||
[m4_if(m4_eval([$# > 3]), [1],
 | 
			
		||||
       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
 | 
			
		||||
[[m4_foreach([_Lt_prefix], [$2],
 | 
			
		||||
	     [m4_foreach([_Lt_suffix],
 | 
			
		||||
		]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
 | 
			
		||||
	[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
 | 
			
		||||
# -----------------------------------------------------------------------
 | 
			
		||||
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
 | 
			
		||||
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
 | 
			
		||||
m4_define([lt_if_append_uniq],
 | 
			
		||||
[m4_ifdef([$1],
 | 
			
		||||
	  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
 | 
			
		||||
		 [lt_append([$1], [$2], [$3])$4],
 | 
			
		||||
		 [$5])],
 | 
			
		||||
	  [lt_append([$1], [$2], [$3])$4])])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# lt_dict_add(DICT, KEY, VALUE)
 | 
			
		||||
# -----------------------------
 | 
			
		||||
m4_define([lt_dict_add],
 | 
			
		||||
[m4_define([$1($2)], [$3])])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
 | 
			
		||||
# --------------------------------------------
 | 
			
		||||
m4_define([lt_dict_add_subkey],
 | 
			
		||||
[m4_define([$1($2:$3)], [$4])])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# lt_dict_fetch(DICT, KEY, [SUBKEY])
 | 
			
		||||
# ----------------------------------
 | 
			
		||||
m4_define([lt_dict_fetch],
 | 
			
		||||
[m4_ifval([$3],
 | 
			
		||||
	m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
 | 
			
		||||
    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
 | 
			
		||||
# -----------------------------------------------------------------
 | 
			
		||||
m4_define([lt_if_dict_fetch],
 | 
			
		||||
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
 | 
			
		||||
	[$5],
 | 
			
		||||
    [$6])])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
 | 
			
		||||
# --------------------------------------------------------------
 | 
			
		||||
m4_define([lt_dict_filter],
 | 
			
		||||
[m4_if([$5], [], [],
 | 
			
		||||
  [lt_join(m4_quote(m4_default([$4], [[, ]])),
 | 
			
		||||
           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
 | 
			
		||||
		      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
 | 
			
		||||
])
 | 
			
		||||
							
								
								
									
										23
									
								
								m4/ltversion.m4
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								m4/ltversion.m4
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
# ltversion.m4 -- version numbers			-*- Autoconf -*-
 | 
			
		||||
#
 | 
			
		||||
#   Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
 | 
			
		||||
#   Written by Scott James Remnant, 2004
 | 
			
		||||
#
 | 
			
		||||
# This file is free software; the Free Software Foundation gives
 | 
			
		||||
# unlimited permission to copy and/or distribute it, with or without
 | 
			
		||||
# modifications, as long as this notice is preserved.
 | 
			
		||||
 | 
			
		||||
# @configure_input@
 | 
			
		||||
 | 
			
		||||
# serial 4179 ltversion.m4
 | 
			
		||||
# This file is part of GNU Libtool
 | 
			
		||||
 | 
			
		||||
m4_define([LT_PACKAGE_VERSION], [2.4.6])
 | 
			
		||||
m4_define([LT_PACKAGE_REVISION], [2.4.6])
 | 
			
		||||
 | 
			
		||||
AC_DEFUN([LTVERSION_VERSION],
 | 
			
		||||
[macro_version='2.4.6'
 | 
			
		||||
macro_revision='2.4.6'
 | 
			
		||||
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
 | 
			
		||||
_LT_DECL(, macro_revision, 0)
 | 
			
		||||
])
 | 
			
		||||
							
								
								
									
										99
									
								
								m4/lt~obsolete.m4
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								m4/lt~obsolete.m4
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,99 @@
 | 
			
		||||
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
 | 
			
		||||
#
 | 
			
		||||
#   Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
 | 
			
		||||
#   Foundation, Inc.
 | 
			
		||||
#   Written by Scott James Remnant, 2004.
 | 
			
		||||
#
 | 
			
		||||
# This file is free software; the Free Software Foundation gives
 | 
			
		||||
# unlimited permission to copy and/or distribute it, with or without
 | 
			
		||||
# modifications, as long as this notice is preserved.
 | 
			
		||||
 | 
			
		||||
# serial 5 lt~obsolete.m4
 | 
			
		||||
 | 
			
		||||
# These exist entirely to fool aclocal when bootstrapping libtool.
 | 
			
		||||
#
 | 
			
		||||
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
 | 
			
		||||
# which have later been changed to m4_define as they aren't part of the
 | 
			
		||||
# exported API, or moved to Autoconf or Automake where they belong.
 | 
			
		||||
#
 | 
			
		||||
# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN
 | 
			
		||||
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
 | 
			
		||||
# using a macro with the same name in our local m4/libtool.m4 it'll
 | 
			
		||||
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
 | 
			
		||||
# and doesn't know about Autoconf macros at all.)
 | 
			
		||||
#
 | 
			
		||||
# So we provide this file, which has a silly filename so it's always
 | 
			
		||||
# included after everything else.  This provides aclocal with the
 | 
			
		||||
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
 | 
			
		||||
# because those macros already exist, or will be overwritten later.
 | 
			
		||||
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
 | 
			
		||||
#
 | 
			
		||||
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
 | 
			
		||||
# Yes, that means every name once taken will need to remain here until
 | 
			
		||||
# we give up compatibility with versions before 1.7, at which point
 | 
			
		||||
# we need to keep only those names which we still refer to.
 | 
			
		||||
 | 
			
		||||
# This is to help aclocal find these macros, as it can't see m4_define.
 | 
			
		||||
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
 | 
			
		||||
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_LINKER_OPTION],	[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
 | 
			
		||||
m4_ifndef([AC_PROG_EGREP],		[AC_DEFUN([AC_PROG_EGREP])])
 | 
			
		||||
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
 | 
			
		||||
m4_ifndef([_LT_AC_SHELL_INIT],		[AC_DEFUN([_LT_AC_SHELL_INIT])])
 | 
			
		||||
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX],	[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
 | 
			
		||||
m4_ifndef([_LT_PROG_LTMAIN],		[AC_DEFUN([_LT_PROG_LTMAIN])])
 | 
			
		||||
m4_ifndef([_LT_AC_TAGVAR],		[AC_DEFUN([_LT_AC_TAGVAR])])
 | 
			
		||||
m4_ifndef([AC_LTDL_ENABLE_INSTALL],	[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
 | 
			
		||||
m4_ifndef([AC_LTDL_PREOPEN],		[AC_DEFUN([AC_LTDL_PREOPEN])])
 | 
			
		||||
m4_ifndef([_LT_AC_SYS_COMPILER],	[AC_DEFUN([_LT_AC_SYS_COMPILER])])
 | 
			
		||||
m4_ifndef([_LT_AC_LOCK],		[AC_DEFUN([_LT_AC_LOCK])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],	[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
 | 
			
		||||
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF],	[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O],	[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_OBJDIR],		[AC_DEFUN([AC_LIBTOOL_OBJDIR])])
 | 
			
		||||
m4_ifndef([AC_LTDL_OBJDIR],		[AC_DEFUN([AC_LTDL_OBJDIR])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],	[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
 | 
			
		||||
m4_ifndef([AC_PATH_MAGIC],		[AC_DEFUN([AC_PATH_MAGIC])])
 | 
			
		||||
m4_ifndef([AC_PROG_LD_GNU],		[AC_DEFUN([AC_PROG_LD_GNU])])
 | 
			
		||||
m4_ifndef([AC_PROG_LD_RELOAD_FLAG],	[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
 | 
			
		||||
m4_ifndef([AC_DEPLIBS_CHECK_METHOD],	[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],	[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],	[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
 | 
			
		||||
m4_ifndef([LT_AC_PROG_EGREP],		[AC_DEFUN([LT_AC_PROG_EGREP])])
 | 
			
		||||
m4_ifndef([LT_AC_PROG_SED],		[AC_DEFUN([LT_AC_PROG_SED])])
 | 
			
		||||
m4_ifndef([_LT_CC_BASENAME],		[AC_DEFUN([_LT_CC_BASENAME])])
 | 
			
		||||
m4_ifndef([_LT_COMPILER_BOILERPLATE],	[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
 | 
			
		||||
m4_ifndef([_LT_LINKER_BOILERPLATE],	[AC_DEFUN([_LT_LINKER_BOILERPLATE])])
 | 
			
		||||
m4_ifndef([_AC_PROG_LIBTOOL],		[AC_DEFUN([_AC_PROG_LIBTOOL])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_SETUP],		[AC_DEFUN([AC_LIBTOOL_SETUP])])
 | 
			
		||||
m4_ifndef([_LT_AC_CHECK_DLFCN],		[AC_DEFUN([_LT_AC_CHECK_DLFCN])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],	[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
 | 
			
		||||
m4_ifndef([_LT_AC_TAGCONFIG],		[AC_DEFUN([_LT_AC_TAGCONFIG])])
 | 
			
		||||
m4_ifndef([AC_DISABLE_FAST_INSTALL],	[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
 | 
			
		||||
m4_ifndef([_LT_AC_LANG_CXX],		[AC_DEFUN([_LT_AC_LANG_CXX])])
 | 
			
		||||
m4_ifndef([_LT_AC_LANG_F77],		[AC_DEFUN([_LT_AC_LANG_F77])])
 | 
			
		||||
m4_ifndef([_LT_AC_LANG_GCJ],		[AC_DEFUN([_LT_AC_LANG_GCJ])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
 | 
			
		||||
m4_ifndef([_LT_AC_LANG_C_CONFIG],	[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
 | 
			
		||||
m4_ifndef([_LT_AC_LANG_CXX_CONFIG],	[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
 | 
			
		||||
m4_ifndef([_LT_AC_LANG_F77_CONFIG],	[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
 | 
			
		||||
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG],	[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
 | 
			
		||||
m4_ifndef([_LT_AC_LANG_RC_CONFIG],	[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
 | 
			
		||||
m4_ifndef([AC_LIBTOOL_CONFIG],		[AC_DEFUN([AC_LIBTOOL_CONFIG])])
 | 
			
		||||
m4_ifndef([_LT_AC_FILE_LTDLL_C],	[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
 | 
			
		||||
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS],	[AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
 | 
			
		||||
m4_ifndef([_LT_AC_PROG_CXXCPP],		[AC_DEFUN([_LT_AC_PROG_CXXCPP])])
 | 
			
		||||
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS],	[AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
 | 
			
		||||
m4_ifndef([_LT_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
 | 
			
		||||
m4_ifndef([_LT_PROG_F77],		[AC_DEFUN([_LT_PROG_F77])])
 | 
			
		||||
m4_ifndef([_LT_PROG_FC],		[AC_DEFUN([_LT_PROG_FC])])
 | 
			
		||||
m4_ifndef([_LT_PROG_CXX],		[AC_DEFUN([_LT_PROG_CXX])])
 | 
			
		||||
							
								
								
									
										32
									
								
								m4/nls.m4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								m4/nls.m4
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
# nls.m4 serial 5 (gettext-0.18)
 | 
			
		||||
dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation,
 | 
			
		||||
dnl Inc.
 | 
			
		||||
dnl This file is free software; the Free Software Foundation
 | 
			
		||||
dnl gives unlimited permission to copy and/or distribute it,
 | 
			
		||||
dnl with or without modifications, as long as this notice is preserved.
 | 
			
		||||
dnl
 | 
			
		||||
dnl This file can can be used in projects which are not available under
 | 
			
		||||
dnl the GNU General Public License or the GNU Library General Public
 | 
			
		||||
dnl License but which still want to provide support for the GNU gettext
 | 
			
		||||
dnl functionality.
 | 
			
		||||
dnl Please note that the actual code of the GNU gettext library is covered
 | 
			
		||||
dnl by the GNU Library General Public License, and the rest of the GNU
 | 
			
		||||
dnl gettext package package is covered by the GNU General Public License.
 | 
			
		||||
dnl They are *not* in the public domain.
 | 
			
		||||
 | 
			
		||||
dnl Authors:
 | 
			
		||||
dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
 | 
			
		||||
dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2003.
 | 
			
		||||
 | 
			
		||||
AC_PREREQ([2.50])
 | 
			
		||||
 | 
			
		||||
AC_DEFUN([AM_NLS],
 | 
			
		||||
[
 | 
			
		||||
  AC_MSG_CHECKING([whether NLS is requested])
 | 
			
		||||
  dnl Default is enabled NLS
 | 
			
		||||
  AC_ARG_ENABLE([nls],
 | 
			
		||||
    [  --disable-nls           do not use Native Language Support],
 | 
			
		||||
    USE_NLS=$enableval, USE_NLS=yes)
 | 
			
		||||
  AC_MSG_RESULT([$USE_NLS])
 | 
			
		||||
  AC_SUBST([USE_NLS])
 | 
			
		||||
])
 | 
			
		||||
							
								
								
									
										57
									
								
								m4/pkg.m4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								m4/pkg.m4
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,57 @@
 | 
			
		||||
 | 
			
		||||
dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
 | 
			
		||||
dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
 | 
			
		||||
dnl also defines GSTUFF_PKG_ERRORS on error
 | 
			
		||||
AC_DEFUN([PKG_CHECK_MODULES], [
 | 
			
		||||
  succeeded=no
 | 
			
		||||
 | 
			
		||||
  if test -z "$PKG_CONFIG"; then
 | 
			
		||||
    AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if test "$PKG_CONFIG" = "no" ; then
 | 
			
		||||
     echo "*** The pkg-config script could not be found. Make sure it is"
 | 
			
		||||
     echo "*** in your path, or set the PKG_CONFIG environment variable"
 | 
			
		||||
     echo "*** to the full path to pkg-config."
 | 
			
		||||
     echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
 | 
			
		||||
  else
 | 
			
		||||
     PKG_CONFIG_MIN_VERSION=0.9.0
 | 
			
		||||
     if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
 | 
			
		||||
        AC_MSG_CHECKING(for $2)
 | 
			
		||||
 | 
			
		||||
        if $PKG_CONFIG --exists "$2" ; then
 | 
			
		||||
            AC_MSG_RESULT(yes)
 | 
			
		||||
            succeeded=yes
 | 
			
		||||
 | 
			
		||||
            AC_MSG_CHECKING($1_CFLAGS)
 | 
			
		||||
            $1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
 | 
			
		||||
            AC_MSG_RESULT($$1_CFLAGS)
 | 
			
		||||
 | 
			
		||||
            AC_MSG_CHECKING($1_LIBS)
 | 
			
		||||
            $1_LIBS=`$PKG_CONFIG --libs "$2"`
 | 
			
		||||
            AC_MSG_RESULT($$1_LIBS)
 | 
			
		||||
        else
 | 
			
		||||
            $1_CFLAGS=""
 | 
			
		||||
            $1_LIBS=""
 | 
			
		||||
            ## If we have a custom action on failure, don't print errors, but 
 | 
			
		||||
            ## do set a variable so people can do so.
 | 
			
		||||
            $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
 | 
			
		||||
            ifelse([$4], ,echo $$1_PKG_ERRORS,)
 | 
			
		||||
        fi
 | 
			
		||||
 | 
			
		||||
        AC_SUBST($1_CFLAGS)
 | 
			
		||||
        AC_SUBST($1_LIBS)
 | 
			
		||||
     else
 | 
			
		||||
        echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
 | 
			
		||||
        echo "*** See http://www.freedesktop.org/software/pkgconfig"
 | 
			
		||||
     fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  if test $succeeded = yes; then
 | 
			
		||||
     ifelse([$3], , :, [$3])
 | 
			
		||||
  else
 | 
			
		||||
     ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4])
 | 
			
		||||
  fi
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										449
									
								
								m4/po.m4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										449
									
								
								m4/po.m4
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,449 @@
 | 
			
		||||
# po.m4 serial 17 (gettext-0.18)
 | 
			
		||||
dnl Copyright (C) 1995-2010 Free Software Foundation, Inc.
 | 
			
		||||
dnl This file is free software; the Free Software Foundation
 | 
			
		||||
dnl gives unlimited permission to copy and/or distribute it,
 | 
			
		||||
dnl with or without modifications, as long as this notice is preserved.
 | 
			
		||||
dnl
 | 
			
		||||
dnl This file can can be used in projects which are not available under
 | 
			
		||||
dnl the GNU General Public License or the GNU Library General Public
 | 
			
		||||
dnl License but which still want to provide support for the GNU gettext
 | 
			
		||||
dnl functionality.
 | 
			
		||||
dnl Please note that the actual code of the GNU gettext library is covered
 | 
			
		||||
dnl by the GNU Library General Public License, and the rest of the GNU
 | 
			
		||||
dnl gettext package package is covered by the GNU General Public License.
 | 
			
		||||
dnl They are *not* in the public domain.
 | 
			
		||||
 | 
			
		||||
dnl Authors:
 | 
			
		||||
dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
 | 
			
		||||
dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2003.
 | 
			
		||||
 | 
			
		||||
AC_PREREQ([2.50])
 | 
			
		||||
 | 
			
		||||
dnl Checks for all prerequisites of the po subdirectory.
 | 
			
		||||
AC_DEFUN([AM_PO_SUBDIRS],
 | 
			
		||||
[
 | 
			
		||||
  AC_REQUIRE([AC_PROG_MAKE_SET])dnl
 | 
			
		||||
  AC_REQUIRE([AC_PROG_INSTALL])dnl
 | 
			
		||||
  AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake
 | 
			
		||||
  AC_REQUIRE([AM_NLS])dnl
 | 
			
		||||
 | 
			
		||||
  dnl Release version of the gettext macros. This is used to ensure that
 | 
			
		||||
  dnl the gettext macros and po/Makefile.in.in are in sync.
 | 
			
		||||
  AC_SUBST([GETTEXT_MACRO_VERSION], [0.18])
 | 
			
		||||
 | 
			
		||||
  dnl Perform the following tests also if --disable-nls has been given,
 | 
			
		||||
  dnl because they are needed for "make dist" to work.
 | 
			
		||||
 | 
			
		||||
  dnl Search for GNU msgfmt in the PATH.
 | 
			
		||||
  dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions.
 | 
			
		||||
  dnl The second test excludes FreeBSD msgfmt.
 | 
			
		||||
  AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
 | 
			
		||||
    [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
 | 
			
		||||
     (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
 | 
			
		||||
    :)
 | 
			
		||||
  AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT])
 | 
			
		||||
 | 
			
		||||
  dnl Test whether it is GNU msgfmt >= 0.15.
 | 
			
		||||
changequote(,)dnl
 | 
			
		||||
  case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
 | 
			
		||||
    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
 | 
			
		||||
    *) MSGFMT_015=$MSGFMT ;;
 | 
			
		||||
  esac
 | 
			
		||||
changequote([,])dnl
 | 
			
		||||
  AC_SUBST([MSGFMT_015])
 | 
			
		||||
changequote(,)dnl
 | 
			
		||||
  case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
 | 
			
		||||
    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
 | 
			
		||||
    *) GMSGFMT_015=$GMSGFMT ;;
 | 
			
		||||
  esac
 | 
			
		||||
changequote([,])dnl
 | 
			
		||||
  AC_SUBST([GMSGFMT_015])
 | 
			
		||||
 | 
			
		||||
  dnl Search for GNU xgettext 0.12 or newer in the PATH.
 | 
			
		||||
  dnl The first test excludes Solaris xgettext and early GNU xgettext versions.
 | 
			
		||||
  dnl The second test excludes FreeBSD xgettext.
 | 
			
		||||
  AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
 | 
			
		||||
    [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
 | 
			
		||||
     (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
 | 
			
		||||
    :)
 | 
			
		||||
  dnl Remove leftover from FreeBSD xgettext call.
 | 
			
		||||
  rm -f messages.po
 | 
			
		||||
 | 
			
		||||
  dnl Test whether it is GNU xgettext >= 0.15.
 | 
			
		||||
changequote(,)dnl
 | 
			
		||||
  case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
 | 
			
		||||
    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;;
 | 
			
		||||
    *) XGETTEXT_015=$XGETTEXT ;;
 | 
			
		||||
  esac
 | 
			
		||||
changequote([,])dnl
 | 
			
		||||
  AC_SUBST([XGETTEXT_015])
 | 
			
		||||
 | 
			
		||||
  dnl Search for GNU msgmerge 0.11 or newer in the PATH.
 | 
			
		||||
  AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge,
 | 
			
		||||
    [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :)
 | 
			
		||||
 | 
			
		||||
  dnl Installation directories.
 | 
			
		||||
  dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we
 | 
			
		||||
  dnl have to define it here, so that it can be used in po/Makefile.
 | 
			
		||||
  test -n "$localedir" || localedir='${datadir}/locale'
 | 
			
		||||
  AC_SUBST([localedir])
 | 
			
		||||
 | 
			
		||||
  dnl Support for AM_XGETTEXT_OPTION.
 | 
			
		||||
  test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
 | 
			
		||||
  AC_SUBST([XGETTEXT_EXTRA_OPTIONS])
 | 
			
		||||
 | 
			
		||||
  AC_CONFIG_COMMANDS([po-directories], [[
 | 
			
		||||
    for ac_file in $CONFIG_FILES; do
 | 
			
		||||
      # Support "outfile[:infile[:infile...]]"
 | 
			
		||||
      case "$ac_file" in
 | 
			
		||||
        *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
 | 
			
		||||
      esac
 | 
			
		||||
      # PO directories have a Makefile.in generated from Makefile.in.in.
 | 
			
		||||
      case "$ac_file" in */Makefile.in)
 | 
			
		||||
        # Adjust a relative srcdir.
 | 
			
		||||
        ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
 | 
			
		||||
        ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
 | 
			
		||||
        ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
 | 
			
		||||
        # In autoconf-2.13 it is called $ac_given_srcdir.
 | 
			
		||||
        # In autoconf-2.50 it is called $srcdir.
 | 
			
		||||
        test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
 | 
			
		||||
        case "$ac_given_srcdir" in
 | 
			
		||||
          .)  top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
 | 
			
		||||
          /*) top_srcdir="$ac_given_srcdir" ;;
 | 
			
		||||
          *)  top_srcdir="$ac_dots$ac_given_srcdir" ;;
 | 
			
		||||
        esac
 | 
			
		||||
        # Treat a directory as a PO directory if and only if it has a
 | 
			
		||||
        # POTFILES.in file. This allows packages to have multiple PO
 | 
			
		||||
        # directories under different names or in different locations.
 | 
			
		||||
        if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
 | 
			
		||||
          rm -f "$ac_dir/POTFILES"
 | 
			
		||||
          test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
 | 
			
		||||
          cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ 	]*\$/d" -e "s,.*,     $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
 | 
			
		||||
          POMAKEFILEDEPS="POTFILES.in"
 | 
			
		||||
          # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend
 | 
			
		||||
          # on $ac_dir but don't depend on user-specified configuration
 | 
			
		||||
          # parameters.
 | 
			
		||||
          if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
 | 
			
		||||
            # The LINGUAS file contains the set of available languages.
 | 
			
		||||
            if test -n "$OBSOLETE_ALL_LINGUAS"; then
 | 
			
		||||
              test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
 | 
			
		||||
            fi
 | 
			
		||||
            ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
 | 
			
		||||
            # Hide the ALL_LINGUAS assigment from automake < 1.5.
 | 
			
		||||
            eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
 | 
			
		||||
            POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
 | 
			
		||||
          else
 | 
			
		||||
            # The set of available languages was given in configure.in.
 | 
			
		||||
            # Hide the ALL_LINGUAS assigment from automake < 1.5.
 | 
			
		||||
            eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
 | 
			
		||||
          fi
 | 
			
		||||
          # Compute POFILES
 | 
			
		||||
          # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
 | 
			
		||||
          # Compute UPDATEPOFILES
 | 
			
		||||
          # as      $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
 | 
			
		||||
          # Compute DUMMYPOFILES
 | 
			
		||||
          # as      $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
 | 
			
		||||
          # Compute GMOFILES
 | 
			
		||||
          # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
 | 
			
		||||
          case "$ac_given_srcdir" in
 | 
			
		||||
            .) srcdirpre= ;;
 | 
			
		||||
            *) srcdirpre='$(srcdir)/' ;;
 | 
			
		||||
          esac
 | 
			
		||||
          POFILES=
 | 
			
		||||
          UPDATEPOFILES=
 | 
			
		||||
          DUMMYPOFILES=
 | 
			
		||||
          GMOFILES=
 | 
			
		||||
          for lang in $ALL_LINGUAS; do
 | 
			
		||||
            POFILES="$POFILES $srcdirpre$lang.po"
 | 
			
		||||
            UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
 | 
			
		||||
            DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
 | 
			
		||||
            GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
 | 
			
		||||
          done
 | 
			
		||||
          # CATALOGS depends on both $ac_dir and the user's LINGUAS
 | 
			
		||||
          # environment variable.
 | 
			
		||||
          INST_LINGUAS=
 | 
			
		||||
          if test -n "$ALL_LINGUAS"; then
 | 
			
		||||
            for presentlang in $ALL_LINGUAS; do
 | 
			
		||||
              useit=no
 | 
			
		||||
              if test "%UNSET%" != "$LINGUAS"; then
 | 
			
		||||
                desiredlanguages="$LINGUAS"
 | 
			
		||||
              else
 | 
			
		||||
                desiredlanguages="$ALL_LINGUAS"
 | 
			
		||||
              fi
 | 
			
		||||
              for desiredlang in $desiredlanguages; do
 | 
			
		||||
                # Use the presentlang catalog if desiredlang is
 | 
			
		||||
                #   a. equal to presentlang, or
 | 
			
		||||
                #   b. a variant of presentlang (because in this case,
 | 
			
		||||
                #      presentlang can be used as a fallback for messages
 | 
			
		||||
                #      which are not translated in the desiredlang catalog).
 | 
			
		||||
                case "$desiredlang" in
 | 
			
		||||
                  "$presentlang"*) useit=yes;;
 | 
			
		||||
                esac
 | 
			
		||||
              done
 | 
			
		||||
              if test $useit = yes; then
 | 
			
		||||
                INST_LINGUAS="$INST_LINGUAS $presentlang"
 | 
			
		||||
              fi
 | 
			
		||||
            done
 | 
			
		||||
          fi
 | 
			
		||||
          CATALOGS=
 | 
			
		||||
          if test -n "$INST_LINGUAS"; then
 | 
			
		||||
            for lang in $INST_LINGUAS; do
 | 
			
		||||
              CATALOGS="$CATALOGS $lang.gmo"
 | 
			
		||||
            done
 | 
			
		||||
          fi
 | 
			
		||||
          test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
 | 
			
		||||
          sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
 | 
			
		||||
          for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
 | 
			
		||||
            if test -f "$f"; then
 | 
			
		||||
              case "$f" in
 | 
			
		||||
                *.orig | *.bak | *~) ;;
 | 
			
		||||
                *) cat "$f" >> "$ac_dir/Makefile" ;;
 | 
			
		||||
              esac
 | 
			
		||||
            fi
 | 
			
		||||
          done
 | 
			
		||||
        fi
 | 
			
		||||
        ;;
 | 
			
		||||
      esac
 | 
			
		||||
    done]],
 | 
			
		||||
   [# Capture the value of obsolete ALL_LINGUAS because we need it to compute
 | 
			
		||||
    # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
 | 
			
		||||
    # from automake < 1.5.
 | 
			
		||||
    eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
 | 
			
		||||
    # Capture the value of LINGUAS because we need it to compute CATALOGS.
 | 
			
		||||
    LINGUAS="${LINGUAS-%UNSET%}"
 | 
			
		||||
   ])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl Postprocesses a Makefile in a directory containing PO files.
 | 
			
		||||
AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE],
 | 
			
		||||
[
 | 
			
		||||
  # When this code is run, in config.status, two variables have already been
 | 
			
		||||
  # set:
 | 
			
		||||
  # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in,
 | 
			
		||||
  # - LINGUAS is the value of the environment variable LINGUAS at configure
 | 
			
		||||
  #   time.
 | 
			
		||||
 | 
			
		||||
changequote(,)dnl
 | 
			
		||||
  # Adjust a relative srcdir.
 | 
			
		||||
  ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
 | 
			
		||||
  ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
 | 
			
		||||
  ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
 | 
			
		||||
  # In autoconf-2.13 it is called $ac_given_srcdir.
 | 
			
		||||
  # In autoconf-2.50 it is called $srcdir.
 | 
			
		||||
  test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
 | 
			
		||||
  case "$ac_given_srcdir" in
 | 
			
		||||
    .)  top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
 | 
			
		||||
    /*) top_srcdir="$ac_given_srcdir" ;;
 | 
			
		||||
    *)  top_srcdir="$ac_dots$ac_given_srcdir" ;;
 | 
			
		||||
  esac
 | 
			
		||||
 | 
			
		||||
  # Find a way to echo strings without interpreting backslash.
 | 
			
		||||
  if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then
 | 
			
		||||
    gt_echo='echo'
 | 
			
		||||
  else
 | 
			
		||||
    if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then
 | 
			
		||||
      gt_echo='printf %s\n'
 | 
			
		||||
    else
 | 
			
		||||
      echo_func () {
 | 
			
		||||
        cat <<EOT
 | 
			
		||||
$*
 | 
			
		||||
EOT
 | 
			
		||||
      }
 | 
			
		||||
      gt_echo='echo_func'
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  # A sed script that extracts the value of VARIABLE from a Makefile.
 | 
			
		||||
  sed_x_variable='
 | 
			
		||||
# Test if the hold space is empty.
 | 
			
		||||
x
 | 
			
		||||
s/P/P/
 | 
			
		||||
x
 | 
			
		||||
ta
 | 
			
		||||
# Yes it was empty. Look if we have the expected variable definition.
 | 
			
		||||
/^[	 ]*VARIABLE[	 ]*=/{
 | 
			
		||||
  # Seen the first line of the variable definition.
 | 
			
		||||
  s/^[	 ]*VARIABLE[	 ]*=//
 | 
			
		||||
  ba
 | 
			
		||||
}
 | 
			
		||||
bd
 | 
			
		||||
:a
 | 
			
		||||
# Here we are processing a line from the variable definition.
 | 
			
		||||
# Remove comment, more precisely replace it with a space.
 | 
			
		||||
s/#.*$/ /
 | 
			
		||||
# See if the line ends in a backslash.
 | 
			
		||||
tb
 | 
			
		||||
:b
 | 
			
		||||
s/\\$//
 | 
			
		||||
# Print the line, without the trailing backslash.
 | 
			
		||||
p
 | 
			
		||||
tc
 | 
			
		||||
# There was no trailing backslash. The end of the variable definition is
 | 
			
		||||
# reached. Clear the hold space.
 | 
			
		||||
s/^.*$//
 | 
			
		||||
x
 | 
			
		||||
bd
 | 
			
		||||
:c
 | 
			
		||||
# A trailing backslash means that the variable definition continues in the
 | 
			
		||||
# next line. Put a nonempty string into the hold space to indicate this.
 | 
			
		||||
s/^.*$/P/
 | 
			
		||||
x
 | 
			
		||||
:d
 | 
			
		||||
'
 | 
			
		||||
changequote([,])dnl
 | 
			
		||||
 | 
			
		||||
  # Set POTFILES to the value of the Makefile variable POTFILES.
 | 
			
		||||
  sed_x_POTFILES=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/POTFILES/g'`
 | 
			
		||||
  POTFILES=`sed -n -e "$sed_x_POTFILES" < "$ac_file"`
 | 
			
		||||
  # Compute POTFILES_DEPS as
 | 
			
		||||
  #   $(foreach file, $(POTFILES), $(top_srcdir)/$(file))
 | 
			
		||||
  POTFILES_DEPS=
 | 
			
		||||
  for file in $POTFILES; do
 | 
			
		||||
    POTFILES_DEPS="$POTFILES_DEPS "'$(top_srcdir)/'"$file"
 | 
			
		||||
  done
 | 
			
		||||
  POMAKEFILEDEPS=""
 | 
			
		||||
 | 
			
		||||
  if test -n "$OBSOLETE_ALL_LINGUAS"; then
 | 
			
		||||
    test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
 | 
			
		||||
  fi
 | 
			
		||||
  if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
 | 
			
		||||
    # The LINGUAS file contains the set of available languages.
 | 
			
		||||
    ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
 | 
			
		||||
    POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
 | 
			
		||||
  else
 | 
			
		||||
    # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS.
 | 
			
		||||
    sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'`
 | 
			
		||||
    ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"`
 | 
			
		||||
  fi
 | 
			
		||||
  # Hide the ALL_LINGUAS assigment from automake < 1.5.
 | 
			
		||||
  eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
 | 
			
		||||
  # Compute POFILES
 | 
			
		||||
  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
 | 
			
		||||
  # Compute UPDATEPOFILES
 | 
			
		||||
  # as      $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
 | 
			
		||||
  # Compute DUMMYPOFILES
 | 
			
		||||
  # as      $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
 | 
			
		||||
  # Compute GMOFILES
 | 
			
		||||
  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
 | 
			
		||||
  # Compute PROPERTIESFILES
 | 
			
		||||
  # as      $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).properties)
 | 
			
		||||
  # Compute CLASSFILES
 | 
			
		||||
  # as      $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).class)
 | 
			
		||||
  # Compute QMFILES
 | 
			
		||||
  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm)
 | 
			
		||||
  # Compute MSGFILES
 | 
			
		||||
  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg)
 | 
			
		||||
  # Compute RESOURCESDLLFILES
 | 
			
		||||
  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang))/$(DOMAIN).resources.dll)
 | 
			
		||||
  case "$ac_given_srcdir" in
 | 
			
		||||
    .) srcdirpre= ;;
 | 
			
		||||
    *) srcdirpre='$(srcdir)/' ;;
 | 
			
		||||
  esac
 | 
			
		||||
  POFILES=
 | 
			
		||||
  UPDATEPOFILES=
 | 
			
		||||
  DUMMYPOFILES=
 | 
			
		||||
  GMOFILES=
 | 
			
		||||
  PROPERTIESFILES=
 | 
			
		||||
  CLASSFILES=
 | 
			
		||||
  QMFILES=
 | 
			
		||||
  MSGFILES=
 | 
			
		||||
  RESOURCESDLLFILES=
 | 
			
		||||
  for lang in $ALL_LINGUAS; do
 | 
			
		||||
    POFILES="$POFILES $srcdirpre$lang.po"
 | 
			
		||||
    UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
 | 
			
		||||
    DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
 | 
			
		||||
    GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
 | 
			
		||||
    PROPERTIESFILES="$PROPERTIESFILES \$(top_srcdir)/\$(DOMAIN)_$lang.properties"
 | 
			
		||||
    CLASSFILES="$CLASSFILES \$(top_srcdir)/\$(DOMAIN)_$lang.class"
 | 
			
		||||
    QMFILES="$QMFILES $srcdirpre$lang.qm"
 | 
			
		||||
    frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
 | 
			
		||||
    MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg"
 | 
			
		||||
    frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
 | 
			
		||||
    RESOURCESDLLFILES="$RESOURCESDLLFILES $srcdirpre$frobbedlang/\$(DOMAIN).resources.dll"
 | 
			
		||||
  done
 | 
			
		||||
  # CATALOGS depends on both $ac_dir and the user's LINGUAS
 | 
			
		||||
  # environment variable.
 | 
			
		||||
  INST_LINGUAS=
 | 
			
		||||
  if test -n "$ALL_LINGUAS"; then
 | 
			
		||||
    for presentlang in $ALL_LINGUAS; do
 | 
			
		||||
      useit=no
 | 
			
		||||
      if test "%UNSET%" != "$LINGUAS"; then
 | 
			
		||||
        desiredlanguages="$LINGUAS"
 | 
			
		||||
      else
 | 
			
		||||
        desiredlanguages="$ALL_LINGUAS"
 | 
			
		||||
      fi
 | 
			
		||||
      for desiredlang in $desiredlanguages; do
 | 
			
		||||
        # Use the presentlang catalog if desiredlang is
 | 
			
		||||
        #   a. equal to presentlang, or
 | 
			
		||||
        #   b. a variant of presentlang (because in this case,
 | 
			
		||||
        #      presentlang can be used as a fallback for messages
 | 
			
		||||
        #      which are not translated in the desiredlang catalog).
 | 
			
		||||
        case "$desiredlang" in
 | 
			
		||||
          "$presentlang"*) useit=yes;;
 | 
			
		||||
        esac
 | 
			
		||||
      done
 | 
			
		||||
      if test $useit = yes; then
 | 
			
		||||
        INST_LINGUAS="$INST_LINGUAS $presentlang"
 | 
			
		||||
      fi
 | 
			
		||||
    done
 | 
			
		||||
  fi
 | 
			
		||||
  CATALOGS=
 | 
			
		||||
  JAVACATALOGS=
 | 
			
		||||
  QTCATALOGS=
 | 
			
		||||
  TCLCATALOGS=
 | 
			
		||||
  CSHARPCATALOGS=
 | 
			
		||||
  if test -n "$INST_LINGUAS"; then
 | 
			
		||||
    for lang in $INST_LINGUAS; do
 | 
			
		||||
      CATALOGS="$CATALOGS $lang.gmo"
 | 
			
		||||
      JAVACATALOGS="$JAVACATALOGS \$(DOMAIN)_$lang.properties"
 | 
			
		||||
      QTCATALOGS="$QTCATALOGS $lang.qm"
 | 
			
		||||
      frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
 | 
			
		||||
      TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg"
 | 
			
		||||
      frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
 | 
			
		||||
      CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll"
 | 
			
		||||
    done
 | 
			
		||||
  fi
 | 
			
		||||
 | 
			
		||||
  sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp"
 | 
			
		||||
  if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then
 | 
			
		||||
    # Add dependencies that cannot be formulated as a simple suffix rule.
 | 
			
		||||
    for lang in $ALL_LINGUAS; do
 | 
			
		||||
      frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
 | 
			
		||||
      cat >> "$ac_file.tmp" <<EOF
 | 
			
		||||
$frobbedlang.msg: $lang.po
 | 
			
		||||
	@echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \
 | 
			
		||||
	\$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
 | 
			
		||||
EOF
 | 
			
		||||
    done
 | 
			
		||||
  fi
 | 
			
		||||
  if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then
 | 
			
		||||
    # Add dependencies that cannot be formulated as a simple suffix rule.
 | 
			
		||||
    for lang in $ALL_LINGUAS; do
 | 
			
		||||
      frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
 | 
			
		||||
      cat >> "$ac_file.tmp" <<EOF
 | 
			
		||||
$frobbedlang/\$(DOMAIN).resources.dll: $lang.po
 | 
			
		||||
	@echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \
 | 
			
		||||
	\$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
 | 
			
		||||
EOF
 | 
			
		||||
    done
 | 
			
		||||
  fi
 | 
			
		||||
  if test -n "$POMAKEFILEDEPS"; then
 | 
			
		||||
    cat >> "$ac_file.tmp" <<EOF
 | 
			
		||||
Makefile: $POMAKEFILEDEPS
 | 
			
		||||
EOF
 | 
			
		||||
  fi
 | 
			
		||||
  mv "$ac_file.tmp" "$ac_file"
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl Initializes the accumulator used by AM_XGETTEXT_OPTION.
 | 
			
		||||
AC_DEFUN([AM_XGETTEXT_OPTION_INIT],
 | 
			
		||||
[
 | 
			
		||||
  XGETTEXT_EXTRA_OPTIONS=
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
dnl Registers an option to be passed to xgettext in the po subdirectory.
 | 
			
		||||
AC_DEFUN([AM_XGETTEXT_OPTION],
 | 
			
		||||
[
 | 
			
		||||
  AC_REQUIRE([AM_XGETTEXT_OPTION_INIT])
 | 
			
		||||
  XGETTEXT_EXTRA_OPTIONS="$XGETTEXT_EXTRA_OPTIONS $1"
 | 
			
		||||
])
 | 
			
		||||
							
								
								
									
										92
									
								
								m4/progtest.m4
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								m4/progtest.m4
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,92 @@
 | 
			
		||||
# progtest.m4 serial 6 (gettext-0.18)
 | 
			
		||||
dnl Copyright (C) 1996-2003, 2005, 2008-2010 Free Software Foundation, Inc.
 | 
			
		||||
dnl This file is free software; the Free Software Foundation
 | 
			
		||||
dnl gives unlimited permission to copy and/or distribute it,
 | 
			
		||||
dnl with or without modifications, as long as this notice is preserved.
 | 
			
		||||
dnl
 | 
			
		||||
dnl This file can can be used in projects which are not available under
 | 
			
		||||
dnl the GNU General Public License or the GNU Library General Public
 | 
			
		||||
dnl License but which still want to provide support for the GNU gettext
 | 
			
		||||
dnl functionality.
 | 
			
		||||
dnl Please note that the actual code of the GNU gettext library is covered
 | 
			
		||||
dnl by the GNU Library General Public License, and the rest of the GNU
 | 
			
		||||
dnl gettext package package is covered by the GNU General Public License.
 | 
			
		||||
dnl They are *not* in the public domain.
 | 
			
		||||
 | 
			
		||||
dnl Authors:
 | 
			
		||||
dnl   Ulrich Drepper <drepper@cygnus.com>, 1996.
 | 
			
		||||
 | 
			
		||||
AC_PREREQ([2.50])
 | 
			
		||||
 | 
			
		||||
# Search path for a program which passes the given test.
 | 
			
		||||
 | 
			
		||||
dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
 | 
			
		||||
dnl   TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
 | 
			
		||||
AC_DEFUN([AM_PATH_PROG_WITH_TEST],
 | 
			
		||||
[
 | 
			
		||||
# Prepare PATH_SEPARATOR.
 | 
			
		||||
# The user is always right.
 | 
			
		||||
if test "${PATH_SEPARATOR+set}" != set; then
 | 
			
		||||
  echo "#! /bin/sh" >conf$$.sh
 | 
			
		||||
  echo  "exit 0"   >>conf$$.sh
 | 
			
		||||
  chmod +x conf$$.sh
 | 
			
		||||
  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
 | 
			
		||||
    PATH_SEPARATOR=';'
 | 
			
		||||
  else
 | 
			
		||||
    PATH_SEPARATOR=:
 | 
			
		||||
  fi
 | 
			
		||||
  rm -f conf$$.sh
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Find out how to test for executable files. Don't use a zero-byte file,
 | 
			
		||||
# as systems may use methods other than mode bits to determine executability.
 | 
			
		||||
cat >conf$$.file <<_ASEOF
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
exit 0
 | 
			
		||||
_ASEOF
 | 
			
		||||
chmod +x conf$$.file
 | 
			
		||||
if test -x conf$$.file >/dev/null 2>&1; then
 | 
			
		||||
  ac_executable_p="test -x"
 | 
			
		||||
else
 | 
			
		||||
  ac_executable_p="test -f"
 | 
			
		||||
fi
 | 
			
		||||
rm -f conf$$.file
 | 
			
		||||
 | 
			
		||||
# Extract the first word of "$2", so it can be a program name with args.
 | 
			
		||||
set dummy $2; ac_word=[$]2
 | 
			
		||||
AC_MSG_CHECKING([for $ac_word])
 | 
			
		||||
AC_CACHE_VAL([ac_cv_path_$1],
 | 
			
		||||
[case "[$]$1" in
 | 
			
		||||
  [[\\/]]* | ?:[[\\/]]*)
 | 
			
		||||
    ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
 | 
			
		||||
    ;;
 | 
			
		||||
  *)
 | 
			
		||||
    ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
 | 
			
		||||
    for ac_dir in ifelse([$5], , $PATH, [$5]); do
 | 
			
		||||
      IFS="$ac_save_IFS"
 | 
			
		||||
      test -z "$ac_dir" && ac_dir=.
 | 
			
		||||
      for ac_exec_ext in '' $ac_executable_extensions; do
 | 
			
		||||
        if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
 | 
			
		||||
          echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD
 | 
			
		||||
          if [$3]; then
 | 
			
		||||
            ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext"
 | 
			
		||||
            break 2
 | 
			
		||||
          fi
 | 
			
		||||
        fi
 | 
			
		||||
      done
 | 
			
		||||
    done
 | 
			
		||||
    IFS="$ac_save_IFS"
 | 
			
		||||
dnl If no 4th arg is given, leave the cache variable unset,
 | 
			
		||||
dnl so AC_PATH_PROGS will keep looking.
 | 
			
		||||
ifelse([$4], , , [  test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
 | 
			
		||||
])dnl
 | 
			
		||||
    ;;
 | 
			
		||||
esac])dnl
 | 
			
		||||
$1="$ac_cv_path_$1"
 | 
			
		||||
if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
 | 
			
		||||
  AC_MSG_RESULT([$][$1])
 | 
			
		||||
else
 | 
			
		||||
  AC_MSG_RESULT([no])
 | 
			
		||||
fi
 | 
			
		||||
AC_SUBST([$1])dnl
 | 
			
		||||
])
 | 
			
		||||
							
								
								
									
										25
									
								
								pkgconfig/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								pkgconfig/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,25 @@
 | 
			
		||||
# This Makefile.am is in the public domain
 | 
			
		||||
pcfiles = \
 | 
			
		||||
       gnunetmulticast.pc \
 | 
			
		||||
       gnunetpsyc.pc \
 | 
			
		||||
       gnunetpsycstore.pc
 | 
			
		||||
 | 
			
		||||
all-local: $(pcfiles)
 | 
			
		||||
 | 
			
		||||
cp_verbose = $(cp_verbose_$(V))
 | 
			
		||||
cp_verbose_ = $(cp_verbose_$(AM_DEFAULT_VERBOSITY))
 | 
			
		||||
cp_verbose_0 = @echo "  CP     $@";
 | 
			
		||||
 | 
			
		||||
%.pc: %.pc
 | 
			
		||||
	$(cp_verbose_0)cp $< $@
 | 
			
		||||
 | 
			
		||||
pkgconfigdir = $(libdir)/pkgconfig
 | 
			
		||||
pkgconfig_DATA = $(pcfiles)
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = \
 | 
			
		||||
       gnunetmulticast.pc.in \
 | 
			
		||||
       gnunetpsyc.pc.in \
 | 
			
		||||
       gnunetpsycstore.pc.in
 | 
			
		||||
 | 
			
		||||
CLEANFILES = $(pcfiles)
 | 
			
		||||
AM_CPPFLAGS = -I$(top_srcdir)/src/include
 | 
			
		||||
							
								
								
									
										12
									
								
								pkgconfig/gnunetmulticast.pc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								pkgconfig/gnunetmulticast.pc.in
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
prefix=@prefix@
 | 
			
		||||
exec_prefix=@exec_prefix@
 | 
			
		||||
libdir=@libdir@
 | 
			
		||||
includedir=@includedir@
 | 
			
		||||
 | 
			
		||||
Name: GNUnet MULTICAST
 | 
			
		||||
Description: library to multicast messages to a group of peers
 | 
			
		||||
URL: https://gnunet.org
 | 
			
		||||
Version: @VERSION@
 | 
			
		||||
Requires:
 | 
			
		||||
Libs: -L${libdir} -lgnunetmulticast
 | 
			
		||||
Cflags: -I${includedir}
 | 
			
		||||
							
								
								
									
										12
									
								
								pkgconfig/gnunetpsyc.pc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								pkgconfig/gnunetpsyc.pc.in
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
prefix=@prefix@
 | 
			
		||||
exec_prefix=@exec_prefix@
 | 
			
		||||
libdir=@libdir@
 | 
			
		||||
includedir=@includedir@
 | 
			
		||||
 | 
			
		||||
Name: GNUnet PSYC
 | 
			
		||||
Description: library for PSYC multicast channel management
 | 
			
		||||
URL: https://gnunet.org
 | 
			
		||||
Version: @VERSION@
 | 
			
		||||
Requires:
 | 
			
		||||
Libs: -L${libdir} -lgnunetpsyc
 | 
			
		||||
Cflags: -I${includedir}
 | 
			
		||||
							
								
								
									
										12
									
								
								pkgconfig/gnunetpsycstore.pc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								pkgconfig/gnunetpsycstore.pc.in
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
prefix=@prefix@
 | 
			
		||||
exec_prefix=@exec_prefix@
 | 
			
		||||
libdir=@libdir@
 | 
			
		||||
includedir=@includedir@
 | 
			
		||||
 | 
			
		||||
Name: GNUnet PSYCSTORE
 | 
			
		||||
Description: library to for persistent storage of PSYC messages
 | 
			
		||||
URL: https://gnunet.org
 | 
			
		||||
Version: @VERSION@
 | 
			
		||||
Requires:
 | 
			
		||||
Libs: -L${libdir} -lgnunetpsycstore
 | 
			
		||||
Cflags: -I${includedir}
 | 
			
		||||
							
								
								
									
										6
									
								
								po/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								po/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
Makefile.in
 | 
			
		||||
Makefile
 | 
			
		||||
POTFILES
 | 
			
		||||
gnunet-ext.pot
 | 
			
		||||
remove-potcdate.sed
 | 
			
		||||
stamp-po
 | 
			
		||||
							
								
								
									
										12
									
								
								po/ChangeLog
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								po/ChangeLog
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
2012-03-07  gettextize  <bug-gnu-gettext@gnu.org>
 | 
			
		||||
 | 
			
		||||
	* Makefile.in.in: New file, from gettext-0.18.1.
 | 
			
		||||
	* Rules-quot: New file, from gettext-0.18.1.
 | 
			
		||||
	* boldquot.sed: New file, from gettext-0.18.1.
 | 
			
		||||
	* en@boldquot.header: New file, from gettext-0.18.1.
 | 
			
		||||
	* en@quot.header: New file, from gettext-0.18.1.
 | 
			
		||||
	* insert-header.sin: New file, from gettext-0.18.1.
 | 
			
		||||
	* quot.sed: New file, from gettext-0.18.1.
 | 
			
		||||
	* remove-potcdate.sin: New file, from gettext-0.18.1.
 | 
			
		||||
	* POTFILES.in: New file.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										444
									
								
								po/Makefile.in.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										444
									
								
								po/Makefile.in.in
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,444 @@
 | 
			
		||||
# Makefile for PO directory in any package using GNU gettext.
 | 
			
		||||
# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
 | 
			
		||||
#
 | 
			
		||||
# This file can be copied and used freely without restrictions.  It can
 | 
			
		||||
# be used in projects which are not available under the GNU General Public
 | 
			
		||||
# License but which still want to provide support for the GNU gettext
 | 
			
		||||
# functionality.
 | 
			
		||||
# Please note that the actual code of GNU gettext is covered by the GNU
 | 
			
		||||
# General Public License and is *not* in the public domain.
 | 
			
		||||
#
 | 
			
		||||
# Origin: gettext-0.18
 | 
			
		||||
GETTEXT_MACRO_VERSION = 0.18
 | 
			
		||||
 | 
			
		||||
PACKAGE = @PACKAGE@
 | 
			
		||||
VERSION = @VERSION@
 | 
			
		||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
 | 
			
		||||
 | 
			
		||||
SHELL = /bin/sh
 | 
			
		||||
@SET_MAKE@
 | 
			
		||||
 | 
			
		||||
srcdir = @srcdir@
 | 
			
		||||
top_srcdir = @top_srcdir@
 | 
			
		||||
VPATH = @srcdir@
 | 
			
		||||
 | 
			
		||||
prefix = @prefix@
 | 
			
		||||
exec_prefix = @exec_prefix@
 | 
			
		||||
datarootdir = @datarootdir@
 | 
			
		||||
datadir = @datadir@
 | 
			
		||||
localedir = @localedir@
 | 
			
		||||
gettextsrcdir = $(datadir)/gettext/po
 | 
			
		||||
 | 
			
		||||
INSTALL = @INSTALL@
 | 
			
		||||
INSTALL_DATA = @INSTALL_DATA@
 | 
			
		||||
 | 
			
		||||
# We use $(mkdir_p).
 | 
			
		||||
# In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as
 | 
			
		||||
# "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions,
 | 
			
		||||
# @install_sh@ does not start with $(SHELL), so we add it.
 | 
			
		||||
# In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined
 | 
			
		||||
# either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake
 | 
			
		||||
# versions, $(mkinstalldirs) and $(install_sh) are unused.
 | 
			
		||||
mkinstalldirs = $(SHELL) @install_sh@ -d
 | 
			
		||||
install_sh = $(SHELL) @install_sh@
 | 
			
		||||
MKDIR_P = @MKDIR_P@
 | 
			
		||||
mkdir_p = @mkdir_p@
 | 
			
		||||
 | 
			
		||||
GMSGFMT_ = @GMSGFMT@
 | 
			
		||||
GMSGFMT_no = @GMSGFMT@
 | 
			
		||||
GMSGFMT_yes = @GMSGFMT_015@
 | 
			
		||||
GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
 | 
			
		||||
MSGFMT_ = @MSGFMT@
 | 
			
		||||
MSGFMT_no = @MSGFMT@
 | 
			
		||||
MSGFMT_yes = @MSGFMT_015@
 | 
			
		||||
MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
 | 
			
		||||
XGETTEXT_ = @XGETTEXT@
 | 
			
		||||
XGETTEXT_no = @XGETTEXT@
 | 
			
		||||
XGETTEXT_yes = @XGETTEXT_015@
 | 
			
		||||
XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
 | 
			
		||||
MSGMERGE = msgmerge
 | 
			
		||||
MSGMERGE_UPDATE = @MSGMERGE@ --update
 | 
			
		||||
MSGINIT = msginit
 | 
			
		||||
MSGCONV = msgconv
 | 
			
		||||
MSGFILTER = msgfilter
 | 
			
		||||
 | 
			
		||||
POFILES = @POFILES@
 | 
			
		||||
GMOFILES = @GMOFILES@
 | 
			
		||||
UPDATEPOFILES = @UPDATEPOFILES@
 | 
			
		||||
DUMMYPOFILES = @DUMMYPOFILES@
 | 
			
		||||
DISTFILES.common = Makefile.in.in remove-potcdate.sin \
 | 
			
		||||
$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
 | 
			
		||||
DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \
 | 
			
		||||
$(POFILES) $(GMOFILES) \
 | 
			
		||||
$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)
 | 
			
		||||
 | 
			
		||||
POTFILES = \
 | 
			
		||||
 | 
			
		||||
CATALOGS = @CATALOGS@
 | 
			
		||||
 | 
			
		||||
# Makevars gets inserted here. (Don't remove this line!)
 | 
			
		||||
 | 
			
		||||
.SUFFIXES:
 | 
			
		||||
.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update
 | 
			
		||||
 | 
			
		||||
.po.mo:
 | 
			
		||||
	@echo "$(MSGFMT) -c -o $@ $<"; \
 | 
			
		||||
	$(MSGFMT) -c -o t-$@ $< && mv t-$@ $@
 | 
			
		||||
 | 
			
		||||
.po.gmo:
 | 
			
		||||
	@lang=`echo $* | sed -e 's,.*/,,'`; \
 | 
			
		||||
	test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
 | 
			
		||||
	echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \
 | 
			
		||||
	cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
 | 
			
		||||
 | 
			
		||||
.sin.sed:
 | 
			
		||||
	sed -e '/^#/d' $< > t-$@
 | 
			
		||||
	mv t-$@ $@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
all: check-macro-version all-@USE_NLS@
 | 
			
		||||
 | 
			
		||||
all-yes: stamp-po
 | 
			
		||||
all-no:
 | 
			
		||||
 | 
			
		||||
# Ensure that the gettext macros and this Makefile.in.in are in sync.
 | 
			
		||||
check-macro-version:
 | 
			
		||||
	@test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
 | 
			
		||||
	  || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \
 | 
			
		||||
	       exit 1; \
 | 
			
		||||
	     }
 | 
			
		||||
 | 
			
		||||
# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no
 | 
			
		||||
# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
 | 
			
		||||
# we don't want to bother translators with empty POT files). We assume that
 | 
			
		||||
# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
 | 
			
		||||
# In this case, stamp-po is a nop (i.e. a phony target).
 | 
			
		||||
 | 
			
		||||
# stamp-po is a timestamp denoting the last time at which the CATALOGS have
 | 
			
		||||
# been loosely updated. Its purpose is that when a developer or translator
 | 
			
		||||
# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
 | 
			
		||||
# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
 | 
			
		||||
# invocations of "make" will do nothing. This timestamp would not be necessary
 | 
			
		||||
# if updating the $(CATALOGS) would always touch them; however, the rule for
 | 
			
		||||
# $(POFILES) has been designed to not touch files that don't need to be
 | 
			
		||||
# changed.
 | 
			
		||||
stamp-po: $(srcdir)/$(DOMAIN).pot
 | 
			
		||||
	test ! -f $(srcdir)/$(DOMAIN).pot || \
 | 
			
		||||
	  test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
 | 
			
		||||
	@test ! -f $(srcdir)/$(DOMAIN).pot || { \
 | 
			
		||||
	  echo "touch stamp-po" && \
 | 
			
		||||
	  echo timestamp > stamp-poT && \
 | 
			
		||||
	  mv stamp-poT stamp-po; \
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
 | 
			
		||||
# otherwise packages like GCC can not be built if only parts of the source
 | 
			
		||||
# have been downloaded.
 | 
			
		||||
 | 
			
		||||
# This target rebuilds $(DOMAIN).pot; it is an expensive operation.
 | 
			
		||||
# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed.
 | 
			
		||||
$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed
 | 
			
		||||
	if LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null | grep -v 'libtool:' >/dev/null; then \
 | 
			
		||||
	  package_gnu='GNU '; \
 | 
			
		||||
	else \
 | 
			
		||||
	  package_gnu=''; \
 | 
			
		||||
	fi; \
 | 
			
		||||
	if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \
 | 
			
		||||
	  msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \
 | 
			
		||||
	else \
 | 
			
		||||
	  msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \
 | 
			
		||||
	fi; \
 | 
			
		||||
	case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
 | 
			
		||||
	  '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \
 | 
			
		||||
	    $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
 | 
			
		||||
	      --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \
 | 
			
		||||
	      --files-from=$(srcdir)/POTFILES.in \
 | 
			
		||||
	      --copyright-holder='$(COPYRIGHT_HOLDER)' \
 | 
			
		||||
	      --msgid-bugs-address="$$msgid_bugs_address" \
 | 
			
		||||
	    ;; \
 | 
			
		||||
	  *) \
 | 
			
		||||
	    $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
 | 
			
		||||
	      --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \
 | 
			
		||||
	      --files-from=$(srcdir)/POTFILES.in \
 | 
			
		||||
	      --copyright-holder='$(COPYRIGHT_HOLDER)' \
 | 
			
		||||
	      --package-name="$${package_gnu}@PACKAGE@" \
 | 
			
		||||
	      --package-version='@VERSION@' \
 | 
			
		||||
	      --msgid-bugs-address="$$msgid_bugs_address" \
 | 
			
		||||
	    ;; \
 | 
			
		||||
	esac
 | 
			
		||||
	test ! -f $(DOMAIN).po || { \
 | 
			
		||||
	  if test -f $(srcdir)/$(DOMAIN).pot; then \
 | 
			
		||||
	    sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \
 | 
			
		||||
	    sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \
 | 
			
		||||
	    if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \
 | 
			
		||||
	      rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \
 | 
			
		||||
	    else \
 | 
			
		||||
	      rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \
 | 
			
		||||
	      mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \
 | 
			
		||||
	    fi; \
 | 
			
		||||
	  else \
 | 
			
		||||
	    mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \
 | 
			
		||||
	  fi; \
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
 | 
			
		||||
# every "make" invocation, only create it when it is missing.
 | 
			
		||||
# Only "make $(DOMAIN).pot-update" or "make dist" will force an update.
 | 
			
		||||
$(srcdir)/$(DOMAIN).pot:
 | 
			
		||||
	$(MAKE) $(DOMAIN).pot-update
 | 
			
		||||
 | 
			
		||||
# This target rebuilds a PO file if $(DOMAIN).pot has changed.
 | 
			
		||||
# Note that a PO file is not touched if it doesn't need to be changed.
 | 
			
		||||
$(POFILES): $(srcdir)/$(DOMAIN).pot
 | 
			
		||||
	@lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
 | 
			
		||||
	if test -f "$(srcdir)/$${lang}.po"; then \
 | 
			
		||||
	  test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
 | 
			
		||||
	  echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \
 | 
			
		||||
	  cd $(srcdir) \
 | 
			
		||||
	    && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
 | 
			
		||||
	           '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
 | 
			
		||||
	             $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \
 | 
			
		||||
	           *) \
 | 
			
		||||
	             $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \
 | 
			
		||||
	         esac; \
 | 
			
		||||
	       }; \
 | 
			
		||||
	else \
 | 
			
		||||
	  $(MAKE) $${lang}.po-create; \
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
install: install-exec install-data
 | 
			
		||||
install-exec:
 | 
			
		||||
install-data: install-data-@USE_NLS@
 | 
			
		||||
	if test "$(PACKAGE)" = "gettext-tools"; then \
 | 
			
		||||
	  $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \
 | 
			
		||||
	  for file in $(DISTFILES.common) Makevars.template; do \
 | 
			
		||||
	    $(INSTALL_DATA) $(srcdir)/$$file \
 | 
			
		||||
			    $(DESTDIR)$(gettextsrcdir)/$$file; \
 | 
			
		||||
	  done; \
 | 
			
		||||
	  for file in Makevars; do \
 | 
			
		||||
	    rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
 | 
			
		||||
	  done; \
 | 
			
		||||
	else \
 | 
			
		||||
	  : ; \
 | 
			
		||||
	fi
 | 
			
		||||
install-data-no: all
 | 
			
		||||
install-data-yes: all
 | 
			
		||||
	@catalogs='$(CATALOGS)'; \
 | 
			
		||||
	for cat in $$catalogs; do \
 | 
			
		||||
	  cat=`basename $$cat`; \
 | 
			
		||||
	  lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
 | 
			
		||||
	  dir=$(localedir)/$$lang/LC_MESSAGES; \
 | 
			
		||||
	  $(mkdir_p) $(DESTDIR)$$dir; \
 | 
			
		||||
	  if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \
 | 
			
		||||
	  $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \
 | 
			
		||||
	  echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \
 | 
			
		||||
	  for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
 | 
			
		||||
	    if test -n "$$lc"; then \
 | 
			
		||||
	      if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
 | 
			
		||||
	        link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
 | 
			
		||||
	        mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
 | 
			
		||||
	        mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
 | 
			
		||||
	        (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
 | 
			
		||||
	         for file in *; do \
 | 
			
		||||
	           if test -f $$file; then \
 | 
			
		||||
	             ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
 | 
			
		||||
	           fi; \
 | 
			
		||||
	         done); \
 | 
			
		||||
	        rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
 | 
			
		||||
	      else \
 | 
			
		||||
	        if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
 | 
			
		||||
	          :; \
 | 
			
		||||
	        else \
 | 
			
		||||
	          rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
 | 
			
		||||
	          mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
 | 
			
		||||
	        fi; \
 | 
			
		||||
	      fi; \
 | 
			
		||||
	      rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
 | 
			
		||||
	      ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
 | 
			
		||||
	      ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
 | 
			
		||||
	      cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
 | 
			
		||||
	      echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \
 | 
			
		||||
	    fi; \
 | 
			
		||||
	  done; \
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
install-strip: install
 | 
			
		||||
 | 
			
		||||
installdirs: installdirs-exec installdirs-data
 | 
			
		||||
installdirs-exec:
 | 
			
		||||
installdirs-data: installdirs-data-@USE_NLS@
 | 
			
		||||
	if test "$(PACKAGE)" = "gettext-tools"; then \
 | 
			
		||||
	  $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \
 | 
			
		||||
	else \
 | 
			
		||||
	  : ; \
 | 
			
		||||
	fi
 | 
			
		||||
installdirs-data-no:
 | 
			
		||||
installdirs-data-yes:
 | 
			
		||||
	@catalogs='$(CATALOGS)'; \
 | 
			
		||||
	for cat in $$catalogs; do \
 | 
			
		||||
	  cat=`basename $$cat`; \
 | 
			
		||||
	  lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
 | 
			
		||||
	  dir=$(localedir)/$$lang/LC_MESSAGES; \
 | 
			
		||||
	  $(mkdir_p) $(DESTDIR)$$dir; \
 | 
			
		||||
	  for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
 | 
			
		||||
	    if test -n "$$lc"; then \
 | 
			
		||||
	      if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
 | 
			
		||||
	        link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
 | 
			
		||||
	        mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
 | 
			
		||||
	        mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
 | 
			
		||||
	        (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
 | 
			
		||||
	         for file in *; do \
 | 
			
		||||
	           if test -f $$file; then \
 | 
			
		||||
	             ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
 | 
			
		||||
	           fi; \
 | 
			
		||||
	         done); \
 | 
			
		||||
	        rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
 | 
			
		||||
	      else \
 | 
			
		||||
	        if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
 | 
			
		||||
	          :; \
 | 
			
		||||
	        else \
 | 
			
		||||
	          rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
 | 
			
		||||
	          mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
 | 
			
		||||
	        fi; \
 | 
			
		||||
	      fi; \
 | 
			
		||||
	    fi; \
 | 
			
		||||
	  done; \
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
# Define this as empty until I found a useful application.
 | 
			
		||||
installcheck:
 | 
			
		||||
 | 
			
		||||
uninstall: uninstall-exec uninstall-data
 | 
			
		||||
uninstall-exec:
 | 
			
		||||
uninstall-data: uninstall-data-@USE_NLS@
 | 
			
		||||
	if test "$(PACKAGE)" = "gettext-tools"; then \
 | 
			
		||||
	  for file in $(DISTFILES.common) Makevars.template; do \
 | 
			
		||||
	    rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
 | 
			
		||||
	  done; \
 | 
			
		||||
	else \
 | 
			
		||||
	  : ; \
 | 
			
		||||
	fi
 | 
			
		||||
uninstall-data-no:
 | 
			
		||||
uninstall-data-yes:
 | 
			
		||||
	catalogs='$(CATALOGS)'; \
 | 
			
		||||
	for cat in $$catalogs; do \
 | 
			
		||||
	  cat=`basename $$cat`; \
 | 
			
		||||
	  lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
 | 
			
		||||
	  for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \
 | 
			
		||||
	    rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
 | 
			
		||||
	  done; \
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
check: all
 | 
			
		||||
 | 
			
		||||
info dvi ps pdf html tags TAGS ctags CTAGS ID:
 | 
			
		||||
 | 
			
		||||
mostlyclean:
 | 
			
		||||
	rm -f remove-potcdate.sed
 | 
			
		||||
	rm -f stamp-poT
 | 
			
		||||
	rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
 | 
			
		||||
	rm -fr *.o
 | 
			
		||||
 | 
			
		||||
clean: mostlyclean
 | 
			
		||||
 | 
			
		||||
distclean: clean
 | 
			
		||||
	rm -f Makefile Makefile.in POTFILES *.mo
 | 
			
		||||
 | 
			
		||||
maintainer-clean: distclean
 | 
			
		||||
	@echo "This command is intended for maintainers to use;"
 | 
			
		||||
	@echo "it deletes files that may require special tools to rebuild."
 | 
			
		||||
	rm -f stamp-po $(GMOFILES)
 | 
			
		||||
 | 
			
		||||
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 | 
			
		||||
dist distdir:
 | 
			
		||||
	$(MAKE) update-po
 | 
			
		||||
	@$(MAKE) dist2
 | 
			
		||||
# This is a separate target because 'update-po' must be executed before.
 | 
			
		||||
dist2: stamp-po $(DISTFILES)
 | 
			
		||||
	dists="$(DISTFILES)"; \
 | 
			
		||||
	if test "$(PACKAGE)" = "gettext-tools"; then \
 | 
			
		||||
	  dists="$$dists Makevars.template"; \
 | 
			
		||||
	fi; \
 | 
			
		||||
	if test -f $(srcdir)/$(DOMAIN).pot; then \
 | 
			
		||||
	  dists="$$dists $(DOMAIN).pot stamp-po"; \
 | 
			
		||||
	fi; \
 | 
			
		||||
	if test -f $(srcdir)/ChangeLog; then \
 | 
			
		||||
	  dists="$$dists ChangeLog"; \
 | 
			
		||||
	fi; \
 | 
			
		||||
	for i in 0 1 2 3 4 5 6 7 8 9; do \
 | 
			
		||||
	  if test -f $(srcdir)/ChangeLog.$$i; then \
 | 
			
		||||
	    dists="$$dists ChangeLog.$$i"; \
 | 
			
		||||
	  fi; \
 | 
			
		||||
	done; \
 | 
			
		||||
	if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \
 | 
			
		||||
	for file in $$dists; do \
 | 
			
		||||
	  if test -f $$file; then \
 | 
			
		||||
	    cp -p $$file $(distdir) || exit 1; \
 | 
			
		||||
	  else \
 | 
			
		||||
	    cp -p $(srcdir)/$$file $(distdir) || exit 1; \
 | 
			
		||||
	  fi; \
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
update-po: Makefile
 | 
			
		||||
	$(MAKE) $(DOMAIN).pot-update
 | 
			
		||||
	test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES)
 | 
			
		||||
	$(MAKE) update-gmo
 | 
			
		||||
 | 
			
		||||
# General rule for creating PO files.
 | 
			
		||||
 | 
			
		||||
.nop.po-create:
 | 
			
		||||
	@lang=`echo $@ | sed -e 's/\.po-create$$//'`; \
 | 
			
		||||
	echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \
 | 
			
		||||
	exit 1
 | 
			
		||||
 | 
			
		||||
# General rule for updating PO files.
 | 
			
		||||
 | 
			
		||||
.nop.po-update:
 | 
			
		||||
	@lang=`echo $@ | sed -e 's/\.po-update$$//'`; \
 | 
			
		||||
	if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \
 | 
			
		||||
	tmpdir=`pwd`; \
 | 
			
		||||
	echo "$$lang:"; \
 | 
			
		||||
	test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
 | 
			
		||||
	echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \
 | 
			
		||||
	cd $(srcdir); \
 | 
			
		||||
	if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
 | 
			
		||||
	       '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
 | 
			
		||||
	         $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
 | 
			
		||||
	       *) \
 | 
			
		||||
	         $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
 | 
			
		||||
	     esac; \
 | 
			
		||||
	   }; then \
 | 
			
		||||
	  if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
 | 
			
		||||
	    rm -f $$tmpdir/$$lang.new.po; \
 | 
			
		||||
	  else \
 | 
			
		||||
	    if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
 | 
			
		||||
	      :; \
 | 
			
		||||
	    else \
 | 
			
		||||
	      echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
 | 
			
		||||
	      exit 1; \
 | 
			
		||||
	    fi; \
 | 
			
		||||
	  fi; \
 | 
			
		||||
	else \
 | 
			
		||||
	  echo "msgmerge for $$lang.po failed!" 1>&2; \
 | 
			
		||||
	  rm -f $$tmpdir/$$lang.new.po; \
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
$(DUMMYPOFILES):
 | 
			
		||||
 | 
			
		||||
update-gmo: Makefile $(GMOFILES)
 | 
			
		||||
	@:
 | 
			
		||||
 | 
			
		||||
# Recreate Makefile by invoking config.status. Explicitly invoke the shell,
 | 
			
		||||
# because execution permission bits may not work on the current file system.
 | 
			
		||||
# Use @SHELL@, which is the shell determined by autoconf for the use by its
 | 
			
		||||
# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient.
 | 
			
		||||
Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
 | 
			
		||||
	cd $(top_builddir) \
 | 
			
		||||
	  && @SHELL@ ./config.status $(subdir)/$@.in po-directories
 | 
			
		||||
 | 
			
		||||
force:
 | 
			
		||||
 | 
			
		||||
# Tell versions [3.59,3.63) of GNU make not to export all variables.
 | 
			
		||||
# Otherwise a system limit (for SysV at least) may be exceeded.
 | 
			
		||||
.NOEXPORT:
 | 
			
		||||
							
								
								
									
										41
									
								
								po/Makevars
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								po/Makevars
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
# Makefile variables for PO directory in any package using GNU gettext.
 | 
			
		||||
 | 
			
		||||
# Usually the message domain is the same as the package name.
 | 
			
		||||
DOMAIN = $(PACKAGE)
 | 
			
		||||
 | 
			
		||||
# These two variables depend on the location of this directory.
 | 
			
		||||
subdir = po
 | 
			
		||||
top_builddir = ..
 | 
			
		||||
 | 
			
		||||
# These options get passed to xgettext.
 | 
			
		||||
XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
 | 
			
		||||
 | 
			
		||||
# This is the copyright holder that gets inserted into the header of the
 | 
			
		||||
# $(DOMAIN).pot file.  Set this to the copyright holder of the surrounding
 | 
			
		||||
# package.  (Note that the msgstr strings, extracted from the package's
 | 
			
		||||
# sources, belong to the copyright holder of the package.)  Translators are
 | 
			
		||||
# expected to transfer the copyright for their translations to this person
 | 
			
		||||
# or entity, or to disclaim their copyright.  The empty string stands for
 | 
			
		||||
# the public domain; in this case the translators are expected to disclaim
 | 
			
		||||
# their copyright.
 | 
			
		||||
COPYRIGHT_HOLDER = Free Software Foundation, Inc.
 | 
			
		||||
 | 
			
		||||
# This is the email address or URL to which the translators shall report
 | 
			
		||||
# bugs in the untranslated strings:
 | 
			
		||||
# - Strings which are not entire sentences, see the maintainer guidelines
 | 
			
		||||
#   in the GNU gettext documentation, section 'Preparing Strings'.
 | 
			
		||||
# - Strings which use unclear terms or require additional context to be
 | 
			
		||||
#   understood.
 | 
			
		||||
# - Strings which make invalid assumptions about notation of date, time or
 | 
			
		||||
#   money.
 | 
			
		||||
# - Pluralisation problems.
 | 
			
		||||
# - Incorrect English spelling.
 | 
			
		||||
# - Incorrect formatting.
 | 
			
		||||
# It can be your email address, or a mailing list address where translators
 | 
			
		||||
# can write to without being subscribed, or the URL of a web page through
 | 
			
		||||
# which the translators can contact you.
 | 
			
		||||
MSGID_BUGS_ADDRESS =
 | 
			
		||||
 | 
			
		||||
# This is the list of locale categories, beyond LC_MESSAGES, for which the
 | 
			
		||||
# message catalogs shall be used.  It is usually empty.
 | 
			
		||||
EXTRA_LOCALE_CATEGORIES =
 | 
			
		||||
							
								
								
									
										2
									
								
								po/POTFILES.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								po/POTFILES.in
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
# List of source files which contain translatable strings.
 | 
			
		||||
src/ext/gnunet-ext.c
 | 
			
		||||
							
								
								
									
										47
									
								
								po/Rules-quot
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								po/Rules-quot
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
			
		||||
# Special Makefile rules for English message catalogs with quotation marks.
 | 
			
		||||
 | 
			
		||||
DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot
 | 
			
		||||
 | 
			
		||||
.SUFFIXES: .insert-header .po-update-en
 | 
			
		||||
 | 
			
		||||
en@quot.po-create:
 | 
			
		||||
	$(MAKE) en@quot.po-update
 | 
			
		||||
en@boldquot.po-create:
 | 
			
		||||
	$(MAKE) en@boldquot.po-update
 | 
			
		||||
 | 
			
		||||
en@quot.po-update: en@quot.po-update-en
 | 
			
		||||
en@boldquot.po-update: en@boldquot.po-update-en
 | 
			
		||||
 | 
			
		||||
.insert-header.po-update-en:
 | 
			
		||||
	@lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \
 | 
			
		||||
	if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \
 | 
			
		||||
	tmpdir=`pwd`; \
 | 
			
		||||
	echo "$$lang:"; \
 | 
			
		||||
	ll=`echo $$lang | sed -e 's/@.*//'`; \
 | 
			
		||||
	LC_ALL=C; export LC_ALL; \
 | 
			
		||||
	cd $(srcdir); \
 | 
			
		||||
	if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$lang -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \
 | 
			
		||||
	  if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
 | 
			
		||||
	    rm -f $$tmpdir/$$lang.new.po; \
 | 
			
		||||
	  else \
 | 
			
		||||
	    if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
 | 
			
		||||
	      :; \
 | 
			
		||||
	    else \
 | 
			
		||||
	      echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
 | 
			
		||||
	      exit 1; \
 | 
			
		||||
	    fi; \
 | 
			
		||||
	  fi; \
 | 
			
		||||
	else \
 | 
			
		||||
	  echo "creation of $$lang.po failed!" 1>&2; \
 | 
			
		||||
	  rm -f $$tmpdir/$$lang.new.po; \
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
en@quot.insert-header: insert-header.sin
 | 
			
		||||
	sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header
 | 
			
		||||
 | 
			
		||||
en@boldquot.insert-header: insert-header.sin
 | 
			
		||||
	sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header
 | 
			
		||||
 | 
			
		||||
mostlyclean: mostlyclean-quot
 | 
			
		||||
mostlyclean-quot:
 | 
			
		||||
	rm -f *.insert-header
 | 
			
		||||
							
								
								
									
										10
									
								
								po/boldquot.sed
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								po/boldquot.sed
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
s/"\([^"]*\)"/“\1”/g
 | 
			
		||||
s/`\([^`']*\)'/‘\1’/g
 | 
			
		||||
s/ '\([^`']*\)' / ‘\1’ /g
 | 
			
		||||
s/ '\([^`']*\)'$/ ‘\1’/g
 | 
			
		||||
s/^'\([^`']*\)' /‘\1’ /g
 | 
			
		||||
s/“”/""/g
 | 
			
		||||
s/“/“[1m/g
 | 
			
		||||
s/”/[0m”/g
 | 
			
		||||
s/‘/‘[1m/g
 | 
			
		||||
s/’/[0m’/g
 | 
			
		||||
							
								
								
									
										25
									
								
								po/en@boldquot.header
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								po/en@boldquot.header
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,25 @@
 | 
			
		||||
# All this catalog "translates" are quotation characters.
 | 
			
		||||
# The msgids must be ASCII and therefore cannot contain real quotation
 | 
			
		||||
# characters, only substitutes like grave accent (0x60), apostrophe (0x27)
 | 
			
		||||
# and double quote (0x22). These substitutes look strange; see
 | 
			
		||||
# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html
 | 
			
		||||
#
 | 
			
		||||
# This catalog translates grave accent (0x60) and apostrophe (0x27) to
 | 
			
		||||
# left single quotation mark (U+2018) and right single quotation mark (U+2019).
 | 
			
		||||
# It also translates pairs of apostrophe (0x27) to
 | 
			
		||||
# left single quotation mark (U+2018) and right single quotation mark (U+2019)
 | 
			
		||||
# and pairs of quotation mark (0x22) to
 | 
			
		||||
# left double quotation mark (U+201C) and right double quotation mark (U+201D).
 | 
			
		||||
#
 | 
			
		||||
# When output to an UTF-8 terminal, the quotation characters appear perfectly.
 | 
			
		||||
# When output to an ISO-8859-1 terminal, the single quotation marks are
 | 
			
		||||
# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to
 | 
			
		||||
# grave/acute accent (by libiconv), and the double quotation marks are
 | 
			
		||||
# transliterated to 0x22.
 | 
			
		||||
# When output to an ASCII terminal, the single quotation marks are
 | 
			
		||||
# transliterated to apostrophes, and the double quotation marks are
 | 
			
		||||
# transliterated to 0x22.
 | 
			
		||||
#
 | 
			
		||||
# This catalog furthermore displays the text between the quotation marks in
 | 
			
		||||
# bold face, assuming the VT100/XTerm escape sequences.
 | 
			
		||||
#
 | 
			
		||||
							
								
								
									
										22
									
								
								po/en@quot.header
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								po/en@quot.header
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
# All this catalog "translates" are quotation characters.
 | 
			
		||||
# The msgids must be ASCII and therefore cannot contain real quotation
 | 
			
		||||
# characters, only substitutes like grave accent (0x60), apostrophe (0x27)
 | 
			
		||||
# and double quote (0x22). These substitutes look strange; see
 | 
			
		||||
# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html
 | 
			
		||||
#
 | 
			
		||||
# This catalog translates grave accent (0x60) and apostrophe (0x27) to
 | 
			
		||||
# left single quotation mark (U+2018) and right single quotation mark (U+2019).
 | 
			
		||||
# It also translates pairs of apostrophe (0x27) to
 | 
			
		||||
# left single quotation mark (U+2018) and right single quotation mark (U+2019)
 | 
			
		||||
# and pairs of quotation mark (0x22) to
 | 
			
		||||
# left double quotation mark (U+201C) and right double quotation mark (U+201D).
 | 
			
		||||
#
 | 
			
		||||
# When output to an UTF-8 terminal, the quotation characters appear perfectly.
 | 
			
		||||
# When output to an ISO-8859-1 terminal, the single quotation marks are
 | 
			
		||||
# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to
 | 
			
		||||
# grave/acute accent (by libiconv), and the double quotation marks are
 | 
			
		||||
# transliterated to 0x22.
 | 
			
		||||
# When output to an ASCII terminal, the single quotation marks are
 | 
			
		||||
# transliterated to apostrophes, and the double quotation marks are
 | 
			
		||||
# transliterated to 0x22.
 | 
			
		||||
#
 | 
			
		||||
							
								
								
									
										23
									
								
								po/insert-header.sin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								po/insert-header.sin
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
# Sed script that inserts the file called HEADER before the header entry.
 | 
			
		||||
#
 | 
			
		||||
# At each occurrence of a line starting with "msgid ", we execute the following
 | 
			
		||||
# commands. At the first occurrence, insert the file. At the following
 | 
			
		||||
# occurrences, do nothing. The distinction between the first and the following
 | 
			
		||||
# occurrences is achieved by looking at the hold space.
 | 
			
		||||
/^msgid /{
 | 
			
		||||
x
 | 
			
		||||
# Test if the hold space is empty.
 | 
			
		||||
s/m/m/
 | 
			
		||||
ta
 | 
			
		||||
# Yes it was empty. First occurrence. Read the file.
 | 
			
		||||
r HEADER
 | 
			
		||||
# Output the file's contents by reading the next line. But don't lose the
 | 
			
		||||
# current line while doing this.
 | 
			
		||||
g
 | 
			
		||||
N
 | 
			
		||||
bb
 | 
			
		||||
:a
 | 
			
		||||
# The hold space was nonempty. Following occurrences. Do nothing.
 | 
			
		||||
x
 | 
			
		||||
:b
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								po/quot.sed
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								po/quot.sed
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
s/"\([^"]*\)"/“\1”/g
 | 
			
		||||
s/`\([^`']*\)'/‘\1’/g
 | 
			
		||||
s/ '\([^`']*\)' / ‘\1’ /g
 | 
			
		||||
s/ '\([^`']*\)'$/ ‘\1’/g
 | 
			
		||||
s/^'\([^`']*\)' /‘\1’ /g
 | 
			
		||||
s/“”/""/g
 | 
			
		||||
							
								
								
									
										19
									
								
								po/remove-potcdate.sin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								po/remove-potcdate.sin
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
			
		||||
# Sed script that remove the POT-Creation-Date line in the header entry
 | 
			
		||||
# from a POT file.
 | 
			
		||||
#
 | 
			
		||||
# The distinction between the first and the following occurrences of the
 | 
			
		||||
# pattern is achieved by looking at the hold space.
 | 
			
		||||
/^"POT-Creation-Date: .*"$/{
 | 
			
		||||
x
 | 
			
		||||
# Test if the hold space is empty.
 | 
			
		||||
s/P/P/
 | 
			
		||||
ta
 | 
			
		||||
# Yes it was empty. First occurrence. Remove the line.
 | 
			
		||||
g
 | 
			
		||||
d
 | 
			
		||||
bb
 | 
			
		||||
:a
 | 
			
		||||
# The hold space was nonempty. Following occurrences. Do nothing.
 | 
			
		||||
x
 | 
			
		||||
:b
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2
									
								
								src/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
							
								
								
									
										7
									
								
								src/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
# This Makefile.am is in the public domain
 | 
			
		||||
SUBDIRS = include \
 | 
			
		||||
  multicast \
 | 
			
		||||
  psycutil \
 | 
			
		||||
  psycstore \
 | 
			
		||||
  psyc \
 | 
			
		||||
  social
 | 
			
		||||
							
								
								
									
										2
									
								
								src/include/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/include/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
							
								
								
									
										15
									
								
								src/include/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/include/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
# This Makefile.am is in the public domain
 | 
			
		||||
SUBDIRS = .
 | 
			
		||||
 | 
			
		||||
gnunetincludedir = $(includedir)/gnunet
 | 
			
		||||
 | 
			
		||||
gnunetinclude_HEADERS = \
 | 
			
		||||
  gnunet_multicast_service.h \
 | 
			
		||||
  gnunet_psycstore_plugin.h \
 | 
			
		||||
  gnunet_psycstore_service.h \
 | 
			
		||||
  gnunet_psyc_service.h \
 | 
			
		||||
  gnunet_psyc_util_lib.h \
 | 
			
		||||
  gnunet_psyc_env.h \
 | 
			
		||||
  gnunet_psyc_message.h \
 | 
			
		||||
  gnunet_psyc_slicer.h \
 | 
			
		||||
  gnunet_social_service.h
 | 
			
		||||
							
								
								
									
										925
									
								
								src/include/gnunet_multicast_service.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										925
									
								
								src/include/gnunet_multicast_service.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,925 @@
 | 
			
		||||
/*
 | 
			
		||||
     This file is part of GNUnet.
 | 
			
		||||
     Copyright (C) 2012, 2013 GNUnet e.V.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 * @author Christian Grothoff
 | 
			
		||||
 *
 | 
			
		||||
 * @file
 | 
			
		||||
 * Multicast service; multicast messaging via CADET
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup multicast  Multicast service
 | 
			
		||||
 * Multicast messaging via CADET.
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef GNUNET_MULTICAST_SERVICE_H
 | 
			
		||||
#define GNUNET_MULTICAST_SERVICE_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C"
 | 
			
		||||
{
 | 
			
		||||
#if 0                           /* keep Emacsens' auto-indent happy */
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
#include "gnunet_transport_service.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Version number of GNUnet-multicast API.
 | 
			
		||||
 */
 | 
			
		||||
#define GNUNET_MULTICAST_VERSION 0x00000000
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Opaque handle for a multicast group member.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_Member;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle for the origin of a multicast group.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_Origin;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
enum GNUNET_MULTICAST_MessageFlags
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * First fragment of a message.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_MULTICAST_MESSAGE_FIRST_FRAGMENT = 1 << 0,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Last fragment of a message.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT = 1 << 1,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * OR'ed flags if message is not fragmented.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_MULTICAST_MESSAGE_NOT_FRAGMENTED
 | 
			
		||||
    = GNUNET_MULTICAST_MESSAGE_FIRST_FRAGMENT
 | 
			
		||||
  | GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Historic message, used only locally when replaying messages from local
 | 
			
		||||
   * storage.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_MULTICAST_MESSAGE_HISTORIC = 1 << 30
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GNUNET_NETWORK_STRUCT_BEGIN
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Header of a multicast message fragment.
 | 
			
		||||
 *
 | 
			
		||||
 * This format is public as the replay mechanism must replay message fragments using the
 | 
			
		||||
 * same format.  This is needed as we want to integrity-check message fragments within
 | 
			
		||||
 * the multicast layer to avoid multicasting mal-formed messages.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_MessageHeader
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Header for all multicast message fragments from the origin.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Number of hops this message fragment has taken since the origin.
 | 
			
		||||
   *
 | 
			
		||||
   * Helpful to determine shortest paths to the origin among honest peers for
 | 
			
		||||
   * unicast requests from members.  Updated at each hop and thus not signed and
 | 
			
		||||
   * not secure.
 | 
			
		||||
   */
 | 
			
		||||
  uint32_t hop_counter GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ECC signature of the message fragment.
 | 
			
		||||
   *
 | 
			
		||||
   * Signature must match the public key of the multicast group.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaSignature signature;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Purpose for the signature and size of the signed data.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Number of the message fragment, monotonically increasing starting from 1.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t fragment_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Byte offset of this @e fragment of the @e message.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t fragment_offset GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Number of the message this fragment belongs to.
 | 
			
		||||
   *
 | 
			
		||||
   * Set in GNUNET_MULTICAST_origin_to_all().
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t message_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Counter that monotonically increases whenever a member parts the group.
 | 
			
		||||
   *
 | 
			
		||||
   * Set in GNUNET_MULTICAST_origin_to_all().
 | 
			
		||||
   *
 | 
			
		||||
   * It has significance in case of replay requests: when a member has missed
 | 
			
		||||
   * messages and gets a replay request: in this case if the @a group_generation
 | 
			
		||||
   * is still the same before and after the missed messages, it means that no
 | 
			
		||||
   * @e join or @e part operations happened during the missed messages.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t group_generation GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Flags for this message fragment.
 | 
			
		||||
   *
 | 
			
		||||
   * @see enum GNUNET_MULTICAST_MessageFlags
 | 
			
		||||
   */
 | 
			
		||||
  uint32_t flags GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /* Followed by message body. */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Header of a request from a member to the origin.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_RequestHeader
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Header for all requests from a member to the origin.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Public key of the sending member.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaPublicKey member_pub_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ECC signature of the request fragment.
 | 
			
		||||
   *
 | 
			
		||||
   * Signature must match the public key of the multicast group.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaSignature signature;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Purpose for the signature and size of the signed data.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Number of the request fragment.
 | 
			
		||||
   * Monotonically increasing from 1.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t fragment_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Byte offset of this @e fragment of the @e request.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t fragment_offset GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Number of the request this fragment belongs to.
 | 
			
		||||
   *
 | 
			
		||||
   * Set in GNUNET_MULTICAST_origin_to_all().
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t request_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Flags for this request.
 | 
			
		||||
   */
 | 
			
		||||
  enum GNUNET_MULTICAST_MessageFlags flags GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /* Followed by request body. */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GNUNET_NETWORK_STRUCT_END
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Maximum size of a multicast message fragment.
 | 
			
		||||
 */
 | 
			
		||||
#define GNUNET_MULTICAST_FRAGMENT_MAX_SIZE (63 * 1024)
 | 
			
		||||
 | 
			
		||||
#define GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD           \
 | 
			
		||||
  (GNUNET_MULTICAST_FRAGMENT_MAX_SIZE                   \
 | 
			
		||||
   - sizeof (struct GNUNET_MULTICAST_MessageHeader))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle that identifies a join request.
 | 
			
		||||
 *
 | 
			
		||||
 * Used to match calls to #GNUNET_MULTICAST_JoinRequestCallback to the
 | 
			
		||||
 * corresponding calls to #GNUNET_MULTICAST_join_decision().
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_JoinHandle;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function to call with the decision made for a join request.
 | 
			
		||||
 *
 | 
			
		||||
 * Must be called once and only once in response to an invocation of the
 | 
			
		||||
 * #GNUNET_MULTICAST_JoinRequestCallback.
 | 
			
		||||
 *
 | 
			
		||||
 * @param jh
 | 
			
		||||
 *        Join request handle.
 | 
			
		||||
 * @param is_admitted
 | 
			
		||||
 *        #GNUNET_YES    if the join is approved,
 | 
			
		||||
 *        #GNUNET_NO     if it is disapproved,
 | 
			
		||||
 *        #GNUNET_SYSERR if we cannot answer the request.
 | 
			
		||||
 * @param relay_count
 | 
			
		||||
 *        Number of relays given.
 | 
			
		||||
 * @param relays
 | 
			
		||||
 *        Array of suggested peers that might be useful relays to use
 | 
			
		||||
 *        when joining the multicast group (essentially a list of peers that
 | 
			
		||||
 *        are already part of the multicast group and might thus be willing
 | 
			
		||||
 *        to help with routing).  If empty, only this local peer (which must
 | 
			
		||||
 *        be the multicast origin) is a good candidate for building the
 | 
			
		||||
 *        multicast tree.  Note that it is unnecessary to specify our own
 | 
			
		||||
 *        peer identity in this array.
 | 
			
		||||
 * @param join_resp
 | 
			
		||||
 *        Message to send in response to the joining peer;
 | 
			
		||||
 *        can also be used to redirect the peer to a different group at the
 | 
			
		||||
 *        application layer; this response is to be transmitted to the
 | 
			
		||||
 *        peer that issued the request even if admission is denied.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_ReplayHandle *
 | 
			
		||||
GNUNET_MULTICAST_join_decision (struct GNUNET_MULTICAST_JoinHandle *jh,
 | 
			
		||||
                                int is_admitted,
 | 
			
		||||
                                uint16_t relay_count,
 | 
			
		||||
                                const struct GNUNET_PeerIdentity *relays,
 | 
			
		||||
                                const struct GNUNET_MessageHeader *join_resp);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Method called whenever another peer wants to join the multicast group.
 | 
			
		||||
 *
 | 
			
		||||
 * Implementations of this function must call GNUNET_MULTICAST_join_decision()
 | 
			
		||||
 * with the decision.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure.
 | 
			
		||||
 * @param member_pub_key
 | 
			
		||||
 *        Public key of the member requesting join.
 | 
			
		||||
 * @param join_msg
 | 
			
		||||
 *        Application-dependent join message from the new member.
 | 
			
		||||
 * @param jh
 | 
			
		||||
 *        Join handle to pass to GNUNET_MULTICAST_join_decison().
 | 
			
		||||
 */
 | 
			
		||||
typedef void
 | 
			
		||||
(*GNUNET_MULTICAST_JoinRequestCallback) (void *cls,
 | 
			
		||||
                                         const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
 | 
			
		||||
                                         const struct GNUNET_MessageHeader *join_msg,
 | 
			
		||||
                                         struct GNUNET_MULTICAST_JoinHandle *jh);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Method called to inform about the decision in response to a join request.
 | 
			
		||||
 *
 | 
			
		||||
 * If @a is_admitted is not #GNUNET_YES, then the multicast service disconnects
 | 
			
		||||
 * the client and the multicast member handle returned by
 | 
			
		||||
 * GNUNET_MULTICAST_member_join() is invalidated.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *         Closure.
 | 
			
		||||
 * @param is_admitted
 | 
			
		||||
 *         #GNUNET_YES or #GNUNET_NO or #GNUNET_SYSERR
 | 
			
		||||
 * @param peer
 | 
			
		||||
 *        The peer we are connected to and the join decision is from.
 | 
			
		||||
 * @param relay_count
 | 
			
		||||
 *        Number of peers in the @a relays array.
 | 
			
		||||
 * @param relays
 | 
			
		||||
 *        Peer identities of members of the group, which serve as relays
 | 
			
		||||
 *        and can be used to join the group at.  If empty, only the origin can
 | 
			
		||||
 *        be used to connect to the group.
 | 
			
		||||
 * @param join_msg
 | 
			
		||||
 *        Application-dependent join message from the origin.
 | 
			
		||||
 */
 | 
			
		||||
typedef void
 | 
			
		||||
(*GNUNET_MULTICAST_JoinDecisionCallback) (void *cls,
 | 
			
		||||
                                          int is_admitted,
 | 
			
		||||
                                          const struct GNUNET_PeerIdentity *peer,
 | 
			
		||||
                                          uint16_t relay_count,
 | 
			
		||||
                                          const struct GNUNET_PeerIdentity *relays,
 | 
			
		||||
                                          const struct GNUNET_MessageHeader *join_msg);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function called whenever a group member has transmitted a request
 | 
			
		||||
 * to the origin (other than joining or leaving).
 | 
			
		||||
 *
 | 
			
		||||
 * FIXME: need to distinguish between origin cancelling a message (some fragments
 | 
			
		||||
 * were sent, then the rest 'discarded') and the case where we got disconnected;
 | 
			
		||||
 * right now, both would mean 'msg' is NULL, but they could be quite different...
 | 
			
		||||
 * So the semantics from the receiver side of
 | 
			
		||||
 * GNUNET_MULTICAST_member_to_origin_cancel() are not clear here.   Maybe we
 | 
			
		||||
 * should do something with the flags in this case?
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure (set from GNUNET_MULTICAST_origin_start).
 | 
			
		||||
 * @param sender
 | 
			
		||||
 *        Identity of the sender.
 | 
			
		||||
 * @param req
 | 
			
		||||
 *        Request to the origin.
 | 
			
		||||
 * @param flags
 | 
			
		||||
 *        Flags for the request.
 | 
			
		||||
 */
 | 
			
		||||
typedef void
 | 
			
		||||
(*GNUNET_MULTICAST_RequestCallback) (void *cls,
 | 
			
		||||
                                     const struct GNUNET_MULTICAST_RequestHeader *req);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function called whenever a group member is receiving a message fragment from
 | 
			
		||||
 * the origin.
 | 
			
		||||
 *
 | 
			
		||||
 * If admission to the group is denied, this function is called once with the
 | 
			
		||||
 * response of the @e origin (as given to GNUNET_MULTICAST_join_decision()) and
 | 
			
		||||
 * then a second time with NULL to indicate that the connection failed for good.
 | 
			
		||||
 *
 | 
			
		||||
 * FIXME: need to distinguish between origin cancelling a message (some fragments
 | 
			
		||||
 * were sent, then the rest 'discarded') and the case where we got disconnected;
 | 
			
		||||
 * right now, both would mean 'msg' is NULL, but they could be quite different...
 | 
			
		||||
 * So the semantics from the receiver side of
 | 
			
		||||
 * GNUNET_MULTICAST_origin_to_all_cancel() are not clear here.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure (set from GNUNET_MULTICAST_member_join())
 | 
			
		||||
 * @param msg
 | 
			
		||||
 *        Message from the origin, NULL if the origin shut down
 | 
			
		||||
 *        (or we were kicked out, and we should thus call
 | 
			
		||||
 *        GNUNET_MULTICAST_member_part() next)
 | 
			
		||||
 */
 | 
			
		||||
typedef void
 | 
			
		||||
(*GNUNET_MULTICAST_MessageCallback) (void *cls,
 | 
			
		||||
                                     const struct GNUNET_MULTICAST_MessageHeader *msg);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Opaque handle to a replay request from the multicast service.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_ReplayHandle;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Functions with this signature are called whenever the multicast service needs
 | 
			
		||||
 * a message fragment to be replayed by fragment_id.
 | 
			
		||||
 *
 | 
			
		||||
 * Implementations of this function MUST call GNUNET_MULTICAST_replay() ONCE
 | 
			
		||||
 * (with a message or an error); however, if the origin is destroyed or the
 | 
			
		||||
 * group is left, the replay handle must no longer be used.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure (set from GNUNET_MULTICAST_origin_start()
 | 
			
		||||
 *        or GNUNET_MULTICAST_member_join()).
 | 
			
		||||
 * @param member_pub_key
 | 
			
		||||
 *        The member requesting replay.
 | 
			
		||||
 * @param fragment_id
 | 
			
		||||
 *        Which message fragment should be replayed.
 | 
			
		||||
 * @param flags
 | 
			
		||||
 *        Flags for the replay.
 | 
			
		||||
 * @param rh
 | 
			
		||||
 *        Handle to pass to message transmit function.
 | 
			
		||||
 */
 | 
			
		||||
typedef void
 | 
			
		||||
(*GNUNET_MULTICAST_ReplayFragmentCallback) (void *cls,
 | 
			
		||||
                                            const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
 | 
			
		||||
                                            uint64_t fragment_id,
 | 
			
		||||
                                            uint64_t flags,
 | 
			
		||||
                                            struct GNUNET_MULTICAST_ReplayHandle *rh);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Functions with this signature are called whenever the multicast service needs
 | 
			
		||||
 * a message fragment to be replayed by message_id and fragment_offset.
 | 
			
		||||
 *
 | 
			
		||||
 * Implementations of this function MUST call GNUNET_MULTICAST_replay() ONCE
 | 
			
		||||
 * (with a message or an error); however, if the origin is destroyed or the
 | 
			
		||||
 * group is left, the replay handle must no longer be used.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure (set from GNUNET_MULTICAST_origin_start()
 | 
			
		||||
 *        or GNUNET_MULTICAST_member_join()).
 | 
			
		||||
 * @param member_pub_key
 | 
			
		||||
 *        The member requesting replay.
 | 
			
		||||
 * @param message_id
 | 
			
		||||
 *        Which message should be replayed.
 | 
			
		||||
 * @param fragment_offset
 | 
			
		||||
 *        Offset of the fragment within of @a message_id to be replayed.
 | 
			
		||||
 * @param flags
 | 
			
		||||
 *        Flags for the replay.
 | 
			
		||||
 * @param rh
 | 
			
		||||
 *        Handle to pass to message transmit function.
 | 
			
		||||
 */
 | 
			
		||||
typedef void
 | 
			
		||||
(*GNUNET_MULTICAST_ReplayMessageCallback) (void *cls,
 | 
			
		||||
                                           const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
 | 
			
		||||
                                           uint64_t message_id,
 | 
			
		||||
                                           uint64_t fragment_offset,
 | 
			
		||||
                                           uint64_t flags,
 | 
			
		||||
                                           struct GNUNET_MULTICAST_ReplayHandle *rh);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Possible error codes during replay.
 | 
			
		||||
 */
 | 
			
		||||
enum GNUNET_MULTICAST_ReplayErrorCode
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Everything is fine.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_MULTICAST_REC_OK = 0,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Message fragment not found in the message store.
 | 
			
		||||
   *
 | 
			
		||||
   * Either discarded if it is too old, or not arrived yet if this member has
 | 
			
		||||
   * missed some messages.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_MULTICAST_REC_NOT_FOUND = 1,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Fragment ID counter was larger than the highest counter this
 | 
			
		||||
   * replay function has ever encountered; thus it is likely the
 | 
			
		||||
   * origin never sent it and we're at the HEAD of the multicast
 | 
			
		||||
   * stream as far as this node is concerned.
 | 
			
		||||
   *
 | 
			
		||||
   * FIXME: needed?
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_MULTICAST_REC_PAST_HEAD = 2,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Access is denied to the requested fragment, membership test did not pass.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_MULTICAST_REC_ACCESS_DENIED = 3,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Internal error (i.e. database error).  Try some other peer.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_MULTICAST_REC_INTERNAL_ERROR = 4
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Replay a message fragment for the multicast group.
 | 
			
		||||
 *
 | 
			
		||||
 * @param rh
 | 
			
		||||
 *        Replay handle identifying which replay operation was requested.
 | 
			
		||||
 * @param msg
 | 
			
		||||
 *        Replayed message fragment, NULL if not found / an error occurred.
 | 
			
		||||
 * @param ec
 | 
			
		||||
 *        Error code.  See enum GNUNET_MULTICAST_ReplayErrorCode
 | 
			
		||||
 *        If not #GNUNET_MULTICAST_REC_OK, the replay handle is invalidated.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_MULTICAST_replay_response (struct GNUNET_MULTICAST_ReplayHandle *rh,
 | 
			
		||||
                                  const struct GNUNET_MessageHeader *msg,
 | 
			
		||||
                                  enum GNUNET_MULTICAST_ReplayErrorCode ec);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Indicate the end of the replay session.
 | 
			
		||||
 *
 | 
			
		||||
 * Invalidates the replay handle.
 | 
			
		||||
 *
 | 
			
		||||
 * @param rh Replay session to end.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_MULTICAST_replay_response_end (struct GNUNET_MULTICAST_ReplayHandle *rh);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function called to provide data for a transmission for a replay.
 | 
			
		||||
 *
 | 
			
		||||
 * @see GNUNET_MULTICAST_replay2()
 | 
			
		||||
 */
 | 
			
		||||
typedef int
 | 
			
		||||
(*GNUNET_MULTICAST_ReplayTransmitNotify) (void *cls,
 | 
			
		||||
                                          size_t *data_size,
 | 
			
		||||
                                          void *data);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Replay a message for the multicast group.
 | 
			
		||||
 *
 | 
			
		||||
 * @param rh
 | 
			
		||||
 *        Replay handle identifying which replay operation was requested.
 | 
			
		||||
 * @param notify
 | 
			
		||||
 *        Function to call to get the message.
 | 
			
		||||
 * @param notify_cls
 | 
			
		||||
 *        Closure for @a notify.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_MULTICAST_replay_response2 (struct GNUNET_MULTICAST_ReplayHandle *rh,
 | 
			
		||||
                                   GNUNET_MULTICAST_ReplayTransmitNotify notify,
 | 
			
		||||
                                   void *notify_cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Start a multicast group.
 | 
			
		||||
 *
 | 
			
		||||
 * Peers that issue GNUNET_MULTICAST_member_join() can transmit a join request
 | 
			
		||||
 * to either an existing group member or to the origin.  If the joining is
 | 
			
		||||
 * approved, the member is cleared for @e replay and will begin to receive
 | 
			
		||||
 * messages transmitted to the group.  If joining is disapproved, the failed
 | 
			
		||||
 * candidate will be given a response.  Members in the group can send messages
 | 
			
		||||
 * to the origin.
 | 
			
		||||
 *
 | 
			
		||||
 * TODO: This function could optionally offer to advertise the origin in the
 | 
			
		||||
 * P2P overlay network(where?) under the respective public key so that other
 | 
			
		||||
 * peers can find an alternate PeerId to join it. Higher level protocols may
 | 
			
		||||
 * however provide other means of solving the problem of the offline host
 | 
			
		||||
 * (see secushare specs about that) and therefore merely need a way to provide
 | 
			
		||||
 * a list of possible PeerIds.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cfg
 | 
			
		||||
 *        Configuration to use.
 | 
			
		||||
 * @param priv_key
 | 
			
		||||
 *        ECC key that will be used to sign messages for this
 | 
			
		||||
 *        multicast session; public key is used to identify the multicast group;
 | 
			
		||||
 * @param max_fragment_id
 | 
			
		||||
 *        Maximum fragment ID already sent to the group.
 | 
			
		||||
 *        0 for a new group.
 | 
			
		||||
 * @param join_request_cb
 | 
			
		||||
 *        Function called to approve / disapprove joining of a peer.
 | 
			
		||||
 * @param replay_frag_cb
 | 
			
		||||
 *        Function that can be called to replay a message fragment.
 | 
			
		||||
 * @param replay_msg_cb
 | 
			
		||||
 *        Function that can be called to replay a message.
 | 
			
		||||
 * @param request_cb
 | 
			
		||||
 *        Function called with message fragments from group members.
 | 
			
		||||
 * @param message_cb
 | 
			
		||||
 *        Function called with the message fragments sent to the
 | 
			
		||||
 *        network by GNUNET_MULTICAST_origin_to_all().  These message fragments
 | 
			
		||||
 *        should be stored for answering replay requests later.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the various callbacks that follow.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle for the origin, NULL on error.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_Origin *
 | 
			
		||||
GNUNET_MULTICAST_origin_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
 | 
			
		||||
                               const struct GNUNET_CRYPTO_EddsaPrivateKey *priv_key,
 | 
			
		||||
                               uint64_t max_fragment_id,
 | 
			
		||||
                               GNUNET_MULTICAST_JoinRequestCallback join_request_cb,
 | 
			
		||||
                               GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb,
 | 
			
		||||
                               GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb,
 | 
			
		||||
                               GNUNET_MULTICAST_RequestCallback request_cb,
 | 
			
		||||
                               GNUNET_MULTICAST_MessageCallback message_cb,
 | 
			
		||||
                               void *cls);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function called to provide data for a transmission from the origin to all
 | 
			
		||||
 * members.
 | 
			
		||||
 *
 | 
			
		||||
 * Note that returning #GNUNET_OK or #GNUNET_SYSERR (but not #GNUNET_NO)
 | 
			
		||||
 * invalidates the respective transmission handle.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure.
 | 
			
		||||
 * @param[in,out] data_size
 | 
			
		||||
 *        Initially set to the number of bytes available in
 | 
			
		||||
 *        @a data, should be set to the number of bytes written to data.
 | 
			
		||||
 * @param[out] data
 | 
			
		||||
 *        Where to write the body of the message to give to the
 | 
			
		||||
 *         method. The function must copy at most @a data_size bytes to @a data.
 | 
			
		||||
 *
 | 
			
		||||
 * @return #GNUNET_SYSERR on error (fatal, aborts transmission)
 | 
			
		||||
 *         #GNUNET_NO on success, if more data is to be transmitted later.
 | 
			
		||||
 *         Should be used if @a data_size was not big enough to take all the
 | 
			
		||||
 *         data.  If 0 is returned in @a data_size the transmission is paused,
 | 
			
		||||
 *         and can be resumed with GNUNET_MULTICAST_origin_to_all_resume().
 | 
			
		||||
 *         #GNUNET_YES if this completes the transmission (all data supplied)
 | 
			
		||||
 * @deprecated should move to MQ-style API!
 | 
			
		||||
 */
 | 
			
		||||
typedef int
 | 
			
		||||
(*GNUNET_MULTICAST_OriginTransmitNotify) (void *cls,
 | 
			
		||||
                                          size_t *data_size,
 | 
			
		||||
                                          void *data);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle for a request to send a message to all multicast group members
 | 
			
		||||
 * (from the origin).
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_OriginTransmitHandle;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Send a message to the multicast group.
 | 
			
		||||
 *
 | 
			
		||||
 * @param origin
 | 
			
		||||
 *        Handle to the multicast group.
 | 
			
		||||
 * @param message_id
 | 
			
		||||
 *        Application layer ID for the message.  Opaque to multicast.
 | 
			
		||||
 * @param group_generation
 | 
			
		||||
 *        Group generation of the message.  Documented in
 | 
			
		||||
 *        struct GNUNET_MULTICAST_MessageHeader.
 | 
			
		||||
 * @param notify
 | 
			
		||||
 *        Function to call to get the message.
 | 
			
		||||
 * @param notify_cls
 | 
			
		||||
 *        Closure for @a notify.
 | 
			
		||||
 *
 | 
			
		||||
 * @return NULL on error (i.e. request already pending).
 | 
			
		||||
 * @deprecated should move to MQ-style API!
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_OriginTransmitHandle *
 | 
			
		||||
GNUNET_MULTICAST_origin_to_all (struct GNUNET_MULTICAST_Origin *origin,
 | 
			
		||||
                                uint64_t message_id,
 | 
			
		||||
                                uint64_t group_generation,
 | 
			
		||||
                                GNUNET_MULTICAST_OriginTransmitNotify notify,
 | 
			
		||||
                                void *notify_cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Resume message transmission to multicast group.
 | 
			
		||||
 *
 | 
			
		||||
 * @param th  Transmission to cancel.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_MULTICAST_origin_to_all_resume (struct GNUNET_MULTICAST_OriginTransmitHandle *th);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Cancel request for message transmission to multicast group.
 | 
			
		||||
 *
 | 
			
		||||
 * @param th  Transmission to cancel.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_MULTICAST_origin_to_all_cancel (struct GNUNET_MULTICAST_OriginTransmitHandle *th);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Stop a multicast group.
 | 
			
		||||
 *
 | 
			
		||||
 * @param origin Multicast group to stop.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_MULTICAST_origin_stop (struct GNUNET_MULTICAST_Origin *origin,
 | 
			
		||||
                              GNUNET_ContinuationCallback stop_cb,
 | 
			
		||||
                              void *stop_cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Join a multicast group.
 | 
			
		||||
 *
 | 
			
		||||
 * The entity joining is always the local peer.  Further information about the
 | 
			
		||||
 * candidate can be provided in @a join_msg.  If the join fails, the
 | 
			
		||||
 * @a message_cb is invoked with a (failure) response and then with NULL.  If
 | 
			
		||||
 * the join succeeds, outstanding (state) messages and ongoing multicast
 | 
			
		||||
 * messages will be given to the @a message_cb until the member decides to part
 | 
			
		||||
 * the group.  The @a mem_test_cb and @a replay_cb functions may be called at
 | 
			
		||||
 * anytime by the multicast service to support relaying messages to other
 | 
			
		||||
 * members of the group.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cfg
 | 
			
		||||
 *        Configuration to use.
 | 
			
		||||
 * @param group_key
 | 
			
		||||
 *        ECC public key that identifies the group to join.
 | 
			
		||||
 * @param member_pub_key
 | 
			
		||||
 *        ECC key that identifies the member
 | 
			
		||||
 *        and used to sign requests sent to the origin.
 | 
			
		||||
 * @param origin
 | 
			
		||||
 *        Peer ID of the origin to send unicast requsets to.  If NULL,
 | 
			
		||||
 *        unicast requests are sent back via multiple hops on the reverse path
 | 
			
		||||
 *        of multicast messages.
 | 
			
		||||
 * @param relay_count
 | 
			
		||||
 *        Number of peers in the @a relays array.
 | 
			
		||||
 * @param relays
 | 
			
		||||
 *        Peer identities of members of the group, which serve as relays
 | 
			
		||||
 *        and can be used to join the group at. and send the @a join_request to.
 | 
			
		||||
 *        If empty, the @a join_request is sent directly to the @a origin.
 | 
			
		||||
 * @param join_msg
 | 
			
		||||
 *        Application-dependent join message to be passed to the peer @a origin.
 | 
			
		||||
 * @param join_request_cb
 | 
			
		||||
 *        Function called to approve / disapprove joining of a peer.
 | 
			
		||||
 * @param join_decision_cb
 | 
			
		||||
 *        Function called to inform about the join decision.
 | 
			
		||||
 * @param replay_frag_cb
 | 
			
		||||
 *        Function that can be called to replay message fragments
 | 
			
		||||
 *        this peer already knows from this group. NULL if this
 | 
			
		||||
 *        client is unable to support replay.
 | 
			
		||||
 * @param replay_msg_cb
 | 
			
		||||
 *        Function that can be called to replay message fragments
 | 
			
		||||
 *        this peer already knows from this group. NULL if this
 | 
			
		||||
 *        client is unable to support replay.
 | 
			
		||||
 * @param message_cb
 | 
			
		||||
 *        Function to be called for all message fragments we
 | 
			
		||||
 *        receive from the group, excluding those our @a replay_cb
 | 
			
		||||
 *        already has.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for callbacks.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle for the member, NULL on error.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_Member *
 | 
			
		||||
GNUNET_MULTICAST_member_join (const struct GNUNET_CONFIGURATION_Handle *cfg,
 | 
			
		||||
                              const struct GNUNET_CRYPTO_EddsaPublicKey *group_key,
 | 
			
		||||
                              const struct GNUNET_CRYPTO_EcdsaPrivateKey *member_pub_key,
 | 
			
		||||
                              const struct GNUNET_PeerIdentity *origin,
 | 
			
		||||
                              uint16_t relay_count,
 | 
			
		||||
                              const struct GNUNET_PeerIdentity *relays,
 | 
			
		||||
                              const struct GNUNET_MessageHeader *join_request,
 | 
			
		||||
                              GNUNET_MULTICAST_JoinRequestCallback join_request_cb,
 | 
			
		||||
                              GNUNET_MULTICAST_JoinDecisionCallback join_decision_cb,
 | 
			
		||||
                              GNUNET_MULTICAST_ReplayFragmentCallback replay_frag_cb,
 | 
			
		||||
                              GNUNET_MULTICAST_ReplayMessageCallback replay_msg_cb,
 | 
			
		||||
                              GNUNET_MULTICAST_MessageCallback message_cb,
 | 
			
		||||
                              void *cls);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle for a replay request.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_MemberReplayHandle;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Request a fragment to be replayed by fragment ID.
 | 
			
		||||
 *
 | 
			
		||||
 * Useful if messages below the @e max_known_fragment_id given when joining are
 | 
			
		||||
 * needed and not known to the client.
 | 
			
		||||
 *
 | 
			
		||||
 * @param member
 | 
			
		||||
 *        Membership handle.
 | 
			
		||||
 * @param fragment_id
 | 
			
		||||
 *        ID of a message fragment that this client would like to see replayed.
 | 
			
		||||
 * @param flags
 | 
			
		||||
 *        Additional flags for the replay request.
 | 
			
		||||
 *        It is used and defined by GNUNET_MULTICAST_ReplayFragmentCallback
 | 
			
		||||
 *
 | 
			
		||||
 * @return Replay request handle, NULL on error.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_MemberReplayHandle *
 | 
			
		||||
GNUNET_MULTICAST_member_replay_fragment (struct GNUNET_MULTICAST_Member *member,
 | 
			
		||||
                                         uint64_t fragment_id,
 | 
			
		||||
                                         uint64_t flags);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Request a message fr to be replayed.
 | 
			
		||||
 *
 | 
			
		||||
 * Useful if messages below the @e max_known_fragment_id given when joining are
 | 
			
		||||
 * needed and not known to the client.
 | 
			
		||||
 *
 | 
			
		||||
 * @param member
 | 
			
		||||
 *        Membership handle.
 | 
			
		||||
 * @param message_id
 | 
			
		||||
 *        ID of the message this client would like to see replayed.
 | 
			
		||||
 * @param fragment_offset
 | 
			
		||||
 *        Offset of the fragment within the message to replay.
 | 
			
		||||
 * @param flags
 | 
			
		||||
 *        Additional flags for the replay request.
 | 
			
		||||
 *        It is used & defined by GNUNET_MULTICAST_ReplayMessageCallback
 | 
			
		||||
 *
 | 
			
		||||
 * @return Replay request handle, NULL on error.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_MemberReplayHandle *
 | 
			
		||||
GNUNET_MULTICAST_member_replay_message (struct GNUNET_MULTICAST_Member *member,
 | 
			
		||||
                                        uint64_t message_id,
 | 
			
		||||
                                        uint64_t fragment_offset,
 | 
			
		||||
                                        uint64_t flags);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Cancel a replay request.
 | 
			
		||||
 *
 | 
			
		||||
 * @param rh
 | 
			
		||||
 *        Request to cancel.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_MULTICAST_member_replay_cancel (struct GNUNET_MULTICAST_MemberReplayHandle *rh);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Part a multicast group.
 | 
			
		||||
 *
 | 
			
		||||
 * Disconnects from all group members and invalidates the @a member handle.
 | 
			
		||||
 *
 | 
			
		||||
 * An application-dependent part message can be transmitted beforehand using
 | 
			
		||||
 * #GNUNET_MULTICAST_member_to_origin())
 | 
			
		||||
 *
 | 
			
		||||
 * @param member
 | 
			
		||||
 *        Membership handle.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_MULTICAST_member_part (struct GNUNET_MULTICAST_Member *member,
 | 
			
		||||
                              GNUNET_ContinuationCallback part_cb,
 | 
			
		||||
                              void *part_cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function called to provide data for a transmission from a member to the origin.
 | 
			
		||||
 *
 | 
			
		||||
 * Note that returning #GNUNET_OK or #GNUNET_SYSERR (but not #GNUNET_NO)
 | 
			
		||||
 * invalidates the respective transmission handle.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure.
 | 
			
		||||
 * @param[in,out] data_size
 | 
			
		||||
 *        Initially set to the number of bytes available in
 | 
			
		||||
 *        @a data, should be set to the number of bytes written to data.
 | 
			
		||||
 * @param[out] data
 | 
			
		||||
 *        Where to write the body of the message to give to the
 | 
			
		||||
 *        method. The function must copy at most @a data_size bytes to @a data.
 | 
			
		||||
 *
 | 
			
		||||
 * @return #GNUNET_SYSERR on error (fatal, aborts transmission)
 | 
			
		||||
 *         #GNUNET_NO on success, if more data is to be transmitted later.
 | 
			
		||||
 *         Should be used if @a data_size was not big enough to take all the
 | 
			
		||||
 *         data.  If 0 is returned in @a data_size the transmission is paused,
 | 
			
		||||
 *         and can be resumed with GNUNET_MULTICAST_member_to_origin_resume().
 | 
			
		||||
 *         #GNUNET_YES if this completes the transmission (all data supplied)
 | 
			
		||||
 * @deprecated should move to MQ-style API!
 | 
			
		||||
 */
 | 
			
		||||
typedef int
 | 
			
		||||
(*GNUNET_MULTICAST_MemberTransmitNotify) (void *cls,
 | 
			
		||||
                                          size_t *data_size,
 | 
			
		||||
                                          void *data);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle for a message to be delivered from a member to the origin.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_MemberTransmitHandle;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Send a message to the origin of the multicast group.
 | 
			
		||||
 *
 | 
			
		||||
 * @param member
 | 
			
		||||
 *        Membership handle.
 | 
			
		||||
 * @param request_id
 | 
			
		||||
 *        Application layer ID for the request.  Opaque to multicast.
 | 
			
		||||
 * @param notify
 | 
			
		||||
 *        Callback to call to get the message.
 | 
			
		||||
 * @param notify_cls
 | 
			
		||||
 *        Closure for @a notify.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle to cancel request, NULL on error (i.e. request already pending).
 | 
			
		||||
 * @deprecated should move to MQ-style API!
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_MULTICAST_MemberTransmitHandle *
 | 
			
		||||
GNUNET_MULTICAST_member_to_origin (struct GNUNET_MULTICAST_Member *member,
 | 
			
		||||
                                   uint64_t request_id,
 | 
			
		||||
                                   GNUNET_MULTICAST_MemberTransmitNotify notify,
 | 
			
		||||
                                   void *notify_cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Resume message transmission to origin.
 | 
			
		||||
 *
 | 
			
		||||
 * @param th
 | 
			
		||||
 *        Transmission to cancel.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_MULTICAST_member_to_origin_resume (struct GNUNET_MULTICAST_MemberTransmitHandle *th);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Cancel request for message transmission to origin.
 | 
			
		||||
 *
 | 
			
		||||
 * @param th
 | 
			
		||||
 *        Transmission to cancel.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_MULTICAST_member_to_origin_cancel (struct GNUNET_MULTICAST_MemberTransmitHandle *th);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if 0                           /* keep Emacsens' auto-indent happy */
 | 
			
		||||
{
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* ifndef GNUNET_MULTICAST_SERVICE_H */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** @} */  /* end of group */
 | 
			
		||||
							
								
								
									
										340
									
								
								src/include/gnunet_psyc_env.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										340
									
								
								src/include/gnunet_psyc_env.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,340 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of GNUnet.
 | 
			
		||||
 * Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 *
 | 
			
		||||
 * @file
 | 
			
		||||
 * PSYC Environment library
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup psyc-util-env  PSYC Utilities library: Environment
 | 
			
		||||
 * Environment data structure operations for PSYC and Social messages.
 | 
			
		||||
 *
 | 
			
		||||
 * Library providing operations for the @e environment of
 | 
			
		||||
 * PSYC and Social messages, and for (de)serializing variable values.
 | 
			
		||||
 *
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef GNUNET_PSYC_ENV_H
 | 
			
		||||
#define GNUNET_PSYC_ENV_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C"
 | 
			
		||||
{
 | 
			
		||||
#if 0                           /* keep Emacsens' auto-indent happy */
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Possible operations on PSYC state (persistent) and transient variables (per message).
 | 
			
		||||
 */
 | 
			
		||||
enum GNUNET_PSYC_Operator
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Set value of a transient variable.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_PSYC_OP_SET = ':',
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Assign value for a persistent state variable.
 | 
			
		||||
   *
 | 
			
		||||
   * If an assigned value is NULL, the variable is deleted.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_PSYC_OP_ASSIGN = '=',
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Augment state variable.
 | 
			
		||||
   *
 | 
			
		||||
   * Used for appending strings, adding numbers, and adding new items to a list or dictionary.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_PSYC_OP_AUGMENT = '+',
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Diminish state variable.
 | 
			
		||||
   *
 | 
			
		||||
   * Used for subtracting numbers, and removing items from a list or dictionary.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_PSYC_OP_DIMINISH = '-',
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Update state variable.
 | 
			
		||||
   *
 | 
			
		||||
   * Used for modifying a single item of a list or dictionary.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_PSYC_OP_UPDATE = '@',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * PSYC variable types.
 | 
			
		||||
 */
 | 
			
		||||
enum GNUNET_PSYC_Type
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_PSYC_TYPE_DATA = 0,
 | 
			
		||||
  GNUNET_PSYC_TYPE_NUMBER,
 | 
			
		||||
  GNUNET_PSYC_TYPE_LIST,
 | 
			
		||||
  GNUNET_PSYC_TYPE_DICT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * PSYC state modifier.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_Modifier
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * State operation.
 | 
			
		||||
   */
 | 
			
		||||
  enum GNUNET_PSYC_Operator oper;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Variable name.
 | 
			
		||||
   */
 | 
			
		||||
  const char *name;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Size of @a value.
 | 
			
		||||
   */
 | 
			
		||||
  size_t value_size;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Value of variable.
 | 
			
		||||
   */
 | 
			
		||||
  const void *value;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Next modifier.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_PSYC_Modifier *next;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Previous modifier.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_PSYC_Modifier *prev;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Environment for a message.
 | 
			
		||||
 *
 | 
			
		||||
 * Contains modifiers.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_Environment;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create an environment.
 | 
			
		||||
 *
 | 
			
		||||
 * @return A newly allocated environment.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_Environment *
 | 
			
		||||
GNUNET_PSYC_env_create ();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Add a modifier to the environment.
 | 
			
		||||
 *
 | 
			
		||||
 * @param env The environment.
 | 
			
		||||
 * @param oper Operation to perform.
 | 
			
		||||
 * @param name Name of the variable.
 | 
			
		||||
 * @param value Value of the variable.
 | 
			
		||||
 * @param value_size Size of @a value.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_env_add (struct GNUNET_PSYC_Environment *env,
 | 
			
		||||
                     enum GNUNET_PSYC_Operator oper, const char *name,
 | 
			
		||||
                     const void *value, size_t value_size);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the first modifier of the environment.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_Modifier *
 | 
			
		||||
GNUNET_PSYC_env_head (const struct GNUNET_PSYC_Environment *env);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the last modifier of the environment.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_Modifier *
 | 
			
		||||
GNUNET_PSYC_env_tail (const struct GNUNET_PSYC_Environment *env);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove a modifier from the environment.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_env_remove (struct GNUNET_PSYC_Environment *env,
 | 
			
		||||
                        struct GNUNET_PSYC_Modifier *mod);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove a modifier at the beginning of the environment.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYC_env_shift (struct GNUNET_PSYC_Environment *env,
 | 
			
		||||
                       enum GNUNET_PSYC_Operator *oper, const char **name,
 | 
			
		||||
                       const void **value, size_t *value_size);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Iterator for modifiers in the environment.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls Closure.
 | 
			
		||||
 * @param mod Modifier.
 | 
			
		||||
 *
 | 
			
		||||
 * @return #GNUNET_YES to continue iterating,
 | 
			
		||||
 *         #GNUNET_NO to stop.
 | 
			
		||||
 */
 | 
			
		||||
typedef int
 | 
			
		||||
(*GNUNET_PSYC_Iterator) (void *cls, enum GNUNET_PSYC_Operator oper,
 | 
			
		||||
                         const char *name, const char *value,
 | 
			
		||||
                         uint32_t value_size);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Iterate through all modifiers in the environment.
 | 
			
		||||
 *
 | 
			
		||||
 * @param env The environment.
 | 
			
		||||
 * @param it Iterator.
 | 
			
		||||
 * @param it_cls Closure for iterator.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_env_iterate (const struct GNUNET_PSYC_Environment *env,
 | 
			
		||||
                         GNUNET_PSYC_Iterator it, void *it_cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the number of modifiers in the environment.
 | 
			
		||||
 *
 | 
			
		||||
 * @param env The environment.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Number of modifiers.
 | 
			
		||||
 */
 | 
			
		||||
size_t
 | 
			
		||||
GNUNET_PSYC_env_get_count (const struct GNUNET_PSYC_Environment *env);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Destroy an environment.
 | 
			
		||||
 *
 | 
			
		||||
 * @param env The environment to destroy.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_env_destroy (struct GNUNET_PSYC_Environment *env);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the type of variable.
 | 
			
		||||
 *
 | 
			
		||||
 * @param name Name of the variable.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Variable type.
 | 
			
		||||
 */
 | 
			
		||||
enum GNUNET_PSYC_Type
 | 
			
		||||
GNUNET_PSYC_var_get_type (char *name);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Perform an operation on a variable.
 | 
			
		||||
 *
 | 
			
		||||
 * @param name Name of variable.
 | 
			
		||||
 * @param current_value Current value of variable.
 | 
			
		||||
 * @param current_value_size Size of @a current_value.
 | 
			
		||||
 * @param oper Operator.
 | 
			
		||||
 * @param args Arguments for the operation.
 | 
			
		||||
 * @param args_size Size of @a args.
 | 
			
		||||
 * @param return_value Return value.
 | 
			
		||||
 * @param return_value_size Size of @a return_value.
 | 
			
		||||
 *
 | 
			
		||||
 * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYC_operation (char *name, void *current_value, size_t current_value_size,
 | 
			
		||||
                       enum GNUNET_PSYC_Operator oper, void *args, size_t args_size,
 | 
			
		||||
                       void **return_value, size_t *return_value_size);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the variable's value as an integer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param size Size of value.
 | 
			
		||||
 * @param value Raw value of variable.
 | 
			
		||||
 * @param[out] number Value converted to a 64-bit integer.
 | 
			
		||||
 *
 | 
			
		||||
 * @return #GNUNET_OK on success, #GNUNET_SYSERR if an error occurred (e.g. the value is invalid).
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYC_value_to_number (size_t size, const void *value, int64_t *number);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the variable's value as a dictionary.
 | 
			
		||||
 *
 | 
			
		||||
 * @param size Size of value.
 | 
			
		||||
 * @param value Raw value of variable.
 | 
			
		||||
 * @param[out] dict A newly created hashmap holding the elements of the dictionary.
 | 
			
		||||
 *
 | 
			
		||||
 * @return #GNUNET_OK on success, #GNUNET_SYSERR if an error occurred (e.g. the value is invalid).
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYC_value_to_dict (size_t size, const void *value, struct GNUNET_CONTAINER_MultiHashMap **dict);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a PSYC variable value from an integer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param number The number to convert.
 | 
			
		||||
 * @param[out] value_size Size of returned value.
 | 
			
		||||
 *
 | 
			
		||||
 * @return A newly allocated value or NULL on error.
 | 
			
		||||
 */
 | 
			
		||||
void *
 | 
			
		||||
GNUNET_PSYC_value_from_number (int64_t number, size_t *value_size);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a PSYC variable value from a dictionary.
 | 
			
		||||
 *
 | 
			
		||||
 * @param dict The dict to convert.
 | 
			
		||||
 * @param[out] value_size Size of returned value.
 | 
			
		||||
 *
 | 
			
		||||
 * @return A newly allocated value or NULL on error.
 | 
			
		||||
 */
 | 
			
		||||
void *
 | 
			
		||||
GNUNET_PSYC_value_from_dict (struct GNUNET_CONTAINER_MultiHashMap *dict, size_t *value_size);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if 0                           /* keep Emacsens' auto-indent happy */
 | 
			
		||||
{
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* ifndef GNUNET_PSYC_ENV_H */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** @} */  /* end of group */
 | 
			
		||||
							
								
								
									
										278
									
								
								src/include/gnunet_psyc_message.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										278
									
								
								src/include/gnunet_psyc_message.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,278 @@
 | 
			
		||||
/*
 | 
			
		||||
     This file is part of GNUnet.
 | 
			
		||||
     Copyright (C) 2012, 2013 GNUnet e.V.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 *
 | 
			
		||||
 * @file
 | 
			
		||||
 * PSYC message utilities; receiving/transmitting/logging PSYC messages
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup psyc-util-message  PSYC Utilities library: Messages
 | 
			
		||||
 * Receiving, transmitting, logging PSYC messages.
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef GNUNET_PSYC_MESSAGE_H
 | 
			
		||||
#define GNUNET_PSYC_MESSAGE_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C"
 | 
			
		||||
{
 | 
			
		||||
#if 0                           /* keep Emacsens' auto-indent happy */
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
#include "gnunet_psyc_util_lib.h"
 | 
			
		||||
#include "gnunet_psyc_service.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a PSYC message.
 | 
			
		||||
 *
 | 
			
		||||
 * @param method_name
 | 
			
		||||
 *        PSYC method for the message.
 | 
			
		||||
 * @param env
 | 
			
		||||
 *        Environment for the message.
 | 
			
		||||
 * @param data
 | 
			
		||||
 *        Data payload for the message.
 | 
			
		||||
 * @param data_size
 | 
			
		||||
 *        Size of @a data.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Message header with size information,
 | 
			
		||||
 *         followed by the message parts.
 | 
			
		||||
 *
 | 
			
		||||
 * FIXME: arg order
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_Message *
 | 
			
		||||
GNUNET_PSYC_message_create (const char *method_name,
 | 
			
		||||
                            const struct GNUNET_PSYC_Environment *env,
 | 
			
		||||
                            const void *data,
 | 
			
		||||
                            size_t data_size);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Parse PSYC message.
 | 
			
		||||
 *
 | 
			
		||||
 * @param msg
 | 
			
		||||
 *        The PSYC message to parse.
 | 
			
		||||
 * @param env
 | 
			
		||||
 *        The environment for the message with a list of modifiers.
 | 
			
		||||
 * @param[out] method_name
 | 
			
		||||
 *        Pointer to the method name inside @a pmsg.
 | 
			
		||||
 * @param[out] data
 | 
			
		||||
 *        Pointer to data inside @a pmsg.
 | 
			
		||||
 * @param[out] data_size
 | 
			
		||||
 *        Size of @data is written here.
 | 
			
		||||
 *
 | 
			
		||||
 * @return #GNUNET_OK on success,
 | 
			
		||||
 *         #GNUNET_SYSERR on parse error.
 | 
			
		||||
 *
 | 
			
		||||
 * FIXME: arg order
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYC_message_parse (const struct GNUNET_PSYC_MessageHeader *msg,
 | 
			
		||||
                           const char **method_name,
 | 
			
		||||
                           struct GNUNET_PSYC_Environment *env,
 | 
			
		||||
                           const void **data,
 | 
			
		||||
                           uint16_t *data_size);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_log_message (enum GNUNET_ErrorType kind,
 | 
			
		||||
                         const struct GNUNET_MessageHeader *msg);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct GNUNET_PSYC_TransmitHandle;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a transmission handle.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_TransmitHandle *
 | 
			
		||||
GNUNET_PSYC_transmit_create (struct GNUNET_MQ_Handle *mq);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Destroy a transmission handle.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_transmit_destroy (struct GNUNET_PSYC_TransmitHandle *tmit);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Transmit a message.
 | 
			
		||||
 *
 | 
			
		||||
 * @param tmit
 | 
			
		||||
 *        Transmission handle.
 | 
			
		||||
 * @param method_name
 | 
			
		||||
 *        Which method should be invoked.
 | 
			
		||||
 * @param env
 | 
			
		||||
 *        Environment for the message.
 | 
			
		||||
 *        Should stay available until the first call to notify_data.
 | 
			
		||||
 *        Can be NULL if there are no modifiers or @a notify_mod is
 | 
			
		||||
 *        provided instead.
 | 
			
		||||
 * @param notify_mod
 | 
			
		||||
 *        Function to call to obtain modifiers.
 | 
			
		||||
 *        Can be NULL if there are no modifiers or @a env is provided instead.
 | 
			
		||||
 * @param notify_data
 | 
			
		||||
 *        Function to call to obtain fragments of the data.
 | 
			
		||||
 * @param notify_cls
 | 
			
		||||
 *        Closure for @a notify_mod and @a notify_data.
 | 
			
		||||
 * @param flags
 | 
			
		||||
 *        Flags for the message being transmitted.
 | 
			
		||||
 *
 | 
			
		||||
 * @return #GNUNET_OK if the transmission was started.
 | 
			
		||||
 *         #GNUNET_SYSERR if another transmission is already going on.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYC_transmit_message (struct GNUNET_PSYC_TransmitHandle *tmit,
 | 
			
		||||
                              const char *method_name,
 | 
			
		||||
                              const struct GNUNET_PSYC_Environment *env,
 | 
			
		||||
                              GNUNET_PSYC_TransmitNotifyModifier notify_mod,
 | 
			
		||||
                              GNUNET_PSYC_TransmitNotifyData notify_data,
 | 
			
		||||
                              void *notify_cls,
 | 
			
		||||
                              uint32_t flags);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Resume transmission.
 | 
			
		||||
 *
 | 
			
		||||
 * @param tmit  Transmission handle.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_transmit_resume (struct GNUNET_PSYC_TransmitHandle *tmit);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Abort transmission request.
 | 
			
		||||
 *
 | 
			
		||||
 * @param tmit  Transmission handle.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_transmit_cancel (struct GNUNET_PSYC_TransmitHandle *tmit);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Got acknowledgement of a transmitted message part, continue transmission.
 | 
			
		||||
 *
 | 
			
		||||
 * @param tmit  Transmission handle.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_transmit_got_ack (struct GNUNET_PSYC_TransmitHandle *tmit);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct GNUNET_PSYC_ReceiveHandle;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create handle for receiving messages.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_ReceiveHandle *
 | 
			
		||||
GNUNET_PSYC_receive_create (GNUNET_PSYC_MessageCallback message_cb,
 | 
			
		||||
                            GNUNET_PSYC_MessagePartCallback message_part_cb,
 | 
			
		||||
                            void *cb_cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Destroy handle for receiving messages.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_receive_destroy (struct GNUNET_PSYC_ReceiveHandle *recv);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reset stored data related to the last received message.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_receive_reset (struct GNUNET_PSYC_ReceiveHandle *recv);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle incoming PSYC message.
 | 
			
		||||
 *
 | 
			
		||||
 * @param recv
 | 
			
		||||
 *        Receive handle.
 | 
			
		||||
 * @param msg
 | 
			
		||||
 *        The message.
 | 
			
		||||
 *
 | 
			
		||||
 * @return #GNUNET_OK on success,
 | 
			
		||||
 *         #GNUNET_SYSERR on receive error.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYC_receive_message (struct GNUNET_PSYC_ReceiveHandle *recv,
 | 
			
		||||
                             const struct GNUNET_PSYC_MessageHeader *msg);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if @a data contains a series of valid message parts.
 | 
			
		||||
 *
 | 
			
		||||
 * @param data_size
 | 
			
		||||
 *        Size of @a data.
 | 
			
		||||
 * @param data
 | 
			
		||||
 *        Data.
 | 
			
		||||
 * @param[out] first_ptype
 | 
			
		||||
 *        Type of first message part.
 | 
			
		||||
 * @param[out] last_ptype
 | 
			
		||||
 *        Type of last message part.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Number of message parts found in @a data.
 | 
			
		||||
 *         or GNUNET_SYSERR if the message contains invalid parts.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYC_receive_check_parts (uint16_t data_size, const char *data,
 | 
			
		||||
                                 uint16_t *first_ptype, uint16_t *last_ptype);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialize PSYC message header.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_message_header_init (struct GNUNET_PSYC_MessageHeader *pmsg,
 | 
			
		||||
                                 const struct GNUNET_MULTICAST_MessageHeader *mmsg,
 | 
			
		||||
                                 uint32_t flags);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a new PSYC message header from a multicast message for sending it to clients.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_MessageHeader *
 | 
			
		||||
GNUNET_PSYC_message_header_create (const struct GNUNET_MULTICAST_MessageHeader *mmsg,
 | 
			
		||||
                                   uint32_t flags);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a new PSYC message header from a PSYC message.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_MessageHeader *
 | 
			
		||||
GNUNET_PSYC_message_header_create_from_psyc (const struct GNUNET_PSYC_Message *msg);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if 0                           /* keep Emacsens' auto-indent happy */
 | 
			
		||||
{
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* ifndef GNUNET_PSYC_MESSAGE_H */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** @} */  /* end of group */
 | 
			
		||||
							
								
								
									
										1364
									
								
								src/include/gnunet_psyc_service.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1364
									
								
								src/include/gnunet_psyc_service.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										378
									
								
								src/include/gnunet_psyc_slicer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										378
									
								
								src/include/gnunet_psyc_slicer.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,378 @@
 | 
			
		||||
/*
 | 
			
		||||
     This file is part of GNUnet.
 | 
			
		||||
     Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 * @author Christian Grothoff
 | 
			
		||||
 *
 | 
			
		||||
 * @file
 | 
			
		||||
 * PSYC Slicer library
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup psyc-util-slicer  PSYC Utilities library: Slicer
 | 
			
		||||
 * Try-and-slice processing of PSYC method names and environment.
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef GNUNET_PSYC_SLICER_H
 | 
			
		||||
#define GNUNET_PSYC_SLICER_H
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C"
 | 
			
		||||
{
 | 
			
		||||
#if 0                           /* keep Emacsens' auto-indent happy */
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle to an implementation of try-and-slice.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_Slicer;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function called upon receiving a message indicating a call to a @e method.
 | 
			
		||||
 *
 | 
			
		||||
 * This function is called one or more times for each message until all data
 | 
			
		||||
 * fragments arrive from the network.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure.
 | 
			
		||||
 * @param msg
 | 
			
		||||
 *        Message part, as it arrived from the network.
 | 
			
		||||
 * @param message_id
 | 
			
		||||
 *        Message counter, monotonically increasing from 1.
 | 
			
		||||
 * @param flags
 | 
			
		||||
 *        OR'ed GNUNET_PSYC_MessageFlags
 | 
			
		||||
 * @param fragment_offset
 | 
			
		||||
 *        Multicast message fragment offset.
 | 
			
		||||
 * @param tmit_flags
 | 
			
		||||
 *        OR'ed GNUNET_PSYC_MasterTransmitFlags
 | 
			
		||||
 * @param nym
 | 
			
		||||
 *        The sender of the message.
 | 
			
		||||
 *        Can be NULL if the message is not connected to a pseudonym.
 | 
			
		||||
 * @param method_name
 | 
			
		||||
 *        Original method name from PSYC.
 | 
			
		||||
 *        May be more specific than the registered method name due to
 | 
			
		||||
 *        try-and-slice matching.
 | 
			
		||||
 */
 | 
			
		||||
typedef void
 | 
			
		||||
(*GNUNET_PSYC_MethodCallback) (void *cls,
 | 
			
		||||
                               const struct GNUNET_PSYC_MessageHeader *msg,
 | 
			
		||||
                               const struct GNUNET_PSYC_MessageMethod *meth,
 | 
			
		||||
                               uint64_t message_id,
 | 
			
		||||
                               const char *method_name);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function called upon receiving a modifier of a message.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure.
 | 
			
		||||
 * @param message_id
 | 
			
		||||
 *        Message ID this data fragment belongs to.
 | 
			
		||||
 * @param flags
 | 
			
		||||
 *        OR'ed GNUNET_PSYC_MessageFlags
 | 
			
		||||
 * @param fragment_offset
 | 
			
		||||
 *        Multicast message fragment offset.
 | 
			
		||||
 * @param msg
 | 
			
		||||
 *        Message part, as it arrived from the network.
 | 
			
		||||
 * @param oper
 | 
			
		||||
 *        Operation to perform.
 | 
			
		||||
 *        0 in case of a modifier continuation.
 | 
			
		||||
 * @param name
 | 
			
		||||
 *        Name of the modifier.
 | 
			
		||||
 *        NULL in case of a modifier continuation.
 | 
			
		||||
 * @param value
 | 
			
		||||
 *        Value of the modifier.
 | 
			
		||||
 * @param value_size
 | 
			
		||||
 *        Size of @value.
 | 
			
		||||
 */
 | 
			
		||||
typedef void
 | 
			
		||||
(*GNUNET_PSYC_ModifierCallback) (void *cls,
 | 
			
		||||
                                 const struct GNUNET_PSYC_MessageHeader *msg,
 | 
			
		||||
                                 const struct GNUNET_MessageHeader *pmsg,
 | 
			
		||||
                                 uint64_t message_id,
 | 
			
		||||
                                 enum GNUNET_PSYC_Operator oper,
 | 
			
		||||
                                 const char *name,
 | 
			
		||||
                                 const void *value,
 | 
			
		||||
                                 uint16_t value_size,
 | 
			
		||||
                                 uint16_t full_value_size);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function called upon receiving a data fragment of a message.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure.
 | 
			
		||||
 * @param msg
 | 
			
		||||
 *        Message part, as it arrived from the network.
 | 
			
		||||
 * @param message_id
 | 
			
		||||
 *        Message ID this data fragment belongs to.
 | 
			
		||||
 * @param flags
 | 
			
		||||
 *        OR'ed GNUNET_PSYC_MessageFlags
 | 
			
		||||
 * @param fragment_offset
 | 
			
		||||
 *        Multicast message fragment offset.
 | 
			
		||||
 * @param data
 | 
			
		||||
 *        Data stream given to the method.
 | 
			
		||||
 * @param data_size
 | 
			
		||||
 *        Number of bytes in @a data.
 | 
			
		||||
 * @param end
 | 
			
		||||
 *        End of message?
 | 
			
		||||
 *        #GNUNET_NO     if there are further fragments,
 | 
			
		||||
 *        #GNUNET_YES    if this is the last fragment,
 | 
			
		||||
 *        #GNUNET_SYSERR indicates the message was cancelled by the sender.
 | 
			
		||||
 */
 | 
			
		||||
typedef void
 | 
			
		||||
(*GNUNET_PSYC_DataCallback) (void *cls,
 | 
			
		||||
                             const struct GNUNET_PSYC_MessageHeader *msg,
 | 
			
		||||
                             const struct GNUNET_MessageHeader *pmsg,
 | 
			
		||||
                             uint64_t message_id,
 | 
			
		||||
                             const void *data,
 | 
			
		||||
                             uint16_t data_size);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * End of message.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure.
 | 
			
		||||
 * @param msg
 | 
			
		||||
 *        Message part, as it arrived from the network.
 | 
			
		||||
 * @param message_id
 | 
			
		||||
 *        Message ID this data fragment belongs to.
 | 
			
		||||
 * @param flags
 | 
			
		||||
 *        OR'ed GNUNET_PSYC_MessageFlags
 | 
			
		||||
 * @param fragment_offset
 | 
			
		||||
 *        Multicast message fragment offset.
 | 
			
		||||
 * @param cancelled
 | 
			
		||||
 *        #GNUNET_YES if the message was cancelled,
 | 
			
		||||
 *        #GNUNET_NO  if the message is complete.
 | 
			
		||||
 */
 | 
			
		||||
typedef void
 | 
			
		||||
(*GNUNET_PSYC_EndOfMessageCallback) (void *cls,
 | 
			
		||||
                                     const struct GNUNET_PSYC_MessageHeader *msg,
 | 
			
		||||
                                     const struct GNUNET_MessageHeader *pmsg,
 | 
			
		||||
                                     uint64_t message_id,
 | 
			
		||||
                                     uint8_t is_cancelled);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a try-and-slice instance.
 | 
			
		||||
 *
 | 
			
		||||
 * A slicer processes incoming messages and notifies callbacks about matching
 | 
			
		||||
 * methods or modifiers encountered.
 | 
			
		||||
 *
 | 
			
		||||
 * @return A new try-and-slice construct.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_Slicer *
 | 
			
		||||
GNUNET_PSYC_slicer_create (void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Add a method to the try-and-slice instance.
 | 
			
		||||
 *
 | 
			
		||||
 * The callbacks are called for messages with a matching @a method_name prefix.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        The try-and-slice instance to extend.
 | 
			
		||||
 * @param method_name
 | 
			
		||||
 *        Name of the given method, use empty string to match all.
 | 
			
		||||
 * @param method_cb
 | 
			
		||||
 *        Method handler invoked upon a matching message.
 | 
			
		||||
 * @param modifier_cb
 | 
			
		||||
 *        Modifier handler, invoked after @a method_cb
 | 
			
		||||
 *        for each modifier in the message.
 | 
			
		||||
 * @param data_cb
 | 
			
		||||
 *        Data handler, invoked after @a modifier_cb for each data fragment.
 | 
			
		||||
 * @param eom_cb
 | 
			
		||||
 *        Invoked upon reaching the end of a matching message.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the callbacks.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_method_add (struct GNUNET_PSYC_Slicer *slicer,
 | 
			
		||||
                               const char *method_name,
 | 
			
		||||
                               GNUNET_PSYC_MessageCallback msg_cb,
 | 
			
		||||
                               GNUNET_PSYC_MethodCallback method_cb,
 | 
			
		||||
                               GNUNET_PSYC_ModifierCallback modifier_cb,
 | 
			
		||||
                               GNUNET_PSYC_DataCallback data_cb,
 | 
			
		||||
                               GNUNET_PSYC_EndOfMessageCallback eom_cb,
 | 
			
		||||
                               void *cls);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove a registered method from the try-and-slice instance.
 | 
			
		||||
 *
 | 
			
		||||
 * Removes one matching handler registered with the given
 | 
			
		||||
 * @a method_name and callbacks.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        The try-and-slice instance.
 | 
			
		||||
 * @param method_name
 | 
			
		||||
 *        Name of the method to remove.
 | 
			
		||||
 * @param method_cb
 | 
			
		||||
 *        Only remove matching method handler, or NULL.
 | 
			
		||||
 * @param modifier_cb
 | 
			
		||||
 *        Only remove matching modifier handler, or NULL.
 | 
			
		||||
 * @param data_cb
 | 
			
		||||
 *        Only remove matching data handler, or NULL.
 | 
			
		||||
 * @param eom_cb
 | 
			
		||||
 *        Only remove matching End of Message handler, or NULL.
 | 
			
		||||
 *
 | 
			
		||||
 * @return #GNUNET_OK if a method handler was removed,
 | 
			
		||||
 *         #GNUNET_NO if no handler matched the given method name and callbacks.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYC_slicer_method_remove (struct GNUNET_PSYC_Slicer *slicer,
 | 
			
		||||
                                  const char *method_name,
 | 
			
		||||
                                  GNUNET_PSYC_MessageCallback msg_cb,
 | 
			
		||||
                                  GNUNET_PSYC_MethodCallback method_cb,
 | 
			
		||||
                                  GNUNET_PSYC_ModifierCallback modifier_cb,
 | 
			
		||||
                                  GNUNET_PSYC_DataCallback data_cb,
 | 
			
		||||
                                  GNUNET_PSYC_EndOfMessageCallback eom_cb);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Watch a place for changed objects.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        The try-and-slice instance.
 | 
			
		||||
 * @param object_filter
 | 
			
		||||
 *        Object prefix to match.
 | 
			
		||||
 * @param modifier_cb
 | 
			
		||||
 *        Function to call when encountering a state modifier.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for callback.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_modifier_add (struct GNUNET_PSYC_Slicer *slicer,
 | 
			
		||||
                                 const char *object_filter,
 | 
			
		||||
                                 GNUNET_PSYC_ModifierCallback modifier_cb,
 | 
			
		||||
                                 void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove a registered modifier from the try-and-slice instance.
 | 
			
		||||
 *
 | 
			
		||||
 * Removes one matching handler registered with the given
 | 
			
		||||
 * @a object_filter and callback.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        The try-and-slice instance.
 | 
			
		||||
 * @param object_filter
 | 
			
		||||
 *        Object prefix to match.
 | 
			
		||||
 * @param modifier_cb
 | 
			
		||||
 *        Function to call when encountering a state modifier changes.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYC_slicer_modifier_remove (struct GNUNET_PSYC_Slicer *slicer,
 | 
			
		||||
                                    const char *object_filter,
 | 
			
		||||
                                    GNUNET_PSYC_ModifierCallback modifier_cb);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Process an incoming message and call matching handlers.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        The slicer to use.
 | 
			
		||||
 * @param msg
 | 
			
		||||
 *        The message as it arrived from the network.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_message (struct GNUNET_PSYC_Slicer *slicer,
 | 
			
		||||
                            const struct GNUNET_PSYC_MessageHeader *msg);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Process an incoming message part and call matching handlers.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        The slicer to use.
 | 
			
		||||
 * @param message_id
 | 
			
		||||
 *        ID of the message.
 | 
			
		||||
 * @param flags
 | 
			
		||||
 *        Flags for the message.
 | 
			
		||||
 *        @see enum GNUNET_PSYC_MessageFlags
 | 
			
		||||
 * @param fragment offset
 | 
			
		||||
 *        Fragment offset of the message.
 | 
			
		||||
 * @param msg
 | 
			
		||||
 *        The message part as it arrived from the network.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_message_part (struct GNUNET_PSYC_Slicer *slicer,
 | 
			
		||||
                                 const struct GNUNET_PSYC_MessageHeader *msg,
 | 
			
		||||
                                 const struct GNUNET_MessageHeader *pmsg);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove all registered method handlers.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        Slicer to clear.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_method_clear (struct GNUNET_PSYC_Slicer *slicer);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove all registered modifier handlers.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        Slicer to clear.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_modifier_clear (struct GNUNET_PSYC_Slicer *slicer);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove all registered method & modifier handlers.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        Slicer to clear.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_clear (struct GNUNET_PSYC_Slicer *slicer);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Destroy a given try-and-slice instance.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        Slicer to destroy
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_destroy (struct GNUNET_PSYC_Slicer *slicer);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if 0                           /* keep Emacsens' auto-indent happy */
 | 
			
		||||
{
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* ifndef GNUNET_PSYC_SLICER_H */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** @} */  /* end of group */
 | 
			
		||||
							
								
								
									
										53
									
								
								src/include/gnunet_psyc_util_lib.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/include/gnunet_psyc_util_lib.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,53 @@
 | 
			
		||||
/*
 | 
			
		||||
     This file is part of GNUnet.
 | 
			
		||||
     Copyright (C) 2012, 2013 GNUnet e.V.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 *
 | 
			
		||||
 * @file
 | 
			
		||||
 * PSYC utilities: messages, environment, slicer
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef GNUNET_PSYC_UTIL_LIB_H
 | 
			
		||||
#define GNUNET_PSYC_UTIL_LIB_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C"
 | 
			
		||||
{
 | 
			
		||||
#if 0                           /* keep Emacsens' auto-indent happy */
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "gnunet_psyc_env.h"
 | 
			
		||||
#include "gnunet_psyc_message.h"
 | 
			
		||||
#include "gnunet_psyc_slicer.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if 0                           /* keep Emacsens' auto-indent happy */
 | 
			
		||||
{
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* ifndef GNUNET_PSYC_UTIL_LIB_H */
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										383
									
								
								src/include/gnunet_psycstore_plugin.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										383
									
								
								src/include/gnunet_psycstore_plugin.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,383 @@
 | 
			
		||||
/*
 | 
			
		||||
     This file is part of GNUnet
 | 
			
		||||
     Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 *
 | 
			
		||||
 * @file
 | 
			
		||||
 * Plugin API for the PSYCstore database backend
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup psycstore-plugin  PSYC Store plugin API
 | 
			
		||||
 * Plugin API for the PSYC Store database backend
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
#ifndef GNUNET_PSYCSTORE_PLUGIN_H
 | 
			
		||||
#define GNUNET_PSYCSTORE_PLUGIN_H
 | 
			
		||||
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
#include "gnunet_psycstore_service.h"
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C"
 | 
			
		||||
{
 | 
			
		||||
#if 0                           /* keep Emacsens' auto-indent happy */
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Struct returned by the initialization function of the plugin.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_PluginFunctions
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Closure to pass to all plugin functions.
 | 
			
		||||
   */
 | 
			
		||||
  void *cls;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Store join/leave events for a PSYC channel in order to be able to answer
 | 
			
		||||
   * membership test queries later.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_membership_store()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*membership_store) (void *cls,
 | 
			
		||||
                       const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                       const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
 | 
			
		||||
                       int did_join,
 | 
			
		||||
                       uint64_t announced_at,
 | 
			
		||||
                       uint64_t effective_since,
 | 
			
		||||
                       uint64_t group_generation);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Test if a member was admitted to the channel at the given message ID.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_membership_test()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_YES if the member was admitted, #GNUNET_NO if not,
 | 
			
		||||
   *         #GNUNET_SYSERR if there was en error.
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*membership_test) (void *cls,
 | 
			
		||||
                      const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                      const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
 | 
			
		||||
                      uint64_t message_id);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Store a message fragment sent to a channel.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_fragment_store()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*fragment_store) (void *cls,
 | 
			
		||||
                     const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                     const struct GNUNET_MULTICAST_MessageHeader *message,
 | 
			
		||||
                     uint32_t psycstore_flags);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set additional flags for a given message.
 | 
			
		||||
   *
 | 
			
		||||
   * They are OR'd with any existing flags set.
 | 
			
		||||
   *
 | 
			
		||||
   * @param cls Closure.
 | 
			
		||||
   * @param channel_key Public key of the channel.
 | 
			
		||||
   * @param message_id ID of the message.
 | 
			
		||||
   * @param psycstore_flags OR'd GNUNET_PSYCSTORE_MessageFlags.
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*message_add_flags) (void *cls,
 | 
			
		||||
                        const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                        uint64_t message_id,
 | 
			
		||||
                        uint32_t psycstore_flags);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve a message fragment range by fragment ID.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_fragment_get()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*fragment_get) (void *cls,
 | 
			
		||||
                   const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                   uint64_t first_fragment_id,
 | 
			
		||||
                   uint64_t last_fragment_id,
 | 
			
		||||
                   uint64_t *returned_fragments,
 | 
			
		||||
                   GNUNET_PSYCSTORE_FragmentCallback cb,
 | 
			
		||||
                   void *cb_cls);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve latest message fragments.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_fragment_get()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*fragment_get_latest) (void *cls,
 | 
			
		||||
                          const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                          uint64_t fragment_limit,
 | 
			
		||||
                          uint64_t *returned_fragments,
 | 
			
		||||
                          GNUNET_PSYCSTORE_FragmentCallback cb,
 | 
			
		||||
                          void *cb_cls);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve all fragments of a message ID range.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_message_get()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*message_get) (void *cls,
 | 
			
		||||
                  const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                  uint64_t first_fragment_id,
 | 
			
		||||
                  uint64_t last_fragment_id,
 | 
			
		||||
                  uint64_t fragment_limit,
 | 
			
		||||
                  uint64_t *returned_fragments,
 | 
			
		||||
                  GNUNET_PSYCSTORE_FragmentCallback cb,
 | 
			
		||||
                  void *cb_cls);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve all fragments of the latest messages.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_message_get()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*message_get_latest) (void *cls,
 | 
			
		||||
                         const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                         uint64_t fragment_limit,
 | 
			
		||||
                         uint64_t *returned_fragments,
 | 
			
		||||
                         GNUNET_PSYCSTORE_FragmentCallback cb,
 | 
			
		||||
                         void *cb_cls);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve a fragment of message specified by its message ID and fragment
 | 
			
		||||
   * offset.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_message_get_fragment()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*message_get_fragment) (void *cls,
 | 
			
		||||
                           const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                           uint64_t message_id,
 | 
			
		||||
                           uint64_t fragment_offset,
 | 
			
		||||
                           GNUNET_PSYCSTORE_FragmentCallback cb,
 | 
			
		||||
                           void *cb_cls);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve the max. values of message counters for a channel.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_counters_get()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*counters_message_get) (void *cls,
 | 
			
		||||
                           const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                           uint64_t *max_fragment_id,
 | 
			
		||||
                           uint64_t *max_message_id,
 | 
			
		||||
                           uint64_t *max_group_generation);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve the max. values of state counters for a channel.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_counters_get()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*counters_state_get) (void *cls,
 | 
			
		||||
                         const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                         uint64_t *max_state_message_id);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Begin modifying current state.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_state_modify()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*state_modify_begin) (void *cls,
 | 
			
		||||
                         const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                         uint64_t message_id, uint64_t state_delta);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the current value of a state variable.
 | 
			
		||||
   *
 | 
			
		||||
   * The state modification process is started with state_modify_begin(),
 | 
			
		||||
   * which is followed by one or more calls to this function,
 | 
			
		||||
   * and finished with state_modify_end().
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_state_modify()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*state_modify_op) (void *cls,
 | 
			
		||||
                      const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                      enum GNUNET_PSYC_Operator op,
 | 
			
		||||
                      const char *name, const void *value, size_t value_size);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * End modifying current state.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_state_modify()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*state_modify_end) (void *cls,
 | 
			
		||||
                       const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                       uint64_t message_id);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Begin synchronizing state.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_state_sync()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*state_sync_begin) (void *cls,
 | 
			
		||||
                         const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Assign value of a state variable while synchronizing state.
 | 
			
		||||
   *
 | 
			
		||||
   * The state synchronization process is started with state_sync_begin(),
 | 
			
		||||
   * which is followed by one or more calls to this function,
 | 
			
		||||
   * and finished using state_sync_end().
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_state_sync()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*state_sync_assign) (void *cls,
 | 
			
		||||
                        const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                        const char *name, const void *value, size_t value_size);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * End synchronizing state.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_state_sync()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*state_sync_end) (void *cls,
 | 
			
		||||
                     const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                     uint64_t max_state_message_id,
 | 
			
		||||
                     uint64_t state_hash_message_id);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Reset the state of a channel.
 | 
			
		||||
   *
 | 
			
		||||
   * Delete all state variables stored for the given channel.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_state_reset()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*state_reset) (void *cls,
 | 
			
		||||
                  const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Update signed state values from the current ones.
 | 
			
		||||
   *
 | 
			
		||||
   * Sets value_signed = value_current for each variable for the given channel.
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*state_update_signed) (void *cls,
 | 
			
		||||
                          const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve a state variable by name (exact match).
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*state_get) (void *cls,
 | 
			
		||||
                const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                const char *name,
 | 
			
		||||
                GNUNET_PSYCSTORE_StateCallback cb,
 | 
			
		||||
                void *cb_cls);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve all state variables for a channel with the given prefix.
 | 
			
		||||
   *
 | 
			
		||||
   * @see GNUNET_PSYCSTORE_state_get_prefix()
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*state_get_prefix) (void *cls,
 | 
			
		||||
                       const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                       const char *name,
 | 
			
		||||
                       GNUNET_PSYCSTORE_StateCallback cb,
 | 
			
		||||
                       void *cb_cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve all signed state variables for a channel.
 | 
			
		||||
   *
 | 
			
		||||
   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
 | 
			
		||||
   */
 | 
			
		||||
  int
 | 
			
		||||
  (*state_get_signed) (void *cls,
 | 
			
		||||
                       const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                       GNUNET_PSYCSTORE_StateCallback cb,
 | 
			
		||||
                       void *cb_cls);
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if 0                           /* keep Emacsens' auto-indent happy */
 | 
			
		||||
{
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** @} */  /* end of group */
 | 
			
		||||
							
								
								
									
										701
									
								
								src/include/gnunet_psycstore_service.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										701
									
								
								src/include/gnunet_psycstore_service.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,701 @@
 | 
			
		||||
/*
 | 
			
		||||
     This file is part of GNUnet.
 | 
			
		||||
     Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 * @author Christian Grothoff
 | 
			
		||||
 *
 | 
			
		||||
 * @file
 | 
			
		||||
 * PSYCstore service; implements persistent storage for the PSYC service
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup psycstore  PSYC Store service
 | 
			
		||||
 * Persistent storage for the PSYC service.
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
#ifndef GNUNET_PSYCSTORE_SERVICE_H
 | 
			
		||||
#define GNUNET_PSYCSTORE_SERVICE_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C"
 | 
			
		||||
{
 | 
			
		||||
#if 0                           /* keep Emacsens' auto-indent happy */
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
#include "gnunet_psyc_util_lib.h"
 | 
			
		||||
#include "gnunet_multicast_service.h"
 | 
			
		||||
#include "gnunet_psyc_service.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Version number of GNUnet PSYCstore API.
 | 
			
		||||
 */
 | 
			
		||||
#define GNUNET_PSYCSTORE_VERSION 0x00000000
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Membership test failed.
 | 
			
		||||
 */
 | 
			
		||||
#define GNUNET_PSYCSTORE_MEMBERSHIP_TEST_FAILED -2
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Flags for stored messages.
 | 
			
		||||
 */
 | 
			
		||||
enum GNUNET_PSYCSTORE_MessageFlags
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * The message contains state modifiers.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_PSYCSTORE_MESSAGE_STATE = 1 << 0,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The state modifiers have been applied to the state store.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED = 1 << 1,
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The message contains a state hash.
 | 
			
		||||
   */
 | 
			
		||||
  GNUNET_PSYCSTORE_MESSAGE_STATE_HASH = 1 << 2
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle for a PSYCstore
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_Handle;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Connect to the PSYCstore service.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cfg Configuration to use.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle for the connecton.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_Handle *
 | 
			
		||||
GNUNET_PSYCSTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Disconnect from the PSYCstore service.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h Handle for the connection.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYCSTORE_disconnect (struct GNUNET_PSYCSTORE_Handle *h);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle for an operation on the PSYCSTORE (useful to cancel the operation).
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function called with the result of an asynchronous operation.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure.
 | 
			
		||||
 * @param result
 | 
			
		||||
 *        Result of the operation.
 | 
			
		||||
 * @param err_msg
 | 
			
		||||
 *        Error message, or NULL if there's no error.
 | 
			
		||||
 * @param err_msg_size
 | 
			
		||||
 *        Size of @a err_msg
 | 
			
		||||
 */
 | 
			
		||||
typedef void
 | 
			
		||||
(*GNUNET_PSYCSTORE_ResultCallback) (void *cls,
 | 
			
		||||
                                    int64_t result,
 | 
			
		||||
                                    const char *err_msg,
 | 
			
		||||
                                    uint16_t err_msg_size);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Store join/leave events for a PSYC channel in order to be able to answer
 | 
			
		||||
 * membership test queries later.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h
 | 
			
		||||
 *        Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key
 | 
			
		||||
 *        The channel where the event happened.
 | 
			
		||||
 * @param slave_key
 | 
			
		||||
 *        Public key of joining/leaving slave.
 | 
			
		||||
 * @param did_join
 | 
			
		||||
 *        #GNUNET_YES on join, #GNUNET_NO on part.
 | 
			
		||||
 * @param announced_at
 | 
			
		||||
 *        ID of the message that announced the membership change.
 | 
			
		||||
 * @param effective_since
 | 
			
		||||
 *        Message ID this membership change is in effect since.
 | 
			
		||||
 *        For joins it is <= announced_at, for parts it is always 0.
 | 
			
		||||
 * @param group_generation
 | 
			
		||||
 *        In case of a part, the last group generation the slave has access to.
 | 
			
		||||
 *        It has relevance when a larger message have fragments with different
 | 
			
		||||
 *        group generations.
 | 
			
		||||
 * @param result_cb
 | 
			
		||||
 *        Callback to call with the result of the storage operation.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the callback.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Operation handle that can be used to cancel the operation.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_membership_store (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                                   const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                                   const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
 | 
			
		||||
                                   int did_join,
 | 
			
		||||
                                   uint64_t announced_at,
 | 
			
		||||
                                   uint64_t effective_since,
 | 
			
		||||
                                   uint64_t group_generation,
 | 
			
		||||
                                   GNUNET_PSYCSTORE_ResultCallback result_cb,
 | 
			
		||||
                                   void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test if a member was admitted to the channel at the given message ID.
 | 
			
		||||
 *
 | 
			
		||||
 * This is useful when relaying and replaying messages to check if a particular
 | 
			
		||||
 * slave has access to the message fragment with a given group generation.  It
 | 
			
		||||
 * is also used when handling join requests to determine whether the slave is
 | 
			
		||||
 * currently admitted to the channel.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h
 | 
			
		||||
 *        Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key
 | 
			
		||||
 *        The channel we are interested in.
 | 
			
		||||
 * @param slave_key
 | 
			
		||||
 *        Public key of slave whose membership to check.
 | 
			
		||||
 * @param message_id
 | 
			
		||||
 *        Message ID for which to do the membership test.
 | 
			
		||||
 * @param group_generation
 | 
			
		||||
 *        Group generation of the fragment of the message to test.
 | 
			
		||||
 *        It has relevance if the message consists of multiple fragments with
 | 
			
		||||
 *        different group generations.
 | 
			
		||||
 * @param result_cb
 | 
			
		||||
 *        Callback to call with the test result.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the callback.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Operation handle that can be used to cancel the operation.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_membership_test (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                                  const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                                  const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
 | 
			
		||||
                                  uint64_t message_id,
 | 
			
		||||
                                  uint64_t group_generation,
 | 
			
		||||
                                  GNUNET_PSYCSTORE_ResultCallback result_cb,
 | 
			
		||||
                                  void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Store a message fragment sent to a channel.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key The channel the message belongs to.
 | 
			
		||||
 * @param msg Message to store.
 | 
			
		||||
 * @param psycstore_flags Flags indicating whether the PSYC message contains
 | 
			
		||||
 *        state modifiers.
 | 
			
		||||
 * @param result_cb Callback to call with the result of the operation.
 | 
			
		||||
 * @param cls Closure for the callback.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle that can be used to cancel the operation.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_fragment_store (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                                 const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                                 const struct GNUNET_MULTICAST_MessageHeader *msg,
 | 
			
		||||
                                 enum GNUNET_PSYCSTORE_MessageFlags psycstore_flags,
 | 
			
		||||
                                 GNUNET_PSYCSTORE_ResultCallback result_cb,
 | 
			
		||||
                                 void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function called with one message fragment, as the result of a
 | 
			
		||||
 * GNUNET_PSYCSTORE_fragment_get() or GNUNET_PSYCSTORE_message_get() call.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls Closure.
 | 
			
		||||
 * @param message The retrieved message fragment.  A NULL value indicates that
 | 
			
		||||
 *        there are no more results to be returned.
 | 
			
		||||
 * @param psycstore_flags Flags stored with the message.
 | 
			
		||||
 *
 | 
			
		||||
 * @return #GNUNET_NO to stop calling this callback with further fragments,
 | 
			
		||||
 *         #GNUNET_YES to continue.
 | 
			
		||||
 */
 | 
			
		||||
typedef int
 | 
			
		||||
(*GNUNET_PSYCSTORE_FragmentCallback) (void *cls,
 | 
			
		||||
                                      struct GNUNET_MULTICAST_MessageHeader *message,
 | 
			
		||||
                                      enum GNUNET_PSYCSTORE_MessageFlags psycstore_flags);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieve message fragments by fragment ID range.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h
 | 
			
		||||
 *        Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key
 | 
			
		||||
 *        The channel we are interested in.
 | 
			
		||||
 * @param slave_key
 | 
			
		||||
 *        The slave requesting the fragment.  If not NULL, a membership test is
 | 
			
		||||
 *        performed first and the fragment is only returned if the slave has
 | 
			
		||||
 *        access to it.
 | 
			
		||||
 * @param first_fragment_id
 | 
			
		||||
 *        First fragment ID to retrieve.
 | 
			
		||||
 *        Use 0 to get the latest message fragment.
 | 
			
		||||
 * @param last_fragment_id
 | 
			
		||||
 *        Last consecutive fragment ID to retrieve.
 | 
			
		||||
 *        Use 0 to get the latest message fragment.
 | 
			
		||||
 * @param fragment_cb
 | 
			
		||||
 *        Callback to call with the retrieved fragments.
 | 
			
		||||
 * @param result_cb
 | 
			
		||||
 *        Callback to call with the result of the operation.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the callbacks.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle that can be used to cancel the operation.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_fragment_get (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                               const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                               const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
 | 
			
		||||
                               uint64_t first_message_id,
 | 
			
		||||
                               uint64_t last_message_id,
 | 
			
		||||
                               GNUNET_PSYCSTORE_FragmentCallback fragment_cb,
 | 
			
		||||
                               GNUNET_PSYCSTORE_ResultCallback result_cb,
 | 
			
		||||
                               void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieve latest message fragments.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h
 | 
			
		||||
 *        Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key
 | 
			
		||||
 *        The channel we are interested in.
 | 
			
		||||
 * @param slave_key
 | 
			
		||||
 *        The slave requesting the fragment.  If not NULL, a membership test is
 | 
			
		||||
 *        performed first and the fragment is only returned if the slave has
 | 
			
		||||
 *        access to it.
 | 
			
		||||
 * @param first_fragment_id
 | 
			
		||||
 *        First fragment ID to retrieve.
 | 
			
		||||
 *        Use 0 to get the latest message fragment.
 | 
			
		||||
 * @param last_fragment_id
 | 
			
		||||
 *        Last consecutive fragment ID to retrieve.
 | 
			
		||||
 *        Use 0 to get the latest message fragment.
 | 
			
		||||
 * @param fragment_limit
 | 
			
		||||
 *        Maximum number of fragments to retrieve.
 | 
			
		||||
 * @param fragment_cb
 | 
			
		||||
 *        Callback to call with the retrieved fragments.
 | 
			
		||||
 * @param result_cb
 | 
			
		||||
 *        Callback to call with the result of the operation.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the callbacks.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle that can be used to cancel the operation.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_fragment_get_latest (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                                      const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                                      const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
 | 
			
		||||
                                      uint64_t fragment_limit,
 | 
			
		||||
                                      GNUNET_PSYCSTORE_FragmentCallback fragment_cb,
 | 
			
		||||
                                      GNUNET_PSYCSTORE_ResultCallback result_cb,
 | 
			
		||||
                                      void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieve all fragments of messages in a message ID range.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h
 | 
			
		||||
 *        Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key
 | 
			
		||||
 *        The channel we are interested in.
 | 
			
		||||
 * @param slave_key
 | 
			
		||||
 *        The slave requesting the message.
 | 
			
		||||
 *        If not NULL, a membership test is performed first
 | 
			
		||||
 *        and the message is only returned if the slave has access to it.
 | 
			
		||||
 * @param first_message_id
 | 
			
		||||
 *        First message ID to retrieve.
 | 
			
		||||
 * @param last_message_id
 | 
			
		||||
 *        Last consecutive message ID to retrieve.
 | 
			
		||||
 * @param fragment_limit
 | 
			
		||||
 *        Maximum number of fragments to retrieve.
 | 
			
		||||
 * @param method_prefix
 | 
			
		||||
 *        Retrieve only messages with a matching method prefix.
 | 
			
		||||
 * @param fragment_cb
 | 
			
		||||
 *        Callback to call with the retrieved fragments.
 | 
			
		||||
 * @param result_cb
 | 
			
		||||
 *        Callback to call with the result of the operation.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the callbacks.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle that can be used to cancel the operation.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_message_get (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                              const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                              const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
 | 
			
		||||
                              uint64_t first_message_id,
 | 
			
		||||
                              uint64_t last_message_id,
 | 
			
		||||
                              uint64_t fragment_limit,
 | 
			
		||||
                              const char *method_prefix,
 | 
			
		||||
                              GNUNET_PSYCSTORE_FragmentCallback fragment_cb,
 | 
			
		||||
                              GNUNET_PSYCSTORE_ResultCallback result_cb,
 | 
			
		||||
                              void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieve all fragments of the latest messages.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h
 | 
			
		||||
 *        Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key
 | 
			
		||||
 *        The channel we are interested in.
 | 
			
		||||
 * @param slave_key
 | 
			
		||||
 *        The slave requesting the message.
 | 
			
		||||
 *        If not NULL, a membership test is performed first
 | 
			
		||||
 *        and the message is only returned if the slave has access to it.
 | 
			
		||||
 * @param message_limit
 | 
			
		||||
 *        Maximum number of messages to retrieve.
 | 
			
		||||
 * @param method_prefix
 | 
			
		||||
 *        Retrieve only messages with a matching method prefix.
 | 
			
		||||
 * @param fragment_cb
 | 
			
		||||
 *        Callback to call with the retrieved fragments.
 | 
			
		||||
 * @param result_cb
 | 
			
		||||
 *        Callback to call with the result of the operation.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the callbacks.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle that can be used to cancel the operation.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_message_get_latest (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                                     const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                                     const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
 | 
			
		||||
                                     uint64_t message_limit,
 | 
			
		||||
                                     const char *method_prefix,
 | 
			
		||||
                                     GNUNET_PSYCSTORE_FragmentCallback fragment_cb,
 | 
			
		||||
                                     GNUNET_PSYCSTORE_ResultCallback result_cb,
 | 
			
		||||
                                     void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieve a fragment of message specified by its message ID and fragment
 | 
			
		||||
 * offset.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h
 | 
			
		||||
 *        Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key
 | 
			
		||||
 *        The channel we are interested in.
 | 
			
		||||
 * @param slave_key
 | 
			
		||||
 *        The slave requesting the message fragment.  If not NULL, a membership
 | 
			
		||||
 *        test is performed first and the message fragment is only returned
 | 
			
		||||
 *        if the slave has access to it.
 | 
			
		||||
 * @param message_id
 | 
			
		||||
 *        Message ID to retrieve.  Use 0 to get the latest message.
 | 
			
		||||
 * @param fragment_offset
 | 
			
		||||
 *        Offset of the fragment to retrieve.
 | 
			
		||||
 * @param fragment_cb
 | 
			
		||||
 *        Callback to call with the retrieved fragments.
 | 
			
		||||
 * @param result_cb
 | 
			
		||||
 *        Callback to call with the result of the operation.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the callbacks.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle that can be used to cancel the operation.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_message_get_fragment (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                                       const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                                       const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
 | 
			
		||||
                                       uint64_t message_id,
 | 
			
		||||
                                       uint64_t fragment_offset,
 | 
			
		||||
                                       GNUNET_PSYCSTORE_FragmentCallback fragment_cb,
 | 
			
		||||
                                       GNUNET_PSYCSTORE_ResultCallback result_cb,
 | 
			
		||||
                                       void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Callback used to return the latest value of counters for the channel master.
 | 
			
		||||
 *
 | 
			
		||||
 * @see GNUNET_PSYCSTORE_counters_get()
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls Closure.
 | 
			
		||||
 * @param result_code
 | 
			
		||||
 *        Status code for the operation:
 | 
			
		||||
 *        #GNUNET_OK: success, counter values are returned.
 | 
			
		||||
 *        #GNUNET_NO: no message has been sent to the channel yet.
 | 
			
		||||
 *        #GNUNET_SYSERR: an error occurred.
 | 
			
		||||
 * @param max_fragment_id
 | 
			
		||||
 *        Latest message fragment ID, used by multicast.
 | 
			
		||||
 * @param max_message_id
 | 
			
		||||
 *        Latest message ID, used by PSYC.
 | 
			
		||||
 * @param max_group_generation
 | 
			
		||||
 *        Latest group generation, used by PSYC.
 | 
			
		||||
 * @param max_state_message_id
 | 
			
		||||
 *        Latest message ID containing state modifiers that
 | 
			
		||||
 *        was applied to the state store.  Used for the state sync process.
 | 
			
		||||
 */
 | 
			
		||||
typedef void
 | 
			
		||||
(*GNUNET_PSYCSTORE_CountersCallback) (void *cls,
 | 
			
		||||
                                      int result_code,
 | 
			
		||||
                                      uint64_t max_fragment_id,
 | 
			
		||||
                                      uint64_t max_message_id,
 | 
			
		||||
                                      uint64_t max_group_generation,
 | 
			
		||||
                                      uint64_t max_state_message_id);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieve latest values of counters for a channel.
 | 
			
		||||
 *
 | 
			
		||||
 * The current value of counters are needed
 | 
			
		||||
 * - when a channel master is restarted, so that it can continue incrementing
 | 
			
		||||
 *   the counters from their last value.
 | 
			
		||||
 * - when a channel slave rejoins and starts the state synchronization process.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h
 | 
			
		||||
 *        Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key
 | 
			
		||||
 *        Public key that identifies the channel.
 | 
			
		||||
 * @param counters_cb
 | 
			
		||||
 *        Callback to call with the result.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the @a ccb callback.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle that can be used to cancel the operation.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_counters_get (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                               struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                               GNUNET_PSYCSTORE_CountersCallback counters_cb,
 | 
			
		||||
                               void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Apply modifiers of a message to the current channel state.
 | 
			
		||||
 *
 | 
			
		||||
 * An error is returned if there are missing messages containing state
 | 
			
		||||
 * operations before the current one.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h
 | 
			
		||||
 *        Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key
 | 
			
		||||
 *        The channel we are interested in.
 | 
			
		||||
 * @param message_id
 | 
			
		||||
 *        ID of the message that contains the @a modifiers.
 | 
			
		||||
 * @param state_delta
 | 
			
		||||
 *        Value of the @e state_delta PSYC header variable of the message.
 | 
			
		||||
 * @param result_cb
 | 
			
		||||
 *        Callback to call with the result of the operation.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the @a result_cb callback.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle that can be used to cancel the operation.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_state_modify (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                               const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                               uint64_t message_id,
 | 
			
		||||
                               uint64_t state_delta,
 | 
			
		||||
                               GNUNET_PSYCSTORE_ResultCallback result_cb,
 | 
			
		||||
                               void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Store synchronized state.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h
 | 
			
		||||
 *        Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key
 | 
			
		||||
 *        The channel we are interested in.
 | 
			
		||||
 * @param max_state_message_id
 | 
			
		||||
 *        ID of the last stateful message before @a state_hash_message_id.
 | 
			
		||||
 * @param state_hash_message_id
 | 
			
		||||
 *        ID of the message that contains the state_hash PSYC header variable.
 | 
			
		||||
 * @param modifier_count
 | 
			
		||||
 *        Number of elements in the @a modifiers array.
 | 
			
		||||
 * @param modifiers
 | 
			
		||||
 *        Full state to store.
 | 
			
		||||
 * @param result_cb
 | 
			
		||||
 *        Callback to call with the result of the operation.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the callback.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle that can be used to cancel the operation.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_state_sync (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                             const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                             uint64_t max_state_message_id,
 | 
			
		||||
                             uint64_t state_hash_message_id,
 | 
			
		||||
                             size_t modifier_count,
 | 
			
		||||
                             const struct GNUNET_PSYC_Modifier *modifiers,
 | 
			
		||||
                             GNUNET_PSYCSTORE_ResultCallback result_cb,
 | 
			
		||||
                             void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reset the state of a channel.
 | 
			
		||||
 *
 | 
			
		||||
 * Delete all state variables stored for the given channel.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h
 | 
			
		||||
 *        Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key
 | 
			
		||||
 *        The channel we are interested in.
 | 
			
		||||
 * @param result_cb
 | 
			
		||||
 *        Callback to call with the result of the operation.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the callback.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle that can be used to cancel the operation.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_state_reset (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                              const struct GNUNET_CRYPTO_EddsaPublicKey
 | 
			
		||||
                              *channel_key,
 | 
			
		||||
                              GNUNET_PSYCSTORE_ResultCallback result_cb,
 | 
			
		||||
                              void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Update signed values of state variables in the state store.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h
 | 
			
		||||
 *        Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key
 | 
			
		||||
 *        The channel we are interested in.
 | 
			
		||||
 * @param message_id
 | 
			
		||||
 *        Message ID that contained the state @a hash.
 | 
			
		||||
 * @param hash
 | 
			
		||||
 *        Hash of the serialized full state.
 | 
			
		||||
 * @param result_cb
 | 
			
		||||
 *        Callback to call with the result of the operation.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the callback.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_state_hash_update (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                                    const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                                    uint64_t message_id,
 | 
			
		||||
                                    const struct GNUNET_HashCode *hash,
 | 
			
		||||
                                    GNUNET_PSYCSTORE_ResultCallback result_cb,
 | 
			
		||||
                                    void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function called with the value of a state variable.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure.
 | 
			
		||||
 * @param name
 | 
			
		||||
 *        Name of the state variable.  A NULL value indicates that there are no more
 | 
			
		||||
 *        state variables to be returned.
 | 
			
		||||
 * @param value
 | 
			
		||||
 *        Value of the state variable.
 | 
			
		||||
 * @param value_size
 | 
			
		||||
 *        Number of bytes in @a value.
 | 
			
		||||
 *
 | 
			
		||||
 * @return #GNUNET_NO to stop calling this callback with further variables,
 | 
			
		||||
 *         #GNUNET_YES to continue.
 | 
			
		||||
 */;
 | 
			
		||||
typedef int
 | 
			
		||||
(*GNUNET_PSYCSTORE_StateCallback) (void *cls, const char *name,
 | 
			
		||||
                                   const void *value, uint32_t value_size);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieve the best matching state variable.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h
 | 
			
		||||
 *        Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key
 | 
			
		||||
 *        The channel we are interested in.
 | 
			
		||||
 * @param name
 | 
			
		||||
 *        Name of variable to match, the returned variable might be less specific.
 | 
			
		||||
 * @param state_cb
 | 
			
		||||
 *        Callback to return the matching state variable.
 | 
			
		||||
 * @param result_cb
 | 
			
		||||
 *        Callback to call with the result of the operation.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the callbacks.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle that can be used to cancel the operation.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_state_get (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                            const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                            const char *name,
 | 
			
		||||
                            GNUNET_PSYCSTORE_StateCallback state_cb,
 | 
			
		||||
                            GNUNET_PSYCSTORE_ResultCallback result_cb,
 | 
			
		||||
                            void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieve all state variables for a channel with the given prefix.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h
 | 
			
		||||
 *        Handle for the PSYCstore.
 | 
			
		||||
 * @param channel_key
 | 
			
		||||
 *        The channel we are interested in.
 | 
			
		||||
 * @param name_prefix
 | 
			
		||||
 *        Prefix of state variable names to match.
 | 
			
		||||
 * @param state_cb
 | 
			
		||||
 *        Callback to return matching state variables.
 | 
			
		||||
 * @param result_cb
 | 
			
		||||
 *        Callback to call with the result of the operation.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the callbacks.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Handle that can be used to cancel the operation.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYCSTORE_OperationHandle *
 | 
			
		||||
GNUNET_PSYCSTORE_state_get_prefix (struct GNUNET_PSYCSTORE_Handle *h,
 | 
			
		||||
                                   const struct GNUNET_CRYPTO_EddsaPublicKey *channel_key,
 | 
			
		||||
                                   const char *name_prefix,
 | 
			
		||||
                                   GNUNET_PSYCSTORE_StateCallback state_cb,
 | 
			
		||||
                                   GNUNET_PSYCSTORE_ResultCallback result_cb,
 | 
			
		||||
                                   void *cls);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Cancel an operation.
 | 
			
		||||
 *
 | 
			
		||||
 * @param op Handle for the operation to cancel.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYCSTORE_operation_cancel (struct GNUNET_PSYCSTORE_OperationHandle *op);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if 0                           /* keep Emacsens' auto-indent happy */
 | 
			
		||||
{
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* ifndef GNUNET_PSYCSTORE_SERVICE_H */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** @} */  /* end of group */
 | 
			
		||||
							
								
								
									
										1344
									
								
								src/include/gnunet_social_service.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1344
									
								
								src/include/gnunet_social_service.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										7
									
								
								src/multicast/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/multicast/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
gnunet-service-multicast
 | 
			
		||||
gnunet-multicast
 | 
			
		||||
test_multicast 
 | 
			
		||||
test_multicast_multipeer
 | 
			
		||||
test_multicast_2peers
 | 
			
		||||
test_multicast_multipeer_line
 | 
			
		||||
test_multicast_multipeer_star
 | 
			
		||||
							
								
								
									
										79
									
								
								src/multicast/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/multicast/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,79 @@
 | 
			
		||||
# This Makefile.am is in the public domain
 | 
			
		||||
AM_CPPFLAGS = -I$(top_srcdir)/src/include
 | 
			
		||||
 | 
			
		||||
pkgcfgdir= $(pkgdatadir)/config.d/
 | 
			
		||||
 | 
			
		||||
libexecdir= $(pkglibdir)/libexec/
 | 
			
		||||
 | 
			
		||||
pkgcfg_DATA = \
 | 
			
		||||
  multicast.conf
 | 
			
		||||
 | 
			
		||||
if MINGW
 | 
			
		||||
 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if USE_COVERAGE
 | 
			
		||||
  AM_CFLAGS = -fprofile-arcs -ftest-coverage
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
lib_LTLIBRARIES = libgnunetmulticast.la
 | 
			
		||||
 | 
			
		||||
libgnunetmulticast_la_SOURCES = \
 | 
			
		||||
  multicast_api.c multicast.h
 | 
			
		||||
libgnunetmulticast_la_LIBADD = \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la \
 | 
			
		||||
  $(GN_LIBINTL) $(XLIB)
 | 
			
		||||
libgnunetmulticast_la_LDFLAGS = \
 | 
			
		||||
  $(GN_LIB_LDFLAGS)  $(WINFLAGS) \
 | 
			
		||||
  -version-info 0:0:0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bin_PROGRAMS = \
 | 
			
		||||
 gnunet-multicast
 | 
			
		||||
 | 
			
		||||
libexec_PROGRAMS = \
 | 
			
		||||
 gnunet-service-multicast \
 | 
			
		||||
 $(EXP_LIBEXEC)
 | 
			
		||||
 | 
			
		||||
gnunet_multicast_SOURCES = \
 | 
			
		||||
 gnunet-multicast.c
 | 
			
		||||
gnunet_multicast_LDADD = \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la \
 | 
			
		||||
  $(GN_LIBINTL)
 | 
			
		||||
 | 
			
		||||
gnunet_service_multicast_SOURCES = \
 | 
			
		||||
 gnunet-service-multicast.c
 | 
			
		||||
gnunet_service_multicast_LDADD = \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la \
 | 
			
		||||
  $(top_builddir)/src/cadet/libgnunetcadet.la \
 | 
			
		||||
  $(top_builddir)/src/statistics/libgnunetstatistics.la \
 | 
			
		||||
  $(GN_LIBINTL)
 | 
			
		||||
 | 
			
		||||
check_PROGRAMS = \
 | 
			
		||||
  test_multicast \
 | 
			
		||||
  test_multicast_multipeer_star \
 | 
			
		||||
  test_multicast_multipeer_line
 | 
			
		||||
 | 
			
		||||
if ENABLE_TEST_RUN
 | 
			
		||||
AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@}; export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; unset XDG_DATA_HOME; unset XDG_CONFIG_HOME;
 | 
			
		||||
TESTS = $(check_PROGRAMS)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
test_multicast_SOURCES = \
 | 
			
		||||
 test_multicast.c
 | 
			
		||||
test_multicast_LDADD = \
 | 
			
		||||
  libgnunetmulticast.la \
 | 
			
		||||
  $(top_builddir)/src/testing/libgnunettesting.la \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la
 | 
			
		||||
test_multicast_multipeer_star_SOURCES = \
 | 
			
		||||
  test_multicast_multipeer.c
 | 
			
		||||
test_multicast_multipeer_star_LDADD = \
 | 
			
		||||
  libgnunetmulticast.la \
 | 
			
		||||
  $(top_builddir)/src/testbed/libgnunettestbed.la \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la
 | 
			
		||||
test_multicast_multipeer_line_SOURCES = \
 | 
			
		||||
  test_multicast_multipeer.c
 | 
			
		||||
test_multicast_multipeer_line_LDADD = \
 | 
			
		||||
  libgnunetmulticast.la \
 | 
			
		||||
  $(top_builddir)/src/testbed/libgnunettestbed.la \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la
 | 
			
		||||
							
								
								
									
										79
									
								
								src/multicast/gnunet-multicast.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/multicast/gnunet-multicast.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,79 @@
 | 
			
		||||
/*
 | 
			
		||||
     This file is part of GNUnet.
 | 
			
		||||
     Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file multicast/gnunet-multicast.c
 | 
			
		||||
 * @brief multicast for writing a tool
 | 
			
		||||
 * @author Christian Grothoff
 | 
			
		||||
 */
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
/* #include "gnunet_multicast_service.h" */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Final status code.
 | 
			
		||||
 */
 | 
			
		||||
static int 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 cfg configuration
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
run (void *cls, char *const *args, const char *cfgfile,
 | 
			
		||||
     const struct GNUNET_CONFIGURATION_Handle *cfg)
 | 
			
		||||
{
 | 
			
		||||
  /* main code here */
 | 
			
		||||
  puts( gettext_noop ("This command doesn't do anything yet.") );
 | 
			
		||||
  ret = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The main function.
 | 
			
		||||
 *
 | 
			
		||||
 * @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)
 | 
			
		||||
{
 | 
			
		||||
  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
 | 
			
		||||
    /* FIMXE: add options here */
 | 
			
		||||
    GNUNET_GETOPT_OPTION_END
 | 
			
		||||
  };
 | 
			
		||||
  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
 | 
			
		||||
    return 2;
 | 
			
		||||
 | 
			
		||||
  ret = (GNUNET_OK ==
 | 
			
		||||
	 GNUNET_PROGRAM_run (argc, argv, "gnunet-multicast",
 | 
			
		||||
			     gettext_noop ("This command doesn't do anything yet."),
 | 
			
		||||
			     options, &run,
 | 
			
		||||
			     NULL)) ? ret : 1;
 | 
			
		||||
  GNUNET_free ((void*) argv);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* end of gnunet-multicast.c */
 | 
			
		||||
							
								
								
									
										2234
									
								
								src/multicast/gnunet-service-multicast.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2234
									
								
								src/multicast/gnunet-service-multicast.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										22
									
								
								src/multicast/multicast.conf.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/multicast/multicast.conf.in
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
[multicast]
 | 
			
		||||
START_ON_DEMAND = @START_ON_DEMAND@
 | 
			
		||||
BINARY = gnunet-service-multicast
 | 
			
		||||
 | 
			
		||||
UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-multicast.sock
 | 
			
		||||
UNIX_MATCH_UID = YES
 | 
			
		||||
UNIX_MATCH_GID = YES
 | 
			
		||||
 | 
			
		||||
@UNIXONLY@PORT = 2109
 | 
			
		||||
HOSTNAME = localhost
 | 
			
		||||
ACCEPT_FROM = 127.0.0.1;
 | 
			
		||||
ACCEPT_FROM6 = ::1;
 | 
			
		||||
 | 
			
		||||
# DISABLE_SOCKET_FORWARDING = NO
 | 
			
		||||
# USERNAME = 
 | 
			
		||||
# MAXBUF =
 | 
			
		||||
# TIMEOUT =
 | 
			
		||||
# DISABLEV6 =
 | 
			
		||||
# BINDTO =
 | 
			
		||||
# REJECT_FROM =
 | 
			
		||||
# REJECT_FROM6 =
 | 
			
		||||
# PREFIX =
 | 
			
		||||
							
								
								
									
										303
									
								
								src/multicast/multicast.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										303
									
								
								src/multicast/multicast.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,303 @@
 | 
			
		||||
/*
 | 
			
		||||
     This file is part of GNUnet.
 | 
			
		||||
     Copyright (C) 2012, 2013 GNUnet e.V.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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.
 | 
			
		||||
 | 
			
		||||
     GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file multicast/multicast.h
 | 
			
		||||
 * @brief multicast IPC messages
 | 
			
		||||
 * @author Christian Grothoff
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 */
 | 
			
		||||
#ifndef MULTICAST_H
 | 
			
		||||
#define MULTICAST_H
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "gnunet_multicast_service.h"
 | 
			
		||||
 | 
			
		||||
GNUNET_NETWORK_STRUCT_BEGIN
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Header of a join request sent to the origin or another member.
 | 
			
		||||
 */
 | 
			
		||||
struct MulticastJoinRequestMessage
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_REQUEST
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Always zero.
 | 
			
		||||
   */
 | 
			
		||||
  uint32_t reserved;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ECC signature of the rest of the fields of the join request.
 | 
			
		||||
   *
 | 
			
		||||
   * Signature must match the public key of the joining member.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaSignature signature;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Purpose for the signature and size of the signed data.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Public key of the target group.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPublicKey group_pub_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Public key of the joining member.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaPublicKey member_pub_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Peer identity of the joining member.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_PeerIdentity peer;
 | 
			
		||||
 | 
			
		||||
  /* Followed by struct GNUNET_MessageHeader join_message */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Header of a join decision message sent to a peer requesting join.
 | 
			
		||||
 */
 | 
			
		||||
struct MulticastJoinDecisionMessage
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * #GNUNET_YES    if the peer was admitted
 | 
			
		||||
   * #GNUNET_NO     if entry was refused,
 | 
			
		||||
   * #GNUNET_SYSERR if the request could not be answered.
 | 
			
		||||
   */
 | 
			
		||||
  int32_t is_admitted;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Number of relays given.
 | 
			
		||||
   */
 | 
			
		||||
  uint32_t relay_count;
 | 
			
		||||
 | 
			
		||||
  /* Followed by relay_count peer identities */
 | 
			
		||||
 | 
			
		||||
  /* Followed by the join response message */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Header added to a struct MulticastJoinDecisionMessage
 | 
			
		||||
 * when sent between the client and service.
 | 
			
		||||
 */
 | 
			
		||||
struct MulticastJoinDecisionMessageHeader
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_MULTICAST_JOIN_DECISION
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * C->S: Peer to send the join decision to.
 | 
			
		||||
   * S->C: Peer we received the join decision from.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_PeerIdentity peer;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * C->S: Public key of the member requesting join.
 | 
			
		||||
   * S->C: Unused.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaPublicKey member_pub_key;
 | 
			
		||||
 | 
			
		||||
  /* Followed by struct MulticastJoinDecisionMessage */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Message sent from the client to the service to notify the service
 | 
			
		||||
 * about the result of a membership test.
 | 
			
		||||
 */
 | 
			
		||||
struct MulticastMembershipTestResultMessage
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_MULTICAST_MEMBERSHIP_TEST_RESULT
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Unique ID that identifies the associated membership test.
 | 
			
		||||
   */
 | 
			
		||||
  uint32_t uid;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * #GNUNET_YES    if the peer is a member
 | 
			
		||||
   * #GNUNET_NO     if peer is not a member,
 | 
			
		||||
   * #GNUNET_SYSERR if the test could not be answered.
 | 
			
		||||
   */
 | 
			
		||||
  int32_t is_admitted;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Message sent from the client to the service OR the service to the
 | 
			
		||||
 * client asking for a message fragment to be replayed.
 | 
			
		||||
 */
 | 
			
		||||
struct MulticastReplayRequestMessage
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The message type should be
 | 
			
		||||
   * #GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_REQUEST.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * S->C: Public key of the member requesting replay.
 | 
			
		||||
   * C->S: Unused.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaPublicKey member_pub_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ID of the message that is being requested.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t fragment_id;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ID of the message that is being requested.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t message_id;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Offset of the fragment that is being requested.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t fragment_offset;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Additional flags for the request.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t flags;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Replay request ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint32_t uid;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Message sent from the client to the service to give the service
 | 
			
		||||
 * a replayed message.
 | 
			
		||||
 */
 | 
			
		||||
struct MulticastReplayResponseMessage
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE
 | 
			
		||||
   *    or GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE_END
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ID of the message that is being requested.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t fragment_id;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ID of the message that is being requested.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t message_id;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Offset of the fragment that is being requested.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t fragment_offset;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Additional flags for the request.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t flags;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * An `enum GNUNET_MULTICAST_ReplayErrorCode` identifying issues (in NBO).
 | 
			
		||||
   */
 | 
			
		||||
  int32_t error_code;
 | 
			
		||||
 | 
			
		||||
  /* followed by replayed message */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Message sent from the client to the service to notify the service
 | 
			
		||||
 * about the starting of a multicast group with this peers as its origin.
 | 
			
		||||
 */
 | 
			
		||||
struct MulticastOriginStartMessage
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_MULTICAST_ORIGIN_START
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Always zero.
 | 
			
		||||
   */
 | 
			
		||||
  uint32_t reserved;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Private, non-ephemeral key for the multicast group.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPrivateKey group_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Last fragment ID sent to the group, used to continue counting fragments if
 | 
			
		||||
   * we resume operating * a group.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t max_fragment_id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct MulticastMemberJoinMessage
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_MULTICAST_MEMBER_JOIN
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t relay_count GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPublicKey group_pub_key;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaPrivateKey member_key;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_PeerIdentity origin;
 | 
			
		||||
 | 
			
		||||
  /* Followed by struct GNUNET_PeerIdentity relays[relay_count] */
 | 
			
		||||
 | 
			
		||||
  /* Followed by struct GNUNET_MessageHeader join_msg */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GNUNET_NETWORK_STRUCT_END
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
/* end of multicast.h */
 | 
			
		||||
							
								
								
									
										1399
									
								
								src/multicast/multicast_api.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1399
									
								
								src/multicast/multicast_api.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										758
									
								
								src/multicast/test_multicast.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										758
									
								
								src/multicast/test_multicast.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,758 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of GNUnet
 | 
			
		||||
 * Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file multicast/test_multicast.c
 | 
			
		||||
 * @brief Tests for the Multicast API.
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "gnunet_crypto_lib.h"
 | 
			
		||||
#include "gnunet_common.h"
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
#include "gnunet_testing_lib.h"
 | 
			
		||||
#include "gnunet_multicast_service.h"
 | 
			
		||||
 | 
			
		||||
#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return value from 'main'.
 | 
			
		||||
 */
 | 
			
		||||
static int res;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle for task for timeout termination.
 | 
			
		||||
 */
 | 
			
		||||
static struct GNUNET_SCHEDULER_Task * end_badly_task;
 | 
			
		||||
 | 
			
		||||
static const struct GNUNET_CONFIGURATION_Handle *cfg;
 | 
			
		||||
 | 
			
		||||
struct GNUNET_PeerIdentity this_peer;
 | 
			
		||||
 | 
			
		||||
struct GNUNET_MULTICAST_Origin *origin;
 | 
			
		||||
struct GNUNET_MULTICAST_Member *member;
 | 
			
		||||
 | 
			
		||||
struct GNUNET_CRYPTO_EddsaPrivateKey *group_key;
 | 
			
		||||
struct GNUNET_CRYPTO_EddsaPublicKey group_pub_key;
 | 
			
		||||
 | 
			
		||||
struct GNUNET_CRYPTO_EcdsaPrivateKey *member_key;
 | 
			
		||||
struct GNUNET_CRYPTO_EcdsaPublicKey member_pub_key;
 | 
			
		||||
 | 
			
		||||
struct TransmitClosure {
 | 
			
		||||
  struct GNUNET_MULTICAST_OriginTransmitHandle *orig_tmit;
 | 
			
		||||
  struct GNUNET_MULTICAST_MemberTransmitHandle *mem_tmit;
 | 
			
		||||
  char * data[16];
 | 
			
		||||
  uint8_t data_delay[16];
 | 
			
		||||
  uint8_t data_count;
 | 
			
		||||
  uint8_t paused;
 | 
			
		||||
  uint8_t n;
 | 
			
		||||
} tmit_cls;
 | 
			
		||||
 | 
			
		||||
struct OriginClosure {
 | 
			
		||||
  uint8_t msgs_expected;
 | 
			
		||||
  uint8_t n;
 | 
			
		||||
} origin_cls;
 | 
			
		||||
 | 
			
		||||
struct MemberClosure {
 | 
			
		||||
  uint8_t msgs_expected;
 | 
			
		||||
  size_t n;
 | 
			
		||||
} member_cls;
 | 
			
		||||
 | 
			
		||||
struct GNUNET_MessageHeader *join_req, *join_resp;
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  TEST_NONE                = 0,
 | 
			
		||||
  TEST_ORIGIN_START        = 1,
 | 
			
		||||
  TEST_MEMBER_JOIN_REFUSE  = 2,
 | 
			
		||||
  TEST_MEMBER_JOIN_ADMIT   = 3,
 | 
			
		||||
  TEST_ORIGIN_TO_ALL       = 4,
 | 
			
		||||
  TEST_ORIGIN_TO_ALL_RECV  = 5,
 | 
			
		||||
  TEST_MEMBER_TO_ORIGIN    = 6,
 | 
			
		||||
  TEST_MEMBER_REPLAY_ERROR = 7,
 | 
			
		||||
  TEST_MEMBER_REPLAY_OK    = 8,
 | 
			
		||||
  TEST_MEMBER_PART         = 9,
 | 
			
		||||
  TEST_ORIGIN_STOP        = 10,
 | 
			
		||||
} test;
 | 
			
		||||
 | 
			
		||||
uint64_t replay_fragment_id;
 | 
			
		||||
uint64_t replay_flags;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_join (int t);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Clean up all resources used.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
cleanup ()
 | 
			
		||||
{
 | 
			
		||||
  if (NULL != member)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_MULTICAST_member_part (member, NULL, NULL);
 | 
			
		||||
    member = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  if (NULL != origin)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_MULTICAST_origin_stop (origin, NULL, NULL);
 | 
			
		||||
    origin = NULL;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Terminate the test case (failure).
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls NULL
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
end_badly (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  res = 1;
 | 
			
		||||
  cleanup ();
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Test FAILED.\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Terminate the test case (success).
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls NULL
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
end_normally (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  res = 0;
 | 
			
		||||
  cleanup ();
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test PASSED.\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Finish the test case (successfully).
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
end ()
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending tests.\n");
 | 
			
		||||
 | 
			
		||||
  if (end_badly_task != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_SCHEDULER_cancel (end_badly_task);
 | 
			
		||||
    end_badly_task = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
 | 
			
		||||
				&end_normally, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
tmit_resume (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission resumed.\n");
 | 
			
		||||
  struct TransmitClosure *tmit = cls;
 | 
			
		||||
  if (NULL != tmit->orig_tmit)
 | 
			
		||||
    GNUNET_MULTICAST_origin_to_all_resume (tmit->orig_tmit);
 | 
			
		||||
  else if (NULL != tmit->mem_tmit)
 | 
			
		||||
    GNUNET_MULTICAST_member_to_origin_resume (tmit->mem_tmit);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
tmit_notify (void *cls, size_t *data_size, void *data)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
 | 
			
		||||
              "Test #%u: origin_tmit_notify()\n", test);
 | 
			
		||||
  struct TransmitClosure *tmit = cls;
 | 
			
		||||
 | 
			
		||||
  if (0 == tmit->data_count)
 | 
			
		||||
  {
 | 
			
		||||
    *data_size = 0;
 | 
			
		||||
    return GNUNET_YES;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  uint16_t size = strlen (tmit->data[tmit->n]);
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
 | 
			
		||||
              "Transmit notify data: %u bytes available, processing fragment %u/%u (size %u).\n",
 | 
			
		||||
              (unsigned int) *data_size,
 | 
			
		||||
              tmit->n + 1,
 | 
			
		||||
              tmit->data_count,
 | 
			
		||||
              size);
 | 
			
		||||
  if (*data_size < size)
 | 
			
		||||
  {
 | 
			
		||||
    *data_size = 0;
 | 
			
		||||
    GNUNET_assert (0);
 | 
			
		||||
    return GNUNET_SYSERR;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (GNUNET_YES != tmit->paused && 0 < tmit->data_delay[tmit->n])
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission paused.\n");
 | 
			
		||||
    tmit->paused = GNUNET_YES;
 | 
			
		||||
    GNUNET_SCHEDULER_add_delayed (
 | 
			
		||||
      GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
 | 
			
		||||
                                     tmit->data_delay[tmit->n]),
 | 
			
		||||
      tmit_resume, tmit);
 | 
			
		||||
    *data_size = 0;
 | 
			
		||||
    return GNUNET_NO;
 | 
			
		||||
  }
 | 
			
		||||
  tmit->paused = GNUNET_NO;
 | 
			
		||||
 | 
			
		||||
  *data_size = size;
 | 
			
		||||
  GNUNET_memcpy (data, tmit->data[tmit->n], size);
 | 
			
		||||
 | 
			
		||||
  return ++tmit->n < tmit->data_count ? GNUNET_NO : GNUNET_YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_recv_join_request (void *cls,
 | 
			
		||||
                          const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
 | 
			
		||||
                          const struct GNUNET_MessageHeader *join_msg,
 | 
			
		||||
                          struct GNUNET_MULTICAST_JoinHandle *jh)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: member_recv_join_request()\n", test);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_stopped (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: origin_stopped()\n", test);
 | 
			
		||||
  end ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
schedule_origin_stop (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  test = TEST_ORIGIN_STOP;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: origin_stop()\n", test);
 | 
			
		||||
  GNUNET_MULTICAST_origin_stop (origin, origin_stopped, NULL);
 | 
			
		||||
  origin = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_parted (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: member_parted()\n", test);
 | 
			
		||||
  member = NULL;
 | 
			
		||||
 | 
			
		||||
  switch (test)
 | 
			
		||||
  {
 | 
			
		||||
  case TEST_MEMBER_JOIN_REFUSE:
 | 
			
		||||
    // Test 3 starts here
 | 
			
		||||
    member_join (TEST_MEMBER_JOIN_ADMIT);
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case TEST_MEMBER_PART:
 | 
			
		||||
    GNUNET_SCHEDULER_add_now (&schedule_origin_stop, NULL);
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  default:
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
 | 
			
		||||
                "Invalid test #%d in member_parted()\n", test);
 | 
			
		||||
    GNUNET_assert (0);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
schedule_member_part (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: schedule_member_part()\n", test);
 | 
			
		||||
  GNUNET_MULTICAST_member_part (member, member_parted, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_part ()
 | 
			
		||||
{
 | 
			
		||||
  test = TEST_MEMBER_PART;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: member_part()\n", test);
 | 
			
		||||
  // Test 10 starts here
 | 
			
		||||
  GNUNET_SCHEDULER_add_now (&schedule_member_part, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_replay_ok ()
 | 
			
		||||
{
 | 
			
		||||
  // Execution of test 8 here
 | 
			
		||||
  test = TEST_MEMBER_REPLAY_OK;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: member_replay_ok()\n", test);
 | 
			
		||||
  replay_fragment_id = 1;
 | 
			
		||||
  replay_flags = 1 | 1<<11;
 | 
			
		||||
  GNUNET_MULTICAST_member_replay_fragment (member, replay_fragment_id,
 | 
			
		||||
                                           replay_flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_replay_error ()
 | 
			
		||||
{
 | 
			
		||||
  test = TEST_MEMBER_REPLAY_ERROR;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: member_replay_error()\n", test);
 | 
			
		||||
  replay_fragment_id = 1234;
 | 
			
		||||
  replay_flags = 11 | 1<<11;
 | 
			
		||||
  GNUNET_MULTICAST_member_replay_fragment (member, replay_fragment_id,
 | 
			
		||||
                                           replay_flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_recv_replay_msg (void *cls,
 | 
			
		||||
                        const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
 | 
			
		||||
                        uint64_t message_id,
 | 
			
		||||
                        uint64_t fragment_offset,
 | 
			
		||||
                        uint64_t flags,
 | 
			
		||||
                        struct GNUNET_MULTICAST_ReplayHandle *rh)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: origin_recv_replay_msg()\n", test);
 | 
			
		||||
  GNUNET_assert (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_recv_replay_msg (void *cls,
 | 
			
		||||
                        const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
 | 
			
		||||
                        uint64_t message_id,
 | 
			
		||||
                        uint64_t fragment_offset,
 | 
			
		||||
                        uint64_t flags,
 | 
			
		||||
                        struct GNUNET_MULTICAST_ReplayHandle *rh)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: member_recv_replay_msg()\n", test);
 | 
			
		||||
  GNUNET_assert (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_recv_replay_frag (void *cls,
 | 
			
		||||
                         const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
 | 
			
		||||
                         uint64_t fragment_id,
 | 
			
		||||
                         uint64_t flags,
 | 
			
		||||
                         struct GNUNET_MULTICAST_ReplayHandle *rh)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: origin_recv_replay_frag()"
 | 
			
		||||
              " - fragment_id=%" PRIu64 " flags=%" PRIu64 "\n",
 | 
			
		||||
              test, fragment_id, flags);
 | 
			
		||||
  GNUNET_assert (replay_fragment_id == fragment_id && replay_flags == flags);
 | 
			
		||||
  switch (test)
 | 
			
		||||
  {
 | 
			
		||||
  case TEST_MEMBER_REPLAY_ERROR:
 | 
			
		||||
    // Test 8 starts here
 | 
			
		||||
    GNUNET_MULTICAST_replay_response (rh, NULL, GNUNET_SYSERR);
 | 
			
		||||
    member_replay_ok ();
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case TEST_MEMBER_REPLAY_OK:
 | 
			
		||||
  {
 | 
			
		||||
    struct GNUNET_MULTICAST_MessageHeader mmsg = {
 | 
			
		||||
      .header = {
 | 
			
		||||
        .type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE),
 | 
			
		||||
        .size = htons (sizeof (mmsg)),
 | 
			
		||||
      },
 | 
			
		||||
      .fragment_id = GNUNET_htonll (1),
 | 
			
		||||
      .message_id = GNUNET_htonll (1),
 | 
			
		||||
      .fragment_offset = 0,
 | 
			
		||||
      .group_generation = GNUNET_htonll (1),
 | 
			
		||||
      .flags = 0,
 | 
			
		||||
    };
 | 
			
		||||
    member_cls.n = 0;
 | 
			
		||||
    member_cls.msgs_expected = 1;
 | 
			
		||||
    GNUNET_MULTICAST_replay_response (rh, &mmsg.header, GNUNET_MULTICAST_REC_OK);
 | 
			
		||||
    GNUNET_MULTICAST_replay_response_end (rh);
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  default:
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
 | 
			
		||||
                "Invalid test #%d in origin_recv_replay_frag()\n", test);
 | 
			
		||||
    GNUNET_assert (0);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_recv_replay_frag (void *cls,
 | 
			
		||||
                         const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
 | 
			
		||||
                         uint64_t fragment_id,
 | 
			
		||||
                         uint64_t flags,
 | 
			
		||||
                         struct GNUNET_MULTICAST_ReplayHandle *rh)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: member_recv_replay_frag()\n", test);
 | 
			
		||||
  GNUNET_assert (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_recv_request (void *cls,
 | 
			
		||||
                     const struct GNUNET_MULTICAST_RequestHeader *req)
 | 
			
		||||
{
 | 
			
		||||
  struct OriginClosure *ocls = cls;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: origin_recv_request()\n", test);
 | 
			
		||||
  if (++ocls->n != ocls->msgs_expected)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (0 == memcmp (&req->member_pub_key,
 | 
			
		||||
                              &member_pub_key, sizeof (member_pub_key)));
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
 | 
			
		||||
              "Test #%u: verify message content, take first 3 bytes: %.3s\n",
 | 
			
		||||
              test, (char *)&req[1]);
 | 
			
		||||
  GNUNET_assert (0 == memcmp (&req[1], "abc", 3));
 | 
			
		||||
 | 
			
		||||
  // Test 7 starts here
 | 
			
		||||
  member_replay_error ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_to_origin ()
 | 
			
		||||
{
 | 
			
		||||
  test = TEST_MEMBER_TO_ORIGIN;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: member_to_origin()\n", test);
 | 
			
		||||
 | 
			
		||||
  struct TransmitClosure *tmit = &tmit_cls;
 | 
			
		||||
  *tmit = (struct TransmitClosure) {};
 | 
			
		||||
  tmit->data[0] = "abc def";
 | 
			
		||||
  tmit->data[1] = "ghi jkl mno";
 | 
			
		||||
  tmit->data_delay[1] = 2;
 | 
			
		||||
  tmit->data[2] = "pqr stuw xyz";
 | 
			
		||||
  tmit->data_count = 3;
 | 
			
		||||
 | 
			
		||||
  origin_cls.n = 0;
 | 
			
		||||
  origin_cls.msgs_expected = 1;
 | 
			
		||||
 | 
			
		||||
  tmit->mem_tmit = GNUNET_MULTICAST_member_to_origin (member, 1,
 | 
			
		||||
                                                      tmit_notify, tmit);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_recv_message (void *cls,
 | 
			
		||||
                     const struct GNUNET_MULTICAST_MessageHeader *msg)
 | 
			
		||||
{
 | 
			
		||||
  struct MemberClosure *mcls = cls;
 | 
			
		||||
 | 
			
		||||
  // Test 5 starts here after message has been received from origin
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
 | 
			
		||||
              "Test #%u: member_recv_message() %u/%u\n",
 | 
			
		||||
              test,
 | 
			
		||||
              (unsigned int) (mcls->n + 1),
 | 
			
		||||
              mcls->msgs_expected);
 | 
			
		||||
  if (++mcls->n != mcls->msgs_expected)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  // FIXME: check message content
 | 
			
		||||
 | 
			
		||||
  switch (test)
 | 
			
		||||
  {
 | 
			
		||||
  case TEST_ORIGIN_TO_ALL:
 | 
			
		||||
    test = TEST_ORIGIN_TO_ALL_RECV;
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case TEST_ORIGIN_TO_ALL_RECV:
 | 
			
		||||
    // Test 6 starts here
 | 
			
		||||
    member_to_origin ();
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case TEST_MEMBER_REPLAY_OK:
 | 
			
		||||
    // Test 9 starts here
 | 
			
		||||
    GNUNET_assert (replay_fragment_id == GNUNET_ntohll (msg->fragment_id));
 | 
			
		||||
    member_part ();
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  default:
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
 | 
			
		||||
                "Invalid test #%d in origin_recv_message()\n", test);
 | 
			
		||||
    GNUNET_assert (0);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_recv_message (void *cls,
 | 
			
		||||
                     const struct GNUNET_MULTICAST_MessageHeader *msg)
 | 
			
		||||
{
 | 
			
		||||
  struct OriginClosure *ocls = cls;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: origin_recv_message() %u/%u\n",
 | 
			
		||||
              test, ocls->n + 1, ocls->msgs_expected);
 | 
			
		||||
  if (++ocls->n != ocls->msgs_expected)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  // FIXME: check message content
 | 
			
		||||
 | 
			
		||||
  switch (test)
 | 
			
		||||
  {
 | 
			
		||||
  case TEST_ORIGIN_TO_ALL:
 | 
			
		||||
    // Prepare to execute test 5
 | 
			
		||||
    test = TEST_ORIGIN_TO_ALL_RECV;
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case TEST_ORIGIN_TO_ALL_RECV:
 | 
			
		||||
    // Test 6 starts here
 | 
			
		||||
    member_to_origin ();
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  default:
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
 | 
			
		||||
                "Invalid test #%d in origin_recv_message()\n", test);
 | 
			
		||||
    GNUNET_assert (0);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_to_all ()
 | 
			
		||||
{
 | 
			
		||||
  test = TEST_ORIGIN_TO_ALL;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: origin_to_all()\n", test);
 | 
			
		||||
 | 
			
		||||
  struct TransmitClosure *tmit = &tmit_cls;
 | 
			
		||||
  *tmit = (struct TransmitClosure) {};
 | 
			
		||||
  tmit->data[0] = "ABC DEF";
 | 
			
		||||
  tmit->data[1] =  GNUNET_malloc (GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD + 1);
 | 
			
		||||
  uint16_t i;
 | 
			
		||||
  for (i = 0; i < GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD; i++)
 | 
			
		||||
    tmit->data[1][i] = (0 == i % 10000) ? '0' + i / 10000 : '_';
 | 
			
		||||
  tmit->data[2] = "GHI JKL MNO";
 | 
			
		||||
  tmit->data_delay[2] = 2;
 | 
			
		||||
  tmit->data[3] = "PQR STUW XYZ";
 | 
			
		||||
  tmit->data_count = 4;
 | 
			
		||||
 | 
			
		||||
  origin_cls.n = member_cls.n = 0;
 | 
			
		||||
  origin_cls.msgs_expected = member_cls.msgs_expected = tmit->data_count;
 | 
			
		||||
 | 
			
		||||
  tmit->orig_tmit = GNUNET_MULTICAST_origin_to_all (origin, 1, 1,
 | 
			
		||||
                                                    tmit_notify, tmit);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_recv_join_decision (void *cls,
 | 
			
		||||
                           int is_admitted,
 | 
			
		||||
                           const struct GNUNET_PeerIdentity *peer,
 | 
			
		||||
                           uint16_t relay_count,
 | 
			
		||||
                           const struct GNUNET_PeerIdentity *relays,
 | 
			
		||||
                           const struct GNUNET_MessageHeader *join_msg)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: member_recv_join_decision() - is_admitted: %d\n",
 | 
			
		||||
              test, is_admitted);
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (join_msg->size == join_resp->size);
 | 
			
		||||
  GNUNET_assert (join_msg->type == join_resp->type);
 | 
			
		||||
  GNUNET_assert (0 == memcmp (join_msg, join_resp, ntohs (join_resp->size)));
 | 
			
		||||
 | 
			
		||||
  switch (test)
 | 
			
		||||
  {
 | 
			
		||||
  case TEST_MEMBER_JOIN_REFUSE:
 | 
			
		||||
    GNUNET_assert (0 == relay_count);
 | 
			
		||||
    // Test 3 starts here
 | 
			
		||||
    GNUNET_SCHEDULER_add_now (&schedule_member_part, NULL);
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case TEST_MEMBER_JOIN_ADMIT:
 | 
			
		||||
    GNUNET_assert (1 == relay_count);
 | 
			
		||||
    GNUNET_assert (0 == memcmp (relays, &this_peer, sizeof (this_peer)));
 | 
			
		||||
    // Test 4 starts here
 | 
			
		||||
    origin_to_all ();
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  default:
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
 | 
			
		||||
                "Invalid test #%d in member_recv_join_decision()\n", test);
 | 
			
		||||
    GNUNET_assert (0);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test: origin receives join request
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
origin_recv_join_request (void *cls,
 | 
			
		||||
                          const struct GNUNET_CRYPTO_EcdsaPublicKey *mem_key,
 | 
			
		||||
                          const struct GNUNET_MessageHeader *join_msg,
 | 
			
		||||
                          struct GNUNET_MULTICAST_JoinHandle *jh)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: origin_recv_join_request()\n", test);
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (0 == memcmp (mem_key, &member_pub_key, sizeof (member_pub_key)));
 | 
			
		||||
  GNUNET_assert (join_msg->size == join_req->size);
 | 
			
		||||
  GNUNET_assert (join_msg->type == join_req->type);
 | 
			
		||||
  GNUNET_assert (0 == memcmp (join_msg, join_req, ntohs (join_req->size)));
 | 
			
		||||
 | 
			
		||||
  char data[] = "here's the decision";
 | 
			
		||||
  uint8_t data_size = strlen (data) + 1;
 | 
			
		||||
  join_resp = GNUNET_malloc (sizeof (join_resp) + data_size);
 | 
			
		||||
  join_resp->size = htons (sizeof (join_resp) + data_size);
 | 
			
		||||
  join_resp->type = htons (456);
 | 
			
		||||
  GNUNET_memcpy (&join_resp[1], data, data_size);
 | 
			
		||||
 | 
			
		||||
  switch (test)
 | 
			
		||||
  {
 | 
			
		||||
  case TEST_MEMBER_JOIN_REFUSE:
 | 
			
		||||
    // Test 3 starts here
 | 
			
		||||
    GNUNET_MULTICAST_join_decision (jh, GNUNET_NO, 0, NULL, join_resp);
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case TEST_MEMBER_JOIN_ADMIT:
 | 
			
		||||
    // Test 3 is running
 | 
			
		||||
    GNUNET_MULTICAST_join_decision (jh, GNUNET_YES, 1, &this_peer, join_resp);
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  default:
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
 | 
			
		||||
                "Invalid test #%d in origin_recv_join_request()\n", test);
 | 
			
		||||
    GNUNET_assert (0);
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test: member joins multicast group
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
member_join (int t)
 | 
			
		||||
{
 | 
			
		||||
  test = t;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: member_join()\n", test);
 | 
			
		||||
 | 
			
		||||
  member_key = GNUNET_CRYPTO_ecdsa_key_create ();
 | 
			
		||||
  GNUNET_CRYPTO_ecdsa_key_get_public (member_key, &member_pub_key);
 | 
			
		||||
 | 
			
		||||
  if (NULL != join_req)
 | 
			
		||||
    GNUNET_free (join_req);
 | 
			
		||||
 | 
			
		||||
  char data[] = "let me in!";
 | 
			
		||||
  uint8_t data_size = strlen (data) + 1;
 | 
			
		||||
  join_req = GNUNET_malloc (sizeof (join_req) + data_size);
 | 
			
		||||
  join_req->size = htons (sizeof (join_req) + data_size);
 | 
			
		||||
  join_req->type = htons (123);
 | 
			
		||||
  GNUNET_memcpy (&join_req[1], data, data_size);
 | 
			
		||||
 | 
			
		||||
  member = GNUNET_MULTICAST_member_join (cfg, &group_pub_key, member_key,
 | 
			
		||||
                                         &this_peer, 1, &this_peer, join_req,
 | 
			
		||||
                                         member_recv_join_request,
 | 
			
		||||
                                         member_recv_join_decision,
 | 
			
		||||
                                         member_recv_replay_frag,
 | 
			
		||||
                                         member_recv_replay_msg,
 | 
			
		||||
                                         member_recv_message,
 | 
			
		||||
                                         &member_cls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test: Start a multicast group as origin
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
origin_start ()
 | 
			
		||||
{
 | 
			
		||||
  test = TEST_ORIGIN_START;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Test #%u: origin_start()\n", test);
 | 
			
		||||
 | 
			
		||||
  group_key = GNUNET_CRYPTO_eddsa_key_create ();
 | 
			
		||||
  GNUNET_CRYPTO_eddsa_key_get_public (group_key, &group_pub_key);
 | 
			
		||||
 | 
			
		||||
  origin = GNUNET_MULTICAST_origin_start (cfg, group_key, 0,
 | 
			
		||||
                                          origin_recv_join_request,
 | 
			
		||||
                                          origin_recv_replay_frag,
 | 
			
		||||
                                          origin_recv_replay_msg,
 | 
			
		||||
                                          origin_recv_request,
 | 
			
		||||
                                          origin_recv_message,
 | 
			
		||||
                                          &origin_cls);
 | 
			
		||||
  // Test 2 starts here
 | 
			
		||||
  member_join (TEST_MEMBER_JOIN_REFUSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Main function of the test, run from scheduler.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls NULL
 | 
			
		||||
 * @param cfg configuration we use (also to connect to Multicast service)
 | 
			
		||||
 * @param peer handle to access more of the peer (not used)
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
#if DEBUG_TEST_MULTICAST
 | 
			
		||||
run (void *cls,
 | 
			
		||||
     char *const *args,
 | 
			
		||||
     const char *cfgfile,
 | 
			
		||||
     const struct GNUNET_CONFIGURATION_Handle *c)
 | 
			
		||||
#else
 | 
			
		||||
run (void *cls,
 | 
			
		||||
     const struct GNUNET_CONFIGURATION_Handle *c,
 | 
			
		||||
     struct GNUNET_TESTING_Peer *peer)
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
  cfg = c;
 | 
			
		||||
  end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
 | 
			
		||||
						 &end_badly, NULL);
 | 
			
		||||
  GNUNET_CRYPTO_get_peer_identity (cfg, &this_peer);
 | 
			
		||||
 | 
			
		||||
  // Test 1 starts here
 | 
			
		||||
  origin_start ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
  res = 1;
 | 
			
		||||
#if DEBUG_TEST_MULTICAST
 | 
			
		||||
  const struct GNUNET_GETOPT_CommandLineOption opts[] = {
 | 
			
		||||
    GNUNET_GETOPT_OPTION_END
 | 
			
		||||
  };
 | 
			
		||||
  if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "test-multicast",
 | 
			
		||||
                                       "test-multicast [options]",
 | 
			
		||||
                                       opts, &run, NULL))
 | 
			
		||||
    return 1;
 | 
			
		||||
#else
 | 
			
		||||
  if (0 != GNUNET_TESTING_peer_run ("test-multicast", "test_multicast.conf", &run, NULL))
 | 
			
		||||
    return 1;
 | 
			
		||||
#endif
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* end of test_multicast.c */
 | 
			
		||||
							
								
								
									
										56
									
								
								src/multicast/test_multicast.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/multicast/test_multicast.conf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
			
		||||
[testbed]
 | 
			
		||||
HOSTNAME = localhost
 | 
			
		||||
 | 
			
		||||
[arm]
 | 
			
		||||
GLOBAL_POSTFIX=-L ERROR
 | 
			
		||||
 | 
			
		||||
[multicast]
 | 
			
		||||
#PREFIX = tmux new-window gdb -x ./cmd.gdb  --args
 | 
			
		||||
#PREFIX = valgrind --leak-check=full
 | 
			
		||||
UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-multicast.sock
 | 
			
		||||
 | 
			
		||||
[vpn]
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[peerinfo]
 | 
			
		||||
# Do not use shipped gnunet HELLOs 
 | 
			
		||||
USE_INCLUDED_HELLOS = NO
 | 
			
		||||
 | 
			
		||||
# Option to disable all disk IO; only useful for testbed runs
 | 
			
		||||
# (large-scale experiments); disables persistence of HELLOs!
 | 
			
		||||
NO_IO = YES
 | 
			
		||||
 | 
			
		||||
[hostlist]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[nat]
 | 
			
		||||
ENABLE_UPNP = NO
 | 
			
		||||
 | 
			
		||||
[fs]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[vpn]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[revocation]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[gns]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[namestore]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[namecache]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[topology]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
							
								
								
									
										520
									
								
								src/multicast/test_multicast_2peers.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										520
									
								
								src/multicast/test_multicast_2peers.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,520 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of GNUnet
 | 
			
		||||
 * Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file multicast/test_multicast_2peers.c
 | 
			
		||||
 * @brief Tests for the Multicast API with two peers doing the ping
 | 
			
		||||
 *        pong test.
 | 
			
		||||
 * @author xrs
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "gnunet_crypto_lib.h"
 | 
			
		||||
#include "gnunet_common.h"
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
#include "gnunet_testbed_service.h"
 | 
			
		||||
#include "gnunet_multicast_service.h"
 | 
			
		||||
 | 
			
		||||
#define NUM_PEERS 2
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_TESTBED_Operation *op0;
 | 
			
		||||
static struct GNUNET_TESTBED_Operation *op1;
 | 
			
		||||
static struct GNUNET_TESTBED_Operation *pi_op0;
 | 
			
		||||
static struct GNUNET_TESTBED_Operation *pi_op1;
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_TESTBED_Peer **peers;
 | 
			
		||||
const struct GNUNET_PeerIdentity *peer_id[2];
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_SCHEDULER_Task *timeout_tid;
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_MULTICAST_Origin *origin;
 | 
			
		||||
static struct GNUNET_MULTICAST_Member *member;
 | 
			
		||||
 | 
			
		||||
struct GNUNET_CRYPTO_EddsaPrivateKey *group_key;
 | 
			
		||||
struct GNUNET_CRYPTO_EddsaPublicKey group_pub_key;
 | 
			
		||||
 | 
			
		||||
struct GNUNET_CRYPTO_EcdsaPrivateKey *member_key;
 | 
			
		||||
struct GNUNET_CRYPTO_EcdsaPublicKey member_pub_key;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Global result for testcase.
 | 
			
		||||
 */
 | 
			
		||||
static int result;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function run on CTRL-C or shutdown (i.e. success/timeout/etc.).
 | 
			
		||||
 * Cleans up.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
shutdown_task (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  if (NULL != op0)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_TESTBED_operation_done (op0);
 | 
			
		||||
    op0 = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  if (NULL != op1)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_TESTBED_operation_done (op1);
 | 
			
		||||
    op1 = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  if (NULL != pi_op0)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_TESTBED_operation_done (pi_op0);
 | 
			
		||||
    pi_op0 = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  if (NULL != pi_op1)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_TESTBED_operation_done (pi_op1);
 | 
			
		||||
    pi_op1 = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  if (NULL != timeout_tid)
 | 
			
		||||
    {
 | 
			
		||||
      GNUNET_SCHEDULER_cancel (timeout_tid);
 | 
			
		||||
      timeout_tid = NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
timeout_task (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
 | 
			
		||||
	      "Timeout!\n");
 | 
			
		||||
  result = GNUNET_SYSERR;
 | 
			
		||||
  GNUNET_SCHEDULER_shutdown ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_join_request (void *cls,
 | 
			
		||||
                     const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
 | 
			
		||||
                     const struct GNUNET_MessageHeader *join_msg,
 | 
			
		||||
                     struct GNUNET_MULTICAST_JoinHandle *jh)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Member sent a join request.\n");
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
notify (void *cls,
 | 
			
		||||
        size_t *data_size,
 | 
			
		||||
        void *data)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  char text[] = "ping";
 | 
			
		||||
  *data_size = strlen(text)+1;
 | 
			
		||||
  GNUNET_memcpy(data, text, *data_size);
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Member sents message to origin: %s\n", text);
 | 
			
		||||
 | 
			
		||||
  return GNUNET_YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_join_decision (void *cls,
 | 
			
		||||
                      int is_admitted,
 | 
			
		||||
                      const struct GNUNET_PeerIdentity *peer,
 | 
			
		||||
                      uint16_t relay_count,
 | 
			
		||||
                      const struct GNUNET_PeerIdentity *relays,
 | 
			
		||||
                      const struct GNUNET_MessageHeader *join_msg)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Member received a decision from origin: %s\n",
 | 
			
		||||
              (GNUNET_YES == is_admitted)
 | 
			
		||||
              ? "accepted"
 | 
			
		||||
              : "rejected");
 | 
			
		||||
 | 
			
		||||
  if (GNUNET_YES == is_admitted)
 | 
			
		||||
  {
 | 
			
		||||
    struct GNUNET_MULTICAST_MemberTransmitHandle *req;
 | 
			
		||||
 | 
			
		||||
    // FIXME: move to MQ-style API!
 | 
			
		||||
    req = GNUNET_MULTICAST_member_to_origin (member,
 | 
			
		||||
                                             0,
 | 
			
		||||
                                             ¬ify,
 | 
			
		||||
                                             NULL);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_message (void *cls,
 | 
			
		||||
                const struct GNUNET_MULTICAST_MessageHeader *msg)
 | 
			
		||||
{
 | 
			
		||||
  if (0 != strncmp ("pong", (char *)&msg[1], 4))
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "member did not receive pong\n");
 | 
			
		||||
    result = GNUNET_SYSERR;
 | 
			
		||||
    GNUNET_SCHEDULER_shutdown ();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "member receives: %s\n", (char *)&msg[1]);
 | 
			
		||||
 | 
			
		||||
  // Testcase ends here.
 | 
			
		||||
  result = GNUNET_YES;
 | 
			
		||||
  GNUNET_SCHEDULER_shutdown ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_join_request (void *cls,
 | 
			
		||||
                 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
 | 
			
		||||
                 const struct GNUNET_MessageHeader *join_msg,
 | 
			
		||||
                 struct GNUNET_MULTICAST_JoinHandle *jh)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_MessageHeader *join_resp;
 | 
			
		||||
 | 
			
		||||
  uint8_t data_size = ntohs (join_msg->size);
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "origin got a join request...\n");
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "origin receives: '%s'\n", (char *)&join_msg[1]);
 | 
			
		||||
 | 
			
		||||
  const char data[] = "Come in!";
 | 
			
		||||
  data_size = strlen (data) + 1;
 | 
			
		||||
  join_resp = GNUNET_malloc (sizeof (join_resp) + data_size);
 | 
			
		||||
  join_resp->size = htons (sizeof (join_resp) + data_size);
 | 
			
		||||
  join_resp->type = htons (123);
 | 
			
		||||
  GNUNET_memcpy (&join_resp[1], data, data_size);
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "origin sends: '%s'\n", data);
 | 
			
		||||
 | 
			
		||||
  GNUNET_MULTICAST_join_decision (jh,
 | 
			
		||||
                                  GNUNET_YES,
 | 
			
		||||
                                  0,
 | 
			
		||||
                                  NULL,
 | 
			
		||||
                                  join_resp);
 | 
			
		||||
  GNUNET_free (join_resp);
 | 
			
		||||
  result = GNUNET_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
origin_notify (void *cls,
 | 
			
		||||
               size_t *data_size,
 | 
			
		||||
               void *data)
 | 
			
		||||
{
 | 
			
		||||
  char text[] = "pong";
 | 
			
		||||
 | 
			
		||||
  *data_size = strlen(text)+1;
 | 
			
		||||
  GNUNET_memcpy (data,
 | 
			
		||||
                 text,
 | 
			
		||||
                 *data_size);
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin sends (to all): %s\n", text);
 | 
			
		||||
 | 
			
		||||
  return GNUNET_YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_request (void *cls,
 | 
			
		||||
                const struct GNUNET_MULTICAST_RequestHeader *req)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin receives: %s\n", (char *)&req[1]);
 | 
			
		||||
 | 
			
		||||
  if (0 != strncmp ("ping", (char *)&req[1], 4))
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "origin didn't reveice a correct request");
 | 
			
		||||
 | 
			
		||||
  GNUNET_MULTICAST_origin_to_all (origin,
 | 
			
		||||
                                  0,
 | 
			
		||||
                                  0,
 | 
			
		||||
                                  origin_notify,
 | 
			
		||||
                                  NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_message (void *cls,
 | 
			
		||||
                const struct GNUNET_MULTICAST_MessageHeader *msg)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin message msg\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
service_connect1 (void *cls,
 | 
			
		||||
                  struct GNUNET_TESTBED_Operation *op,
 | 
			
		||||
                  void *ca_result,
 | 
			
		||||
                  const char *emsg)
 | 
			
		||||
{
 | 
			
		||||
  member = ca_result;
 | 
			
		||||
 | 
			
		||||
  if (NULL == member)
 | 
			
		||||
  {
 | 
			
		||||
    result = GNUNET_SYSERR;
 | 
			
		||||
    GNUNET_SCHEDULER_shutdown ();
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to multicast service of member\n");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
multicast_da1 (void *cls,
 | 
			
		||||
               void * op_result)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Member parting from multicast group\n");
 | 
			
		||||
 | 
			
		||||
  GNUNET_MULTICAST_member_part (member, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void *
 | 
			
		||||
multicast_ca1 (void *cls,
 | 
			
		||||
               const struct GNUNET_CONFIGURATION_Handle *cfg)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_MessageHeader *join_msg;
 | 
			
		||||
  void *ret;
 | 
			
		||||
 | 
			
		||||
  // Get members keys
 | 
			
		||||
  member_key = GNUNET_CRYPTO_ecdsa_key_create ();
 | 
			
		||||
  GNUNET_CRYPTO_ecdsa_key_get_public (member_key, &member_pub_key);
 | 
			
		||||
 | 
			
		||||
  char data[] = "Hi, can I enter?";
 | 
			
		||||
  uint8_t data_size = strlen (data) + 1;
 | 
			
		||||
  join_msg = GNUNET_malloc (sizeof (join_msg) + data_size);
 | 
			
		||||
  join_msg->size = htons (sizeof (join_msg) + data_size);
 | 
			
		||||
  join_msg->type = htons (123);
 | 
			
		||||
  GNUNET_memcpy (&join_msg[1], data, data_size);
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Members tries to join multicast group\n");
 | 
			
		||||
 | 
			
		||||
  ret = GNUNET_MULTICAST_member_join (cfg,
 | 
			
		||||
                                       &group_pub_key,
 | 
			
		||||
                                       member_key,
 | 
			
		||||
                                       peer_id[0],
 | 
			
		||||
                                       0,
 | 
			
		||||
                                       NULL,
 | 
			
		||||
                                       join_msg, /* join message */
 | 
			
		||||
                                       member_join_request,
 | 
			
		||||
                                       member_join_decision,
 | 
			
		||||
                                       NULL, /* no test for member_replay_frag */
 | 
			
		||||
                                       NULL, /* no test for member_replay_msg */
 | 
			
		||||
                                       member_message,
 | 
			
		||||
                                       NULL);
 | 
			
		||||
  GNUNET_free (join_msg);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
peer_information_cb (void *cls,
 | 
			
		||||
                     struct GNUNET_TESTBED_Operation *op,
 | 
			
		||||
                     const struct GNUNET_TESTBED_PeerInformation *pinfo,
 | 
			
		||||
                     const char *emsg)
 | 
			
		||||
{
 | 
			
		||||
  int i = (int) (long) cls;
 | 
			
		||||
 | 
			
		||||
  if (NULL == pinfo)
 | 
			
		||||
  {
 | 
			
		||||
    result = GNUNET_SYSERR;
 | 
			
		||||
    GNUNET_SCHEDULER_shutdown ();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  peer_id[i] = pinfo->result.id;
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Got peer information of %s (%s)\n", (0==i)?"origin":"member" ,GNUNET_i2s(pinfo->result.id));
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Create member peer\n");
 | 
			
		||||
 | 
			
		||||
  if (0 == i)
 | 
			
		||||
  {
 | 
			
		||||
    /* connect to multicast service of member */
 | 
			
		||||
    op1 = GNUNET_TESTBED_service_connect (NULL,                    /* Closure for operation */
 | 
			
		||||
                                          peers[1],                /* The peer whose service to connect to */
 | 
			
		||||
                                          "multicast",             /* The name of the service */
 | 
			
		||||
                                          service_connect1,   /* callback to call after a handle to service
 | 
			
		||||
                                                                 is opened */
 | 
			
		||||
                                          NULL,                    /* closure for the above callback */
 | 
			
		||||
                                          multicast_ca1,      /* callback to call with peer's configuration;
 | 
			
		||||
                                                                 this should open the needed service connection */
 | 
			
		||||
                                          multicast_da1,     /* callback to be called when closing the
 | 
			
		||||
                                                                opened service connection */
 | 
			
		||||
                                          NULL);                   /* closure for the above two callbacks */
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Test logic of peer "0" being origin starts here.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls closure, for the example: NULL
 | 
			
		||||
 * @param op should be equal to "dht_op"
 | 
			
		||||
 * @param ca_result result of the connect operation, the
 | 
			
		||||
 *        connection to the DHT service
 | 
			
		||||
 * @param emsg error message, if testbed somehow failed to
 | 
			
		||||
 *        connect to the DHT.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
service_connect0 (void *cls,
 | 
			
		||||
                  struct GNUNET_TESTBED_Operation *op,
 | 
			
		||||
                  void *ca_result,
 | 
			
		||||
                  const char *emsg)
 | 
			
		||||
{
 | 
			
		||||
  origin = ca_result;
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Connected to multicast service of origin\n");
 | 
			
		||||
 | 
			
		||||
  // Get GNUnet identity of origin
 | 
			
		||||
  pi_op0 = GNUNET_TESTBED_peer_get_information (peers[0],
 | 
			
		||||
                                               GNUNET_TESTBED_PIT_IDENTITY,
 | 
			
		||||
                                               peer_information_cb,
 | 
			
		||||
                                               (void *) 0);
 | 
			
		||||
  // Get GNUnet identity of member
 | 
			
		||||
  pi_op1 = GNUNET_TESTBED_peer_get_information (peers[1],
 | 
			
		||||
                                               GNUNET_TESTBED_PIT_IDENTITY,
 | 
			
		||||
                                               peer_information_cb,
 | 
			
		||||
                                               (void *) 1);
 | 
			
		||||
 | 
			
		||||
  /* Connection to service successful. Here we'd usually do something with
 | 
			
		||||
   * the service. */
 | 
			
		||||
  result = GNUNET_OK;
 | 
			
		||||
  //GNUNET_SCHEDULER_shutdown (); /* Also kills the testbed */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function run when service multicast has started and is providing us
 | 
			
		||||
 * with a configuration file.
 | 
			
		||||
 */
 | 
			
		||||
static void *
 | 
			
		||||
multicast_ca0 (void *cls,
 | 
			
		||||
               const struct GNUNET_CONFIGURATION_Handle *cfg)
 | 
			
		||||
{
 | 
			
		||||
  group_key = GNUNET_CRYPTO_eddsa_key_create ();
 | 
			
		||||
  GNUNET_CRYPTO_eddsa_key_get_public (group_key, &group_pub_key);
 | 
			
		||||
 | 
			
		||||
  return GNUNET_MULTICAST_origin_start (cfg,
 | 
			
		||||
                                        group_key,
 | 
			
		||||
                                        0,
 | 
			
		||||
                                        origin_join_request,
 | 
			
		||||
                                        NULL, /* no test for origin_replay_frag */
 | 
			
		||||
                                        NULL, /* no test for origin_replay_msg */
 | 
			
		||||
                                        origin_request,
 | 
			
		||||
                                        origin_message,
 | 
			
		||||
                                        NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
multicast_da0 (void *cls,
 | 
			
		||||
               void *op_result)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Origin closes multicast group\n");
 | 
			
		||||
 | 
			
		||||
  GNUNET_MULTICAST_origin_stop (origin, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Main function inovked from TESTBED once all of the
 | 
			
		||||
 * peers are up and running.  This one then connects
 | 
			
		||||
 * just to the multicast service of peer 0 and 1.
 | 
			
		||||
 * Peer 0 is going to be origin.
 | 
			
		||||
 * Peer 1 is going to be one member.
 | 
			
		||||
 * Origin will start a multicast group and the member will try to join it.
 | 
			
		||||
 * After that we execute some multicast test.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls closure
 | 
			
		||||
 * @param h the run handle
 | 
			
		||||
 * @param peers started peers for the test
 | 
			
		||||
 * @param num_peers size of the 'peers' array
 | 
			
		||||
 * @param links_succeeded number of links between peers that were created
 | 
			
		||||
 * @param links_failed number of links testbed was unable to establish
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
testbed_master (void *cls,
 | 
			
		||||
     struct GNUNET_TESTBED_RunHandle *h,
 | 
			
		||||
     unsigned int num_peers,
 | 
			
		||||
     struct GNUNET_TESTBED_Peer **p,
 | 
			
		||||
     unsigned int links_succeeded,
 | 
			
		||||
     unsigned int links_failed)
 | 
			
		||||
{
 | 
			
		||||
  /* Testbed is ready with peers running and connected in a pre-defined overlay
 | 
			
		||||
     topology (FIXME)  */
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Connected to testbed_master()\n");
 | 
			
		||||
 | 
			
		||||
  peers = p;
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Create origin peer\n");
 | 
			
		||||
  op0 = GNUNET_TESTBED_service_connect (NULL,                    /* Closure for operation */
 | 
			
		||||
                                        peers[0],                /* The peer whose service to connect to */
 | 
			
		||||
                                        "multicast",             /* The name of the service */
 | 
			
		||||
                                        service_connect0,   /* callback to call after a handle to service
 | 
			
		||||
                                                               is opened */
 | 
			
		||||
                                        NULL,                    /* closure for the above callback */
 | 
			
		||||
                                        multicast_ca0,      /* callback to call with peer's configuration;
 | 
			
		||||
                                                               this should open the needed service connection */
 | 
			
		||||
                                        multicast_da0,     /* callback to be called when closing the
 | 
			
		||||
                                                              opened service connection */
 | 
			
		||||
                                        NULL);                   /* closure for the above two callbacks */
 | 
			
		||||
 | 
			
		||||
  GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); /* Schedule a new task on shutdown */
 | 
			
		||||
 | 
			
		||||
  /* Schedule the shutdown task with a delay of a few Seconds */
 | 
			
		||||
  timeout_tid = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 50),
 | 
			
		||||
					      &timeout_task, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
  int ret;
 | 
			
		||||
 | 
			
		||||
  result = GNUNET_SYSERR;
 | 
			
		||||
  ret = GNUNET_TESTBED_test_run
 | 
			
		||||
      ("test-multicast-2peers",  /* test case name */
 | 
			
		||||
       "test_multicast.conf", /* template configuration */
 | 
			
		||||
       NUM_PEERS,       /* number of peers to start */
 | 
			
		||||
       0LL, /* Event mask - set to 0 for no event notifications */
 | 
			
		||||
       NULL, /* Controller event callback */
 | 
			
		||||
       NULL, /* Closure for controller event callback */
 | 
			
		||||
       testbed_master, /* continuation callback to be called when testbed setup is complete */
 | 
			
		||||
       NULL); /* Closure for the test_master callback */
 | 
			
		||||
  if ( (GNUNET_OK != ret) || (GNUNET_OK != result) )
 | 
			
		||||
    return 1;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* end of test_multicast_2peers.c */
 | 
			
		||||
							
								
								
									
										63
									
								
								src/multicast/test_multicast_line.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/multicast/test_multicast_line.conf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,63 @@
 | 
			
		||||
[testbed]
 | 
			
		||||
HOSTNAME = localhost
 | 
			
		||||
OVERLAY_TOPOLOGY = LINE
 | 
			
		||||
 | 
			
		||||
[arm]
 | 
			
		||||
GLOBAL_POSTFIX=-L ERROR
 | 
			
		||||
 | 
			
		||||
[multicast]
 | 
			
		||||
#PREFIX = tmux new-window gdb -x ./cmd.gdb  --args
 | 
			
		||||
#PREFIX = valgrind --leak-check=full
 | 
			
		||||
UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-multicast.sock
 | 
			
		||||
 | 
			
		||||
[vpn]
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[peerinfo]
 | 
			
		||||
# Do not use shipped gnunet HELLOs 
 | 
			
		||||
USE_INCLUDED_HELLOS = NO
 | 
			
		||||
 | 
			
		||||
# Option to disable all disk IO; only useful for testbed runs
 | 
			
		||||
# (large-scale experiments); disables persistence of HELLOs!
 | 
			
		||||
NO_IO = YES
 | 
			
		||||
 | 
			
		||||
[cadet]
 | 
			
		||||
ID_ANNOUNCE_TIME = 5 s
 | 
			
		||||
 | 
			
		||||
[hostlist]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[nat]
 | 
			
		||||
ENABLE_UPNP = NO
 | 
			
		||||
 | 
			
		||||
[fs]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[vpn]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[revocation]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[gns]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[namestore]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[namecache]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[topology]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[nse]
 | 
			
		||||
WORKBITS = 0
 | 
			
		||||
							
								
								
									
										643
									
								
								src/multicast/test_multicast_multipeer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										643
									
								
								src/multicast/test_multicast_multipeer.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,643 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of GNUnet
 | 
			
		||||
 * Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file multicast/test_multicast_multipeers.c
 | 
			
		||||
 * @brief Tests for the Multicast API with multiple peers.
 | 
			
		||||
 * @author xrs
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "gnunet_crypto_lib.h"
 | 
			
		||||
#include "gnunet_common.h"
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
#include "gnunet_testbed_service.h"
 | 
			
		||||
#include "gnunet_multicast_service.h"
 | 
			
		||||
 | 
			
		||||
#define PEERS_REQUESTED 12
 | 
			
		||||
 | 
			
		||||
struct MulticastPeerContext
 | 
			
		||||
{
 | 
			
		||||
  int peer; /* peer number */
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaPrivateKey *key;
 | 
			
		||||
  const struct GNUNET_PeerIdentity *id;
 | 
			
		||||
  struct GNUNET_TESTBED_Operation *op; /* not yet in use */
 | 
			
		||||
  struct GNUNET_TESTBED_Operation *pi_op; /* not yet in use */
 | 
			
		||||
  int test_ok;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum pingpong
 | 
			
		||||
{
 | 
			
		||||
  PING = 1,
 | 
			
		||||
  PONG = 2
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct pingpong_msg
 | 
			
		||||
{
 | 
			
		||||
  int peer;
 | 
			
		||||
  enum pingpong msg;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void service_connect (void *cls,
 | 
			
		||||
                             struct GNUNET_TESTBED_Operation *op,
 | 
			
		||||
                             void *ca_result,
 | 
			
		||||
                             const char *emsg);
 | 
			
		||||
 | 
			
		||||
static struct MulticastPeerContext **multicast_peers;
 | 
			
		||||
static struct GNUNET_TESTBED_Peer **peers;
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_TESTBED_Operation *op[PEERS_REQUESTED];
 | 
			
		||||
static struct GNUNET_TESTBED_Operation *pi_op[PEERS_REQUESTED];
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_MULTICAST_Origin *origin;
 | 
			
		||||
static struct GNUNET_MULTICAST_Member *members[PEERS_REQUESTED]; /* first element always empty */
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_SCHEDULER_Task *timeout_tid;
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_CRYPTO_EddsaPrivateKey *group_key;
 | 
			
		||||
static struct GNUNET_CRYPTO_EddsaPublicKey group_pub_key;
 | 
			
		||||
static struct GNUNET_HashCode group_pub_key_hash;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Global result for testcase.
 | 
			
		||||
 */
 | 
			
		||||
static int result;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function run on CTRL-C or shutdown (i.e. success/timeout/etc.).
 | 
			
		||||
 * Cleans up.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
shutdown_task (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
 | 
			
		||||
              "shutdown_task!\n");
 | 
			
		||||
  for (int i=0;i<PEERS_REQUESTED;i++)
 | 
			
		||||
  {
 | 
			
		||||
    if (NULL != op[i])
 | 
			
		||||
    {
 | 
			
		||||
      GNUNET_TESTBED_operation_done(op[i]);
 | 
			
		||||
      op[i] = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    if (NULL != pi_op[i])
 | 
			
		||||
    {
 | 
			
		||||
      GNUNET_TESTBED_operation_done (pi_op[i]);
 | 
			
		||||
      pi_op[i] = NULL;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (NULL != multicast_peers)
 | 
			
		||||
  {
 | 
			
		||||
    for (int i=0; i < PEERS_REQUESTED; i++)
 | 
			
		||||
    {
 | 
			
		||||
      GNUNET_free_non_null (multicast_peers[i]->key);
 | 
			
		||||
      GNUNET_free (multicast_peers[i]);
 | 
			
		||||
      multicast_peers[i] = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    GNUNET_free (multicast_peers);
 | 
			
		||||
    multicast_peers = NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (NULL != timeout_tid)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_SCHEDULER_cancel (timeout_tid);
 | 
			
		||||
    timeout_tid = NULL;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
timeout_task (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
 | 
			
		||||
	      "Timeout!\n");
 | 
			
		||||
  result = GNUNET_SYSERR;
 | 
			
		||||
  GNUNET_SCHEDULER_shutdown ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_join_request (void *cls,
 | 
			
		||||
                     const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
 | 
			
		||||
                     const struct GNUNET_MessageHeader *join_msg,
 | 
			
		||||
                     struct GNUNET_MULTICAST_JoinHandle *jh)
 | 
			
		||||
{
 | 
			
		||||
  struct MulticastPeerContext *mc_peer = (struct MulticastPeerContext*)cls;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Peer #%u (%s) sent a join request.\n",
 | 
			
		||||
              mc_peer->peer,
 | 
			
		||||
              GNUNET_i2s (multicast_peers[mc_peer->peer]->id));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
notify (void *cls,
 | 
			
		||||
        size_t *data_size,
 | 
			
		||||
        void *data)
 | 
			
		||||
{
 | 
			
		||||
  struct MulticastPeerContext *mc_peer = (struct MulticastPeerContext*)cls;
 | 
			
		||||
 | 
			
		||||
  struct pingpong_msg *pp_msg = GNUNET_new (struct pingpong_msg);
 | 
			
		||||
  pp_msg->peer = mc_peer->peer;
 | 
			
		||||
  pp_msg->msg = PING;
 | 
			
		||||
 | 
			
		||||
  *data_size = sizeof (struct pingpong_msg);
 | 
			
		||||
  GNUNET_memcpy(data, pp_msg, *data_size);
 | 
			
		||||
  GNUNET_free (pp_msg);
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Peer #%u sents ping to origin\n", mc_peer->peer);
 | 
			
		||||
 | 
			
		||||
  return GNUNET_YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_join_decision (void *cls,
 | 
			
		||||
                      int is_admitted,
 | 
			
		||||
                      const struct GNUNET_PeerIdentity *peer,
 | 
			
		||||
                      uint16_t relay_count,
 | 
			
		||||
                      const struct GNUNET_PeerIdentity *relays,
 | 
			
		||||
                      const struct GNUNET_MessageHeader *join_msg)
 | 
			
		||||
{
 | 
			
		||||
  struct MulticastPeerContext *mc_peer = (struct MulticastPeerContext*)cls;
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Peer #%u (%s) received a decision from origin: %s\n",
 | 
			
		||||
              mc_peer->peer,
 | 
			
		||||
              GNUNET_i2s (multicast_peers[mc_peer->peer]->id),
 | 
			
		||||
              (GNUNET_YES == is_admitted)?"accepted":"rejected");
 | 
			
		||||
 | 
			
		||||
  if (GNUNET_YES == is_admitted)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_MULTICAST_member_to_origin (members[mc_peer->peer],
 | 
			
		||||
                                       0,
 | 
			
		||||
                                       notify,
 | 
			
		||||
                                       cls);
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_replay_frag ()
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "member replay frag...\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_replay_msg ()
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "member replay msg...\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_disconnected_cb (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
 | 
			
		||||
              "Origin disconnected. Shutting down.\n");
 | 
			
		||||
  result = GNUNET_YES;
 | 
			
		||||
  GNUNET_SCHEDULER_shutdown ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_disconnected_cb (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  for (int i = 1; i < PEERS_REQUESTED; ++i)
 | 
			
		||||
    if (GNUNET_NO == multicast_peers[i]->test_ok)
 | 
			
		||||
      return;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
 | 
			
		||||
              "All member disconnected. Stopping origin.\n");
 | 
			
		||||
  GNUNET_MULTICAST_origin_stop (origin, origin_disconnected_cb, cls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
member_message (void *cls,
 | 
			
		||||
                const struct GNUNET_MULTICAST_MessageHeader *msg)
 | 
			
		||||
{
 | 
			
		||||
  struct MulticastPeerContext *mc_peer = (struct MulticastPeerContext*)cls;
 | 
			
		||||
  struct pingpong_msg *pp_msg = (struct pingpong_msg*) &(msg[1]);
 | 
			
		||||
 | 
			
		||||
  if (PONG == pp_msg->msg && mc_peer->peer == pp_msg->peer)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
                "peer #%i (%s) receives a pong\n",
 | 
			
		||||
                mc_peer->peer,
 | 
			
		||||
                GNUNET_i2s (multicast_peers[mc_peer->peer]->id));
 | 
			
		||||
    mc_peer->test_ok = GNUNET_OK;
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
                "peer #%u (%s) parting from multicast group\n",
 | 
			
		||||
                mc_peer->peer,
 | 
			
		||||
                GNUNET_i2s (multicast_peers[mc_peer->peer]->id));
 | 
			
		||||
 | 
			
		||||
    GNUNET_MULTICAST_member_part (members[mc_peer->peer], member_disconnected_cb, cls);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_join_request (void *cls,
 | 
			
		||||
                 const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
 | 
			
		||||
                 const struct GNUNET_MessageHeader *join_msg,
 | 
			
		||||
                 struct GNUNET_MULTICAST_JoinHandle *jh)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_MessageHeader *join_resp;
 | 
			
		||||
 | 
			
		||||
  uint8_t data_size = ntohs (join_msg->size);
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "origin got a join request...\n");
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "origin receives: '%s'\n", (char *)&join_msg[1]);
 | 
			
		||||
 | 
			
		||||
  char data[] = "Come in!";
 | 
			
		||||
  data_size = strlen (data) + 1;
 | 
			
		||||
  join_resp = GNUNET_malloc (sizeof (join_resp) + data_size);
 | 
			
		||||
  join_resp->size = htons (sizeof (join_resp) + data_size);
 | 
			
		||||
  join_resp->type = htons (123);
 | 
			
		||||
  GNUNET_memcpy (&join_resp[1], data, data_size);
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "origin sends: '%s'\n", data);
 | 
			
		||||
 | 
			
		||||
  GNUNET_MULTICAST_join_decision (jh,
 | 
			
		||||
                                  GNUNET_YES,
 | 
			
		||||
                                  0,
 | 
			
		||||
                                  NULL,
 | 
			
		||||
                                  join_resp);
 | 
			
		||||
 | 
			
		||||
  result = GNUNET_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_replay_frag (void *cls,
 | 
			
		||||
                    const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
 | 
			
		||||
                    uint64_t fragment_id,
 | 
			
		||||
                    uint64_t flags,
 | 
			
		||||
                    struct GNUNET_MULTICAST_ReplayHandle *rh)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin replay fraq msg\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_replay_msg (void *cls,
 | 
			
		||||
                   const struct GNUNET_CRYPTO_EcdsaPublicKey *member_pub_key,
 | 
			
		||||
                   uint64_t message_id,
 | 
			
		||||
                   uint64_t fragment_offset,
 | 
			
		||||
                   uint64_t flags,
 | 
			
		||||
                   struct GNUNET_MULTICAST_ReplayHandle *rh)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin replay msg\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
origin_notify (void *cls,
 | 
			
		||||
               size_t *data_size,
 | 
			
		||||
               void *data)
 | 
			
		||||
{
 | 
			
		||||
  struct pingpong_msg *rcv_pp_msg = (struct pingpong_msg*)cls;
 | 
			
		||||
  struct pingpong_msg *pp_msg = GNUNET_new (struct pingpong_msg);
 | 
			
		||||
 | 
			
		||||
  pp_msg->peer = rcv_pp_msg->peer;
 | 
			
		||||
  pp_msg->msg = PONG;
 | 
			
		||||
  *data_size = sizeof (struct pingpong_msg);
 | 
			
		||||
  GNUNET_memcpy(data, pp_msg, *data_size);
 | 
			
		||||
  GNUNET_free (pp_msg);
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin sends pong\n");
 | 
			
		||||
 | 
			
		||||
  return GNUNET_YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_request (void *cls,
 | 
			
		||||
                const struct GNUNET_MULTICAST_RequestHeader *req)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin receives a msg\n");
 | 
			
		||||
 | 
			
		||||
  req++;
 | 
			
		||||
  struct pingpong_msg *pp_msg = (struct pingpong_msg *) req;
 | 
			
		||||
 | 
			
		||||
  if (1 != pp_msg->msg) {
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "origin didn't reveice a correct request");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  GNUNET_MULTICAST_origin_to_all (origin,
 | 
			
		||||
                                  0,
 | 
			
		||||
                                  0,
 | 
			
		||||
                                  origin_notify,
 | 
			
		||||
                                  pp_msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
origin_message (void *cls,
 | 
			
		||||
                const struct GNUNET_MULTICAST_MessageHeader *msg)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "origin message msg\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
multicast_disconnect (void *cls,
 | 
			
		||||
                      void *op_result)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void *
 | 
			
		||||
multicast_connect (void *cls,
 | 
			
		||||
                   const struct GNUNET_CONFIGURATION_Handle *cfg)
 | 
			
		||||
{
 | 
			
		||||
  struct MulticastPeerContext *multicast_peer = cls;
 | 
			
		||||
  struct GNUNET_MessageHeader *join_msg;
 | 
			
		||||
  char data[64];
 | 
			
		||||
 | 
			
		||||
  if (0 == multicast_peer->peer)
 | 
			
		||||
  {
 | 
			
		||||
    group_key = GNUNET_CRYPTO_eddsa_key_create ();
 | 
			
		||||
    GNUNET_CRYPTO_eddsa_key_get_public (group_key, &group_pub_key);
 | 
			
		||||
 | 
			
		||||
    GNUNET_CRYPTO_hash (&group_pub_key, sizeof (group_pub_key), &group_pub_key_hash);
 | 
			
		||||
    origin = GNUNET_MULTICAST_origin_start (cfg,
 | 
			
		||||
                                            group_key,
 | 
			
		||||
                                            0,
 | 
			
		||||
                                            origin_join_request,
 | 
			
		||||
                                            origin_replay_frag,
 | 
			
		||||
                                            origin_replay_msg,
 | 
			
		||||
                                            origin_request,
 | 
			
		||||
                                            origin_message,
 | 
			
		||||
                                            cls);
 | 
			
		||||
    if (NULL == origin)
 | 
			
		||||
    {
 | 
			
		||||
      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
                  "Peer #%u could not create a multicast group",
 | 
			
		||||
                  multicast_peer->peer);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
                "Peer #%u connected as origin to group %s\n",
 | 
			
		||||
                multicast_peer->peer,
 | 
			
		||||
                GNUNET_h2s (&group_pub_key_hash));
 | 
			
		||||
    return origin;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    multicast_peer->key = GNUNET_CRYPTO_ecdsa_key_create ();
 | 
			
		||||
 | 
			
		||||
    sprintf(data, "Hi, I am peer #%u (%s). Can I enter?",
 | 
			
		||||
            multicast_peer->peer,
 | 
			
		||||
            GNUNET_i2s (multicast_peers[multicast_peer->peer]->id));
 | 
			
		||||
    uint8_t data_size = strlen (data) + 1;
 | 
			
		||||
    join_msg = GNUNET_malloc (sizeof (join_msg) + data_size);
 | 
			
		||||
    join_msg->size = htons (sizeof (join_msg) + data_size);
 | 
			
		||||
    join_msg->type = htons (123);
 | 
			
		||||
    GNUNET_memcpy (&join_msg[1], data, data_size);
 | 
			
		||||
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
                "Peer #%u (%s) tries to join multicast group %s\n",
 | 
			
		||||
                multicast_peer->peer,
 | 
			
		||||
                GNUNET_i2s (multicast_peers[multicast_peer->peer]->id),
 | 
			
		||||
                GNUNET_h2s (&group_pub_key_hash));
 | 
			
		||||
 | 
			
		||||
    members[multicast_peer->peer] =
 | 
			
		||||
      GNUNET_MULTICAST_member_join (cfg,
 | 
			
		||||
                                    &group_pub_key,
 | 
			
		||||
                                    multicast_peer->key,
 | 
			
		||||
                                    multicast_peers[0]->id,
 | 
			
		||||
                                    0,
 | 
			
		||||
                                    NULL,
 | 
			
		||||
                                    join_msg, /* join message */
 | 
			
		||||
                                    member_join_request,
 | 
			
		||||
                                    member_join_decision,
 | 
			
		||||
                                    member_replay_frag,
 | 
			
		||||
                                    member_replay_msg,
 | 
			
		||||
                                    member_message,
 | 
			
		||||
                                    cls);
 | 
			
		||||
    return members[multicast_peer->peer];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
peer_information_cb (void *cls,
 | 
			
		||||
                     struct GNUNET_TESTBED_Operation *operation,
 | 
			
		||||
                     const struct GNUNET_TESTBED_PeerInformation *pinfo,
 | 
			
		||||
                     const char *emsg)
 | 
			
		||||
{
 | 
			
		||||
  struct MulticastPeerContext *mc_peer = (struct MulticastPeerContext*)cls;
 | 
			
		||||
 | 
			
		||||
  if (NULL == pinfo) {
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "got no peer information\n");
 | 
			
		||||
    result = GNUNET_SYSERR;
 | 
			
		||||
    GNUNET_SCHEDULER_shutdown ();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  multicast_peers[mc_peer->peer]->id = pinfo->result.id;
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Got peer information of %s (%s)\n",
 | 
			
		||||
              (0 == mc_peer->peer)? "origin" : "member",
 | 
			
		||||
              GNUNET_i2s (pinfo->result.id));
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Create peer #%u (%s)\n",
 | 
			
		||||
              mc_peer->peer,
 | 
			
		||||
              GNUNET_i2s (multicast_peers[mc_peer->peer]->id));
 | 
			
		||||
 | 
			
		||||
  if (0 != mc_peer->peer)
 | 
			
		||||
  {
 | 
			
		||||
    /* connect to multicast service of members */
 | 
			
		||||
    op[mc_peer->peer] =
 | 
			
		||||
      GNUNET_TESTBED_service_connect (/* Closure for operation */
 | 
			
		||||
                                      NULL,
 | 
			
		||||
                                      /* The peer whose service to connect to */
 | 
			
		||||
                                      peers[mc_peer->peer],
 | 
			
		||||
                                      /* The name of the service */
 | 
			
		||||
                                      "multicast",
 | 
			
		||||
                                      /* called after a handle to service is opened */
 | 
			
		||||
                                      service_connect,
 | 
			
		||||
                                      /* closure for the above callback */
 | 
			
		||||
                                      cls,
 | 
			
		||||
                                      /* called when opening the service connection */
 | 
			
		||||
                                      multicast_connect,
 | 
			
		||||
                                      /* called when closing the service connection */
 | 
			
		||||
                                      multicast_disconnect,
 | 
			
		||||
                                      /* closure for the above two callbacks */
 | 
			
		||||
                                      cls);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
service_connect (void *cls,
 | 
			
		||||
                 struct GNUNET_TESTBED_Operation *op,
 | 
			
		||||
                 void *ca_result,
 | 
			
		||||
                 const char *emsg)
 | 
			
		||||
{
 | 
			
		||||
  struct MulticastPeerContext *mc_peer = (struct MulticastPeerContext*)cls;
 | 
			
		||||
 | 
			
		||||
  if (NULL == ca_result)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
                "Connection adapter not created for peer #%u (%s)\n",
 | 
			
		||||
                mc_peer->peer,
 | 
			
		||||
                GNUNET_i2s (multicast_peers[mc_peer->peer]->id));
 | 
			
		||||
 | 
			
		||||
    result = GNUNET_SYSERR;
 | 
			
		||||
    GNUNET_SCHEDULER_shutdown();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (0 == mc_peer->peer)
 | 
			
		||||
  {
 | 
			
		||||
    // Get GNUnet identity of members
 | 
			
		||||
    for (int i = 0; i<PEERS_REQUESTED; i++)
 | 
			
		||||
    {
 | 
			
		||||
      pi_op[i] = GNUNET_TESTBED_peer_get_information (peers[i],
 | 
			
		||||
                                                      GNUNET_TESTBED_PIT_IDENTITY,
 | 
			
		||||
                                                      peer_information_cb,
 | 
			
		||||
                                                      multicast_peers[i]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Main function inovked from TESTBED once all of the
 | 
			
		||||
 * peers are up and running.  This one then connects
 | 
			
		||||
 * just to the multicast service of peer 0 and 1.
 | 
			
		||||
 * Peer 0 is going to be origin.
 | 
			
		||||
 * Peer 1 is going to be one member.
 | 
			
		||||
 * Origin will start a multicast group and the member will try to join it.
 | 
			
		||||
 * After that we execute some multicast test.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls closure
 | 
			
		||||
 * @param h the run handle
 | 
			
		||||
 * @param peers started peers for the test
 | 
			
		||||
 * @param PEERS_REQUESTED size of the 'peers' array
 | 
			
		||||
 * @param links_succeeded number of links between peers that were created
 | 
			
		||||
 * @param links_failed number of links testbed was unable to establish
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
testbed_master (void *cls,
 | 
			
		||||
                struct GNUNET_TESTBED_RunHandle *h,
 | 
			
		||||
                unsigned int num_peers,
 | 
			
		||||
                struct GNUNET_TESTBED_Peer **p,
 | 
			
		||||
                unsigned int links_succeeded,
 | 
			
		||||
                unsigned int links_failed)
 | 
			
		||||
{
 | 
			
		||||
  /* Testbed is ready with peers running and connected in a pre-defined overlay
 | 
			
		||||
     topology (FIXME)  */
 | 
			
		||||
  peers = p;
 | 
			
		||||
  multicast_peers = GNUNET_new_array (PEERS_REQUESTED, struct MulticastPeerContext*);
 | 
			
		||||
 | 
			
		||||
  // Create test contexts for members
 | 
			
		||||
  for (int i = 0; i<PEERS_REQUESTED; i++)
 | 
			
		||||
  {
 | 
			
		||||
    multicast_peers[i] = GNUNET_new (struct MulticastPeerContext);
 | 
			
		||||
    multicast_peers[i]->peer = i;
 | 
			
		||||
    multicast_peers[i]->test_ok = GNUNET_NO;
 | 
			
		||||
  }
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Create origin peer\n");
 | 
			
		||||
  op[0] =
 | 
			
		||||
    GNUNET_TESTBED_service_connect (/* Closure for operation */
 | 
			
		||||
                                    NULL,
 | 
			
		||||
                                    /* The peer whose service to connect to */
 | 
			
		||||
                                    peers[0],
 | 
			
		||||
                                    /* The name of the service */
 | 
			
		||||
                                    "multicast",
 | 
			
		||||
                                    /* called after a handle to service is opened */
 | 
			
		||||
                                    service_connect,
 | 
			
		||||
                                    /* closure for the above callback */
 | 
			
		||||
                                    multicast_peers[0],
 | 
			
		||||
                                    /* called when opening the service connection */
 | 
			
		||||
                                    multicast_connect,
 | 
			
		||||
                                    /* called when closing the service connection */
 | 
			
		||||
                                    multicast_disconnect,
 | 
			
		||||
                                    /* closure for the above two callbacks */
 | 
			
		||||
                                    multicast_peers[0]);
 | 
			
		||||
  /* Schedule a new task on shutdown */
 | 
			
		||||
  GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
 | 
			
		||||
  /* Schedule the shutdown task with a delay of a few Seconds */
 | 
			
		||||
  timeout_tid =
 | 
			
		||||
    GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
 | 
			
		||||
                                  (GNUNET_TIME_UNIT_SECONDS, 400),
 | 
			
		||||
				  &timeout_task,
 | 
			
		||||
                                  NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
  int ret;
 | 
			
		||||
  char const *config_file;
 | 
			
		||||
 | 
			
		||||
  if (strstr (argv[0], "_line") != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    config_file = "test_multicast_line.conf";
 | 
			
		||||
  }
 | 
			
		||||
  else if (strstr(argv[0], "_star") != NULL)
 | 
			
		||||
  {
 | 
			
		||||
    config_file = "test_multicast_star.conf";
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    config_file = "test_multicast_star.conf";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  result = GNUNET_SYSERR;
 | 
			
		||||
  ret =
 | 
			
		||||
    GNUNET_TESTBED_test_run ("test-multicast-multipeer",
 | 
			
		||||
                             config_file,
 | 
			
		||||
                             /* number of peers to start */
 | 
			
		||||
                             PEERS_REQUESTED,
 | 
			
		||||
                             /* Event mask - set to 0 for no event notifications */
 | 
			
		||||
                             0LL,
 | 
			
		||||
                             /* Controller event callback */
 | 
			
		||||
                             NULL,
 | 
			
		||||
                             /* Closure for controller event callback */
 | 
			
		||||
                             NULL,
 | 
			
		||||
                             /* called when testbed setup is complete */
 | 
			
		||||
                             testbed_master,
 | 
			
		||||
                             /* Closure for the test_master callback */
 | 
			
		||||
                             NULL);
 | 
			
		||||
  if ( (GNUNET_OK != ret) || (GNUNET_OK != result) )
 | 
			
		||||
    return 1;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* end of test_multicast_multipeer.c */
 | 
			
		||||
							
								
								
									
										64
									
								
								src/multicast/test_multicast_star.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/multicast/test_multicast_star.conf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,64 @@
 | 
			
		||||
[testbed]
 | 
			
		||||
HOSTNAME = localhost
 | 
			
		||||
OVERLAY_TOPOLOGY = STAR
 | 
			
		||||
 | 
			
		||||
[arm]
 | 
			
		||||
GLOBAL_POSTFIX=-L ERROR
 | 
			
		||||
 | 
			
		||||
[multicast]
 | 
			
		||||
#PREFIX = tmux new-window gdb -x ./cmd.gdb  --args
 | 
			
		||||
#PREFIX = valgrind --leak-check=full
 | 
			
		||||
UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-multicast.sock
 | 
			
		||||
 | 
			
		||||
[vpn]
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[peerinfo]
 | 
			
		||||
# Do not use shipped gnunet HELLOs 
 | 
			
		||||
USE_INCLUDED_HELLOS = NO
 | 
			
		||||
 | 
			
		||||
# Option to disable all disk IO; only useful for testbed runs
 | 
			
		||||
# (large-scale experiments); disables persistence of HELLOs!
 | 
			
		||||
NO_IO = YES
 | 
			
		||||
 | 
			
		||||
[cadet]
 | 
			
		||||
ID_ANNOUNCE_TIME = 5 s
 | 
			
		||||
 | 
			
		||||
[hostlist]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[nat]
 | 
			
		||||
ENABLE_UPNP = NO
 | 
			
		||||
 | 
			
		||||
[fs]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[vpn]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[revocation]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[gns]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[namestore]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[namecache]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[topology]
 | 
			
		||||
IMMEDIATE_START = NO
 | 
			
		||||
START_ON_DEMAND = NO
 | 
			
		||||
 | 
			
		||||
[nse]
 | 
			
		||||
WORKBITS = 0
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								src/psyc/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/psyc/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
gnunet-service-psyc
 | 
			
		||||
test_psyc
 | 
			
		||||
							
								
								
									
										77
									
								
								src/psyc/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/psyc/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,77 @@
 | 
			
		||||
# This Makefile.am is in the public domain
 | 
			
		||||
AM_CPPFLAGS = -I$(top_srcdir)/src/include
 | 
			
		||||
 | 
			
		||||
pkgcfgdir= $(pkgdatadir)/config.d/
 | 
			
		||||
 | 
			
		||||
libexecdir= $(pkglibdir)/libexec/
 | 
			
		||||
 | 
			
		||||
pkgcfg_DATA = \
 | 
			
		||||
  psyc.conf
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if MINGW
 | 
			
		||||
 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if USE_COVERAGE
 | 
			
		||||
  AM_CFLAGS = --coverage -O0
 | 
			
		||||
  XLIB = -lgcov
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
lib_LTLIBRARIES = libgnunetpsyc.la
 | 
			
		||||
 | 
			
		||||
libgnunetpsyc_la_SOURCES = \
 | 
			
		||||
  psyc_api.c psyc.h
 | 
			
		||||
libgnunetpsyc_la_LIBADD = \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la \
 | 
			
		||||
  $(top_builddir)/src/psycutil/libgnunetpsycutil.la \
 | 
			
		||||
  $(GN_LIBINTL) $(XLIB)
 | 
			
		||||
libgnunetpsyc_la_LDFLAGS = \
 | 
			
		||||
  $(GN_LIB_LDFLAGS)  $(WINFLAGS) \
 | 
			
		||||
  -version-info 0:0:0
 | 
			
		||||
 | 
			
		||||
bin_PROGRAMS =
 | 
			
		||||
 | 
			
		||||
libexec_PROGRAMS = \
 | 
			
		||||
  gnunet-service-psyc
 | 
			
		||||
 | 
			
		||||
gnunet_service_psyc_SOURCES = \
 | 
			
		||||
  gnunet-service-psyc.c
 | 
			
		||||
gnunet_service_psyc_LDADD = \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la \
 | 
			
		||||
  $(top_builddir)/src/statistics/libgnunetstatistics.la \
 | 
			
		||||
  $(top_builddir)/src/multicast/libgnunetmulticast.la \
 | 
			
		||||
  $(top_builddir)/src/psycstore/libgnunetpsycstore.la \
 | 
			
		||||
  $(top_builddir)/src/psycutil/libgnunetpsycutil.la \
 | 
			
		||||
  $(GN_LIBINTL)
 | 
			
		||||
gnunet_service_psyc_CFLAGS = $(AM_CFLAGS)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if HAVE_TESTING
 | 
			
		||||
check_PROGRAMS = \
 | 
			
		||||
 test_psyc
 | 
			
		||||
# test_psyc2
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if ENABLE_TEST_RUN
 | 
			
		||||
AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
 | 
			
		||||
TESTS = $(check_PROGRAMS)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
test_psyc_SOURCES = \
 | 
			
		||||
 test_psyc.c
 | 
			
		||||
test_psyc_LDADD = \
 | 
			
		||||
  libgnunetpsyc.la \
 | 
			
		||||
  $(top_builddir)/src/psycutil/libgnunetpsycutil.la \
 | 
			
		||||
  $(top_builddir)/src/testing/libgnunettesting.la \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la
 | 
			
		||||
#test_psyc2_SOURCES = \
 | 
			
		||||
#  test_psyc2.c
 | 
			
		||||
#test_psyc2_LDADD = \
 | 
			
		||||
#  libgnunetpsyc.la \
 | 
			
		||||
#  $(top_builddir)/src/psycutil/libgnunetpsycutil.la \
 | 
			
		||||
#  $(top_builddir)/src/testbed/libgnunettestbed.la \
 | 
			
		||||
#  $(top_builddir)/src/util/libgnunetutil.la
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = \
 | 
			
		||||
  test_psyc.conf
 | 
			
		||||
							
								
								
									
										2860
									
								
								src/psyc/gnunet-service-psyc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2860
									
								
								src/psyc/gnunet-service-psyc.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										12
									
								
								src/psyc/psyc.conf.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/psyc/psyc.conf.in
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
[psyc]
 | 
			
		||||
START_ON_DEMAND = @START_ON_DEMAND@
 | 
			
		||||
BINARY = gnunet-service-psyc
 | 
			
		||||
 | 
			
		||||
UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-psyc.sock
 | 
			
		||||
UNIX_MATCH_UID = YES
 | 
			
		||||
UNIX_MATCH_GID = YES
 | 
			
		||||
 | 
			
		||||
@UNIXONLY@PORT = 2115
 | 
			
		||||
HOSTNAME = localhost
 | 
			
		||||
ACCEPT_FROM = 127.0.0.1;
 | 
			
		||||
ACCEPT_FROM6 = ::1;
 | 
			
		||||
							
								
								
									
										178
									
								
								src/psyc/psyc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								src/psyc/psyc.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,178 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of GNUnet
 | 
			
		||||
 * Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file psyc/psyc.h
 | 
			
		||||
 * @brief Common type definitions for the PSYC service and API.
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef PSYC_H
 | 
			
		||||
#define PSYC_H
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "gnunet_psyc_service.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYC_check_message_parts (uint16_t data_size, const char *data,
 | 
			
		||||
                                 uint16_t *first_ptype, uint16_t *last_ptype);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_log_message (enum GNUNET_ErrorType kind,
 | 
			
		||||
                         const struct GNUNET_MessageHeader *msg);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
enum MessageState
 | 
			
		||||
{
 | 
			
		||||
  MSG_STATE_START    = 0,
 | 
			
		||||
  MSG_STATE_HEADER   = 1,
 | 
			
		||||
  MSG_STATE_METHOD   = 2,
 | 
			
		||||
  MSG_STATE_MODIFIER = 3,
 | 
			
		||||
  MSG_STATE_MOD_CONT = 4,
 | 
			
		||||
  MSG_STATE_DATA     = 5,
 | 
			
		||||
  MSG_STATE_END      = 6,
 | 
			
		||||
  MSG_STATE_CANCEL   = 7,
 | 
			
		||||
  MSG_STATE_ERROR    = 8,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
enum MessageFragmentState
 | 
			
		||||
{
 | 
			
		||||
  MSG_FRAG_STATE_START    = 0,
 | 
			
		||||
  MSG_FRAG_STATE_HEADER   = 1,
 | 
			
		||||
  MSG_FRAG_STATE_DATA     = 2,
 | 
			
		||||
  MSG_FRAG_STATE_END      = 3,
 | 
			
		||||
  MSG_FRAG_STATE_CANCEL   = 4,
 | 
			
		||||
  MSG_FRAG_STATE_DROP     = 5,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GNUNET_NETWORK_STRUCT_BEGIN
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**** library -> service ****/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct MasterStartRequest
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYC_MASTER_START
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t policy GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPrivateKey channel_key;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct SlaveJoinRequest
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYC_SLAVE_JOIN
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t relay_count GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPublicKey channel_pub_key;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaPrivateKey slave_key;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_PeerIdentity origin;
 | 
			
		||||
 | 
			
		||||
  uint32_t flags GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /* Followed by struct GNUNET_PeerIdentity relays[relay_count] */
 | 
			
		||||
 | 
			
		||||
  /* Followed by struct GNUNET_MessageHeader join_msg */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct ChannelMembershipStoreRequest
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_MEMBERSHIP_STORE
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t reserved GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaPublicKey slave_pub_key;
 | 
			
		||||
 | 
			
		||||
  uint64_t announced_at GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  uint64_t effective_since GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  uint8_t did_join;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct HistoryRequest
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_HISTORY_REQUEST
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t reserved GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ID for this operation.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  uint64_t start_message_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  uint64_t end_message_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  uint64_t message_limit GNUNET_PACKED;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct StateRequest
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Types:
 | 
			
		||||
   * - GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_STATE_GET
 | 
			
		||||
   * - GNUNET_MESSAGE_TYPE_PSYC_CHANNEL_STATE_GET_PREFIX
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t reserved GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ID for this operation.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /* Followed by NUL-terminated name. */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**** service -> library ****/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GNUNET_NETWORK_STRUCT_END
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										1584
									
								
								src/psyc/psyc_api.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1584
									
								
								src/psyc/psyc_api.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										67
									
								
								src/psyc/psyc_test_lib.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/psyc/psyc_test_lib.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,67 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of GNUnet
 | 
			
		||||
 * Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file psyc/test_psyc_api_join.c
 | 
			
		||||
 * @brief library for writing psyc tests
 | 
			
		||||
 * @author xrs
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define MAX_TESTBED_OPS 32
 | 
			
		||||
 | 
			
		||||
struct pctx
 | 
			
		||||
{
 | 
			
		||||
  int idx;
 | 
			
		||||
  
 | 
			
		||||
  struct GNUNET_TESTBED_Peer *testbed_peer;
 | 
			
		||||
  
 | 
			
		||||
  const struct GNUNET_PeerIdentity *peer_id;
 | 
			
		||||
 | 
			
		||||
  const struct GNUNET_PeerIdentity *peer_id_master;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Used to simulate egos (not peerid)
 | 
			
		||||
   */
 | 
			
		||||
  const struct GNUNET_CRYPTO_EcdsaPrivateKey *id_key;
 | 
			
		||||
 | 
			
		||||
  const struct GNUNET_CRYPTO_EcdsaPublicKey *id_pub_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Used to store either GNUNET_PSYC_Master or GNUNET_PSYC_Slave handle
 | 
			
		||||
   */
 | 
			
		||||
  void *psyc;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_PSYC_Channel *channel;
 | 
			
		||||
 | 
			
		||||
  const struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPublicKey *channel_pub_key;
 | 
			
		||||
 | 
			
		||||
  int test_ok;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_SCHEDULER_Task *timeout_task_id;
 | 
			
		||||
 | 
			
		||||
static int result = GNUNET_SYSERR;
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_TESTBED_Operation *op[MAX_TESTBED_OPS];
 | 
			
		||||
 | 
			
		||||
static int op_cnt = 0;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1018
									
								
								src/psyc/test_psyc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1018
									
								
								src/psyc/test_psyc.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										284
									
								
								src/psyc/test_psyc2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										284
									
								
								src/psyc/test_psyc2.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,284 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of GNUnet
 | 
			
		||||
 * Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file psyc/test_psyc2.c
 | 
			
		||||
 * @brief Testbed test for the PSYC API.
 | 
			
		||||
 * @author xrs
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "gnunet_crypto_lib.h"
 | 
			
		||||
#include "gnunet_common.h"
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
#include "gnunet_testbed_service.h"
 | 
			
		||||
#include "gnunet_psyc_util_lib.h"
 | 
			
		||||
#include "gnunet_psyc_service.h"
 | 
			
		||||
 | 
			
		||||
#define PEERS_REQUESTED 2
 | 
			
		||||
 | 
			
		||||
static int result;
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_SCHEDULER_Task *timeout_tid;
 | 
			
		||||
static struct pctx **pctx;
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key;
 | 
			
		||||
static struct GNUNET_CRYPTO_EddsaPublicKey channel_pub_key;
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_CRYPTO_EcdsaPrivateKey *slave_key;
 | 
			
		||||
static struct GNUNET_CRYPTO_EcdsaPublicKey slave_pub_key;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Task To perform tests
 | 
			
		||||
 */
 | 
			
		||||
static struct GNUNET_SCHEDULER_Task *test_task;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Peer id couter
 | 
			
		||||
 */
 | 
			
		||||
static unsigned int pids;
 | 
			
		||||
 | 
			
		||||
struct pctx
 | 
			
		||||
{
 | 
			
		||||
  int idx;
 | 
			
		||||
  struct GNUNET_TESTBED_Peer *peer;
 | 
			
		||||
  const struct GNUNET_PeerIdentity *id;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_TESTBED_Operation *op; 
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * psyc service handle
 | 
			
		||||
   */
 | 
			
		||||
  void *psyc;
 | 
			
		||||
  struct GNUNET_PSYC_Master *mst;
 | 
			
		||||
  struct GNUNET_PSYC_Slave *slv;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * result for test on peer
 | 
			
		||||
   */
 | 
			
		||||
  int test_ok;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
shutdown_task (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  if (NULL != pctx)
 | 
			
		||||
  {
 | 
			
		||||
    if (NULL != pctx[0]->mst)
 | 
			
		||||
      GNUNET_PSYC_master_stop (pctx[0]->mst, GNUNET_NO, NULL, NULL);  
 | 
			
		||||
 | 
			
		||||
    for (int i=0; i < PEERS_REQUESTED; i++)
 | 
			
		||||
    {
 | 
			
		||||
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Operation done.\n");
 | 
			
		||||
      GNUNET_TESTBED_operation_done (pctx[i]->op);
 | 
			
		||||
      GNUNET_free_non_null (pctx[i]);
 | 
			
		||||
    }
 | 
			
		||||
    GNUNET_free (pctx);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (NULL != timeout_tid)
 | 
			
		||||
    GNUNET_SCHEDULER_cancel (timeout_tid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
timeout_task (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Timeout!\n");
 | 
			
		||||
  result = GNUNET_SYSERR;
 | 
			
		||||
  GNUNET_SCHEDULER_shutdown ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
start_test (void *cls)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
pinfo_cb (void *cls,
 | 
			
		||||
          struct GNUNET_TESTBED_Operation *operation,
 | 
			
		||||
          const struct GNUNET_TESTBED_PeerInformation *pinfo,
 | 
			
		||||
          const char *emsg)
 | 
			
		||||
{
 | 
			
		||||
  struct pctx *pc = (struct pctx*) cls;
 | 
			
		||||
 | 
			
		||||
  pc->id = pinfo->result.id;
 | 
			
		||||
 | 
			
		||||
  pids++;
 | 
			
		||||
  if (pids < (PEERS_REQUESTED - 1))
 | 
			
		||||
    return;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got all IDs, starting test\n");
 | 
			
		||||
  test_task = GNUNET_SCHEDULER_add_now (&start_test, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
mst_start_cb () 
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
join_request_cb ()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
mst_message_cb ()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
mst_message_part_cb ()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
slv_message_cb ()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
slv_message_part_cb ()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
slv_connect_cb () 
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
join_decision_cb ()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *
 | 
			
		||||
psyc_ca (void *cls,
 | 
			
		||||
         const struct GNUNET_CONFIGURATION_Handle *cfg)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_PSYC_Message *join_msg = NULL;
 | 
			
		||||
  struct pctx *pc = (struct pctx *) cls;
 | 
			
		||||
 | 
			
		||||
  if (0 == pc->idx)
 | 
			
		||||
  {
 | 
			
		||||
    pc->mst = GNUNET_PSYC_master_start (cfg, channel_key, 
 | 
			
		||||
                                        GNUNET_PSYC_CHANNEL_PRIVATE,
 | 
			
		||||
                                        &mst_start_cb, &join_request_cb,
 | 
			
		||||
                                        &mst_message_cb, &mst_message_part_cb,
 | 
			
		||||
                                        NULL);
 | 
			
		||||
    return pc->mst;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pc->slv = GNUNET_PSYC_slave_join (cfg, &channel_pub_key, slave_key,
 | 
			
		||||
                                    GNUNET_PSYC_SLAVE_JOIN_NONE,
 | 
			
		||||
                                    &pid, 0, NULL, &slv_message_cb, 
 | 
			
		||||
                                    &slv_message_part_cb,
 | 
			
		||||
                                    &slv_connect_cb, &join_decision_cb, 
 | 
			
		||||
                                    NULL, join_msg);
 | 
			
		||||
  return pc->slv;
 | 
			
		||||
} 
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
psyc_da (void *cls,
 | 
			
		||||
         void *op_result)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Disconnected from service.\n");
 | 
			
		||||
} 
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
service_connect (void *cls,
 | 
			
		||||
                 struct GNUNET_TESTBED_Operation *op,
 | 
			
		||||
                 void *ca_result,
 | 
			
		||||
                 const char *emsg)
 | 
			
		||||
{
 | 
			
		||||
  struct pctx *pc = (struct pctx *) cls;
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "Connected to service\n");
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (NULL != ca_result);
 | 
			
		||||
 | 
			
		||||
  // FIXME: we need a simple service handle to connect to the service, then 
 | 
			
		||||
  // get peer information and AFTER that make PSYC ops. Compare to CADET. 
 | 
			
		||||
  pc->psyc = ca_result;
 | 
			
		||||
 | 
			
		||||
  GNUNET_TESTBED_peer_get_information (pc->peer, 
 | 
			
		||||
                                       GNUNET_TESTBED_PIT_IDENTITY, 
 | 
			
		||||
                                       pinfo_cb, pc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
testbed_master (void *cls,
 | 
			
		||||
     struct GNUNET_TESTBED_RunHandle *h,
 | 
			
		||||
     unsigned int num_peers,
 | 
			
		||||
     struct GNUNET_TESTBED_Peer **p,
 | 
			
		||||
     unsigned int links_succeeded,
 | 
			
		||||
     unsigned int links_failed)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to testbed_master()\n");
 | 
			
		||||
 | 
			
		||||
  // Create ctx for peers
 | 
			
		||||
  pctx = GNUNET_new_array (PEERS_REQUESTED, struct pctx*);
 | 
			
		||||
  for (int i = 0; i<PEERS_REQUESTED; i++) 
 | 
			
		||||
  {
 | 
			
		||||
    pctx[i] = GNUNET_new (struct pctx);
 | 
			
		||||
    pctx[i]->idx = i;
 | 
			
		||||
    pctx[i]->peer = p[i];
 | 
			
		||||
    pctx[i]->id = NULL;
 | 
			
		||||
    pctx[i]->mst = NULL;
 | 
			
		||||
    pctx[i]->op = NULL;
 | 
			
		||||
    pctx[i]->test_ok = GNUNET_NO;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  channel_key = GNUNET_CRYPTO_eddsa_key_create ();
 | 
			
		||||
  slave_key = GNUNET_CRYPTO_ecdsa_key_create ();
 | 
			
		||||
 | 
			
		||||
  GNUNET_CRYPTO_eddsa_key_get_public (channel_key, &channel_pub_key);
 | 
			
		||||
  GNUNET_CRYPTO_ecdsa_key_get_public (slave_key, &slave_pub_key);
 | 
			
		||||
 | 
			
		||||
  pctx[0]->op = 
 | 
			
		||||
    GNUNET_TESTBED_service_connect (NULL, p[0], "psyc", service_connect, 
 | 
			
		||||
                                    pctx[0], psyc_ca, psyc_da, pctx[0]);
 | 
			
		||||
 | 
			
		||||
  GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); 
 | 
			
		||||
 | 
			
		||||
  timeout_tid = 
 | 
			
		||||
    GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5),
 | 
			
		||||
                                  &timeout_task, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
  int ret;
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "test\n");
 | 
			
		||||
 | 
			
		||||
  result = GNUNET_SYSERR;
 | 
			
		||||
 | 
			
		||||
  ret = GNUNET_TESTBED_test_run ("test-psyc2", "test_psyc.conf",
 | 
			
		||||
                                 PEERS_REQUESTED, 0LL, NULL, NULL, 
 | 
			
		||||
                                 testbed_master, NULL);
 | 
			
		||||
 | 
			
		||||
  if ((GNUNET_OK != ret) || (GNUNET_OK != result))
 | 
			
		||||
    return 1;
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* end of test-psyc2.c */
 | 
			
		||||
							
								
								
									
										282
									
								
								src/psyc/test_psyc_api_join.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										282
									
								
								src/psyc/test_psyc_api_join.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,282 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of GNUnet
 | 
			
		||||
 * Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file psyc/test_psyc_api_join.c
 | 
			
		||||
 * @brief Testbed test for the PSYC API.
 | 
			
		||||
 * @author xrs
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Lessons Learned:
 | 
			
		||||
 * - define topology in config
 | 
			
		||||
 * - psyc slave join needs part to end (same with master)
 | 
			
		||||
 * - GNUNET_SCHEDULER_add_delayed return value will outdate at call time
 | 
			
		||||
 * - main can not contain GNUNET_log()
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "gnunet_crypto_lib.h"
 | 
			
		||||
#include "gnunet_common.h"
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
#include "gnunet_testbed_service.h"
 | 
			
		||||
#include "gnunet_psyc_util_lib.h"
 | 
			
		||||
#include "gnunet_psyc_service.h"
 | 
			
		||||
#include "psyc_test_lib.h"
 | 
			
		||||
 | 
			
		||||
static struct pctx PEERS[2];
 | 
			
		||||
 | 
			
		||||
static int pids;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
shutdown_task (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  if (NULL != timeout_task_id) {
 | 
			
		||||
    GNUNET_SCHEDULER_cancel (timeout_task_id);
 | 
			
		||||
    timeout_task_id = NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (int i=0;i<2;i++) {
 | 
			
		||||
    GNUNET_free (PEERS[i].channel_pub_key);
 | 
			
		||||
 | 
			
		||||
    if (NULL != PEERS[i].psyc)
 | 
			
		||||
    {
 | 
			
		||||
      if (0 == i) 
 | 
			
		||||
        GNUNET_PSYC_master_stop (PEERS[i].psyc, GNUNET_NO, NULL, NULL);
 | 
			
		||||
      else 
 | 
			
		||||
        GNUNET_PSYC_slave_part (PEERS[i].psyc, GNUNET_NO, NULL, NULL);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (int i=0;i<MAX_TESTBED_OPS;i++)
 | 
			
		||||
    if (NULL != op[i])
 | 
			
		||||
      GNUNET_TESTBED_operation_done (op[i]);
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shut down!\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
timeout_task (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Timeout!\n");
 | 
			
		||||
 | 
			
		||||
  timeout_task_id = NULL;
 | 
			
		||||
 | 
			
		||||
  result = GNUNET_SYSERR;
 | 
			
		||||
  GNUNET_SCHEDULER_shutdown ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
join_decision_cb (void *cls,
 | 
			
		||||
                  const struct GNUNET_PSYC_JoinDecisionMessage *dcsn,
 | 
			
		||||
                  int is_admitted,
 | 
			
		||||
                  const struct GNUNET_PSYC_Message *join_msg)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 | 
			
		||||
              "slave: got join decision: %s\n", 
 | 
			
		||||
              (GNUNET_YES == is_admitted) ? "admitted":"rejected");
 | 
			
		||||
 | 
			
		||||
  result = (GNUNET_YES == is_admitted) ? GNUNET_OK : GNUNET_SYSERR;
 | 
			
		||||
 | 
			
		||||
  GNUNET_SCHEDULER_shutdown ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
join_request_cb (void *cls,
 | 
			
		||||
                 const struct GNUNET_PSYC_JoinRequestMessage *req,
 | 
			
		||||
                 const struct GNUNET_CRYPTO_EcdsaPublicKey *slave_key,
 | 
			
		||||
                 const struct GNUNET_PSYC_Message *join_msg,
 | 
			
		||||
                 struct GNUNET_PSYC_JoinHandle *jh)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_HashCode slave_key_hash;
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "master: got join request.\n");
 | 
			
		||||
 | 
			
		||||
  GNUNET_CRYPTO_hash (slave_key, sizeof (*slave_key), &slave_key_hash);
 | 
			
		||||
 | 
			
		||||
  GNUNET_PSYC_join_decision (jh, GNUNET_YES, 0, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
psyc_da ()
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "disconnect form PSYC service\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *
 | 
			
		||||
psyc_ca (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) 
 | 
			
		||||
{
 | 
			
		||||
  struct pctx *peer = (struct pctx*) cls;
 | 
			
		||||
 | 
			
		||||
  // Case: master role
 | 
			
		||||
  if (0 == peer->idx) {
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting to PSYC as master ...\n");
 | 
			
		||||
 | 
			
		||||
    peer->psyc = (struct GNUNET_PSYC_Master *) 
 | 
			
		||||
      GNUNET_PSYC_master_start (cfg,
 | 
			
		||||
                                peer->channel_key,
 | 
			
		||||
                                GNUNET_PSYC_CHANNEL_PRIVATE,
 | 
			
		||||
                                NULL,
 | 
			
		||||
                                join_request_cb,
 | 
			
		||||
                                NULL,
 | 
			
		||||
                                NULL,
 | 
			
		||||
                                cls);
 | 
			
		||||
    return peer->psyc;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting to PSYC as slave ...\n");
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_PSYC_Environment *env = GNUNET_PSYC_env_create ();
 | 
			
		||||
  GNUNET_PSYC_env_add (env, GNUNET_PSYC_OP_ASSIGN, "_foo", "bar baz", 7);
 | 
			
		||||
  GNUNET_PSYC_env_add (env, GNUNET_PSYC_OP_ASSIGN, "_foo_bar", "foo bar baz", 11);
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_PSYC_Message *
 | 
			
		||||
    join_msg = GNUNET_PSYC_message_create ("_request_join", env, "some data", 40);
 | 
			
		||||
 | 
			
		||||
  peer->psyc = (struct GNUNET_PSYC_Slave *)
 | 
			
		||||
    GNUNET_PSYC_slave_join (cfg,
 | 
			
		||||
                            peer->channel_pub_key,
 | 
			
		||||
                            peer->id_key,
 | 
			
		||||
                            GNUNET_PSYC_SLAVE_JOIN_NONE,
 | 
			
		||||
                            peer->peer_id_master, 
 | 
			
		||||
                            0,
 | 
			
		||||
                            NULL,
 | 
			
		||||
                            NULL,
 | 
			
		||||
                            NULL,
 | 
			
		||||
                            NULL,
 | 
			
		||||
                            join_decision_cb,
 | 
			
		||||
                            cls,
 | 
			
		||||
                            join_msg);
 | 
			
		||||
 | 
			
		||||
  GNUNET_free (join_msg);
 | 
			
		||||
  peer->channel = GNUNET_PSYC_slave_get_channel (peer->psyc);
 | 
			
		||||
  GNUNET_PSYC_env_destroy (env);
 | 
			
		||||
 | 
			
		||||
  return peer->psyc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
service_connect (void *cls,
 | 
			
		||||
                 struct GNUNET_TESTBED_Operation *op,
 | 
			
		||||
                 void *ca_result,
 | 
			
		||||
                 const char *emsg)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_assert (NULL != ca_result);
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to the service\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
connect_to_services (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  for (int i = 0; i < 2; i++)
 | 
			
		||||
  {
 | 
			
		||||
    PEERS[i].peer_id_master = PEERS[0].peer_id;
 | 
			
		||||
 | 
			
		||||
    op[op_cnt++] = 
 | 
			
		||||
      GNUNET_TESTBED_service_connect (NULL, PEERS[i].testbed_peer, "psyc", 
 | 
			
		||||
                                      &service_connect, &PEERS[i], &psyc_ca, 
 | 
			
		||||
                                      &psyc_da, &PEERS[i]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
pinfo_cb (void *cls,
 | 
			
		||||
          struct GNUNET_TESTBED_Operation *operation,
 | 
			
		||||
          const struct GNUNET_TESTBED_PeerInformation *pinfo,
 | 
			
		||||
          const char *emsg)
 | 
			
		||||
{
 | 
			
		||||
  struct pctx *peer = (struct pctx*) cls;
 | 
			
		||||
 | 
			
		||||
  peer->peer_id = pinfo->result.id;
 | 
			
		||||
 | 
			
		||||
  pids++;
 | 
			
		||||
  if (pids < 2)
 | 
			
		||||
    return;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Got all IDs, starting test\n");
 | 
			
		||||
 | 
			
		||||
  GNUNET_SCHEDULER_add_now (&connect_to_services, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
testbed_master (void *cls,
 | 
			
		||||
     struct GNUNET_TESTBED_RunHandle *h,
 | 
			
		||||
     unsigned int num_peers,
 | 
			
		||||
     struct GNUNET_TESTBED_Peer **p,
 | 
			
		||||
     unsigned int links_succeeded,
 | 
			
		||||
     unsigned int links_failed)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key = NULL;
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connected to testbed_master\n");
 | 
			
		||||
 | 
			
		||||
  // Set up shutdown logic
 | 
			
		||||
  GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); 
 | 
			
		||||
  timeout_task_id = 
 | 
			
		||||
    GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 15),
 | 
			
		||||
                                  &timeout_task, NULL);
 | 
			
		||||
  GNUNET_assert (NULL != timeout_task_id);
 | 
			
		||||
 | 
			
		||||
  // Set up channel key
 | 
			
		||||
  channel_key = GNUNET_CRYPTO_eddsa_key_create ();
 | 
			
		||||
  GNUNET_assert (NULL != channel_key);
 | 
			
		||||
  
 | 
			
		||||
  // Set up information contexts for peers
 | 
			
		||||
  for (int i=0 ; i < 2 ; i++)
 | 
			
		||||
  {
 | 
			
		||||
    PEERS[i].idx = i;
 | 
			
		||||
    PEERS[i].testbed_peer = p[i];
 | 
			
		||||
 | 
			
		||||
    // Create "egos"
 | 
			
		||||
    PEERS[i].id_key = GNUNET_CRYPTO_ecdsa_key_create ();
 | 
			
		||||
 | 
			
		||||
    // Set up channel keys shared by master and slave
 | 
			
		||||
    PEERS[i].channel_key = channel_key; 
 | 
			
		||||
 | 
			
		||||
    PEERS[i].channel_pub_key = 
 | 
			
		||||
      GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
 | 
			
		||||
    // Get public key 
 | 
			
		||||
    GNUNET_CRYPTO_eddsa_key_get_public (PEERS[i].channel_key, 
 | 
			
		||||
                                        PEERS[i].channel_pub_key);
 | 
			
		||||
    // Get peerinfo
 | 
			
		||||
    op[op_cnt++] = 
 | 
			
		||||
      GNUNET_TESTBED_peer_get_information (p[i], 
 | 
			
		||||
                                           GNUNET_TESTBED_PIT_IDENTITY, 
 | 
			
		||||
                                           pinfo_cb, &PEERS[i]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int 
 | 
			
		||||
main (int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
  int ret; 
 | 
			
		||||
 | 
			
		||||
  ret = GNUNET_TESTBED_test_run ("test_psyc_api_join", "test_psyc.conf",
 | 
			
		||||
                                 2, 0LL, NULL, NULL, 
 | 
			
		||||
                                 &testbed_master, NULL);
 | 
			
		||||
 | 
			
		||||
  if ( (GNUNET_OK != ret) || (GNUNET_OK != result) )
 | 
			
		||||
    return 1;
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* end of test_psyc_api_join.c */
 | 
			
		||||
							
								
								
									
										5
									
								
								src/psycstore/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/psycstore/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
gnunet-service-psycstore
 | 
			
		||||
test_plugin_psycstore_mysql
 | 
			
		||||
test_plugin_psycstore_sqlite
 | 
			
		||||
test_plugin_psycstore_postgres
 | 
			
		||||
test_psycstore
 | 
			
		||||
							
								
								
									
										155
									
								
								src/psycstore/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								src/psycstore/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,155 @@
 | 
			
		||||
# This Makefile.am is in the public domain
 | 
			
		||||
AM_CPPFLAGS = -I$(top_srcdir)/src/include
 | 
			
		||||
 | 
			
		||||
plugindir = $(libdir)/gnunet
 | 
			
		||||
 | 
			
		||||
pkgcfgdir= $(pkgdatadir)/config.d/
 | 
			
		||||
 | 
			
		||||
libexecdir= $(pkglibdir)/libexec/
 | 
			
		||||
 | 
			
		||||
pkgcfg_DATA = \
 | 
			
		||||
  psycstore.conf
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if MINGW
 | 
			
		||||
 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if USE_COVERAGE
 | 
			
		||||
  AM_CFLAGS = --coverage -O0
 | 
			
		||||
  XLIB = -lgcov
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if HAVE_MYSQL
 | 
			
		||||
MYSQL_PLUGIN = libgnunet_plugin_psycstore_mysql.la
 | 
			
		||||
if HAVE_TESTING
 | 
			
		||||
MYSQL_TESTS = test_plugin_psycstore_mysql
 | 
			
		||||
endif
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if HAVE_POSTGRESQL
 | 
			
		||||
POSTGRES_PLUGIN = libgnunet_plugin_psycstore_postgres.la
 | 
			
		||||
if HAVE_TESTING
 | 
			
		||||
POSTGRES_TESTS = test_plugin_psycstore_postgres
 | 
			
		||||
endif
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if HAVE_SQLITE
 | 
			
		||||
SQLITE_PLUGIN = libgnunet_plugin_psycstore_sqlite.la
 | 
			
		||||
if HAVE_TESTING
 | 
			
		||||
SQLITE_TESTS = test_plugin_psycstore_sqlite
 | 
			
		||||
endif
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
lib_LTLIBRARIES = libgnunetpsycstore.la
 | 
			
		||||
 | 
			
		||||
libgnunetpsycstore_la_SOURCES = \
 | 
			
		||||
  psycstore_api.c \
 | 
			
		||||
  psycstore.h
 | 
			
		||||
libgnunetpsycstore_la_LIBADD = \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la \
 | 
			
		||||
  $(GN_LIBINTL) $(XLIB)
 | 
			
		||||
libgnunetpsycstore_la_LDFLAGS = \
 | 
			
		||||
  $(GN_LIB_LDFLAGS)  $(WINFLAGS) \
 | 
			
		||||
  -version-info 0:0:0
 | 
			
		||||
 | 
			
		||||
bin_PROGRAMS =
 | 
			
		||||
 | 
			
		||||
libexec_PROGRAMS = \
 | 
			
		||||
 gnunet-service-psycstore
 | 
			
		||||
 | 
			
		||||
gnunet_service_psycstore_SOURCES = \
 | 
			
		||||
 gnunet-service-psycstore.c
 | 
			
		||||
gnunet_service_psycstore_LDADD = \
 | 
			
		||||
  $(top_builddir)/src/statistics/libgnunetstatistics.la \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la \
 | 
			
		||||
  $(top_builddir)/src/psycutil/libgnunetpsycutil.la \
 | 
			
		||||
  $(GN_LIBINTL)
 | 
			
		||||
 | 
			
		||||
plugin_LTLIBRARIES = \
 | 
			
		||||
  $(SQLITE_PLUGIN) \
 | 
			
		||||
  $(MYSQL_PLUGIN) \
 | 
			
		||||
  $(POSTGRES_PLUGIN)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
libgnunet_plugin_psycstore_mysql_la_SOURCES = \
 | 
			
		||||
  plugin_psycstore_mysql.c
 | 
			
		||||
libgnunet_plugin_psycstore_mysql_la_LIBADD = \
 | 
			
		||||
  libgnunetpsycstore.la  \
 | 
			
		||||
  $(top_builddir)/src/my/libgnunetmy.la \
 | 
			
		||||
  $(top_builddir)/src/mysql/libgnunetmysql.la \
 | 
			
		||||
  $(top_builddir)/src/statistics/libgnunetstatistics.la \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
 | 
			
		||||
  $(LTLIBINTL)
 | 
			
		||||
libgnunet_plugin_psycstore_mysql_la_LDFLAGS = \
 | 
			
		||||
 $(GN_PLUGIN_LDFLAGS)
 | 
			
		||||
 | 
			
		||||
libgnunet_plugin_psycstore_postgres_la_SOURCES = \
 | 
			
		||||
  plugin_psycstore_postgres.c
 | 
			
		||||
libgnunet_plugin_psycstore_postgres_la_LIBADD = \
 | 
			
		||||
  libgnunetpsycstore.la  \
 | 
			
		||||
  $(top_builddir)/src/pq/libgnunetpq.la  \
 | 
			
		||||
  $(top_builddir)/src/statistics/libgnunetstatistics.la \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lpq \
 | 
			
		||||
  $(LTLIBINTL)
 | 
			
		||||
libgnunet_plugin_psycstore_postgres_la_LDFLAGS = \
 | 
			
		||||
  $(GN_PLUGIN_LDFLAGS) $(POSTGRESQL_LDFLAGS)
 | 
			
		||||
libgnunet_plugin_psycstore_postgres_la_CPPFLAGS = \
 | 
			
		||||
  $(POSTGRESQL_CPPFLAGS) $(AM_CPPFLAGS)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
libgnunet_plugin_psycstore_sqlite_la_SOURCES = \
 | 
			
		||||
  plugin_psycstore_sqlite.c
 | 
			
		||||
libgnunet_plugin_psycstore_sqlite_la_LIBADD = \
 | 
			
		||||
  libgnunetpsycstore.la  \
 | 
			
		||||
  $(top_builddir)/src/statistics/libgnunetstatistics.la \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) -lsqlite3 \
 | 
			
		||||
  $(LTLIBINTL)
 | 
			
		||||
libgnunet_plugin_psycstore_sqlite_la_LDFLAGS = \
 | 
			
		||||
 $(GN_PLUGIN_LDFLAGS)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if HAVE_SQLITE
 | 
			
		||||
if HAVE_TESTING
 | 
			
		||||
check_PROGRAMS = \
 | 
			
		||||
 $(SQLITE_TESTS) \
 | 
			
		||||
 $(MYSQL_TESTS) \
 | 
			
		||||
 $(POSTGRES_TESTS) \
 | 
			
		||||
 test_psycstore
 | 
			
		||||
endif
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if ENABLE_TEST_RUN
 | 
			
		||||
AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
 | 
			
		||||
TESTS = $(check_PROGRAMS)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
test_psycstore_SOURCES = \
 | 
			
		||||
 test_psycstore.c
 | 
			
		||||
test_psycstore_LDADD = \
 | 
			
		||||
  libgnunetpsycstore.la \
 | 
			
		||||
  $(top_builddir)/src/testing/libgnunettesting.la \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = \
 | 
			
		||||
  test_psycstore.conf
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
test_plugin_psycstore_sqlite_SOURCES = \
 | 
			
		||||
 test_plugin_psycstore.c
 | 
			
		||||
test_plugin_psycstore_sqlite_LDADD = \
 | 
			
		||||
  $(top_builddir)/src/testing/libgnunettesting.la \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la
 | 
			
		||||
 | 
			
		||||
test_plugin_psycstore_mysql_SOURCES = \
 | 
			
		||||
 test_plugin_psycstore.c
 | 
			
		||||
test_plugin_psycstore_mysql_LDADD = \
 | 
			
		||||
  $(top_builddir)/src/testing/libgnunettesting.la \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la
 | 
			
		||||
 | 
			
		||||
test_plugin_psycstore_postgres_SOURCES = \
 | 
			
		||||
 test_plugin_psycstore.c
 | 
			
		||||
test_plugin_psycstore_postgres_LDADD = \
 | 
			
		||||
 $(top_builddir)/src/testing/libgnunettesting.la \
 | 
			
		||||
 $(top_builddir)/src/util/libgnunetutil.la
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1049
									
								
								src/psycstore/gnunet-service-psycstore.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1049
									
								
								src/psycstore/gnunet-service-psycstore.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1960
									
								
								src/psycstore/plugin_psycstore_mysql.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1960
									
								
								src/psycstore/plugin_psycstore_mysql.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1530
									
								
								src/psycstore/plugin_psycstore_postgres.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1530
									
								
								src/psycstore/plugin_psycstore_postgres.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1948
									
								
								src/psycstore/plugin_psycstore_sqlite.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1948
									
								
								src/psycstore/plugin_psycstore_sqlite.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										28
									
								
								src/psycstore/psycstore.conf.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/psycstore/psycstore.conf.in
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
[psycstore]
 | 
			
		||||
START_ON_DEMAND = @START_ON_DEMAND@
 | 
			
		||||
BINARY = gnunet-service-psycstore
 | 
			
		||||
 | 
			
		||||
UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-psycstore.sock
 | 
			
		||||
UNIX_MATCH_UID = YES
 | 
			
		||||
UNIX_MATCH_GID = YES
 | 
			
		||||
 | 
			
		||||
@UNIXONLY@PORT = 2111
 | 
			
		||||
HOSTNAME = localhost
 | 
			
		||||
ACCEPT_FROM = 127.0.0.1;
 | 
			
		||||
ACCEPT_FROM6 = ::1;
 | 
			
		||||
 | 
			
		||||
DATABASE = sqlite
 | 
			
		||||
 | 
			
		||||
[psycstore-sqlite]
 | 
			
		||||
FILENAME = $GNUNET_DATA_HOME/psycstore/sqlite.db
 | 
			
		||||
 | 
			
		||||
[psycstore-mysql]
 | 
			
		||||
DATABASE = gnunet
 | 
			
		||||
CONFIG = ~/.my.cnf
 | 
			
		||||
# USER = gnunet
 | 
			
		||||
# PASSWORD =
 | 
			
		||||
# HOST = localhost
 | 
			
		||||
# PORT = 3306
 | 
			
		||||
 | 
			
		||||
[psycstore-postgres]
 | 
			
		||||
CONFIG = connect_timeout=10; dbname=gnunet
 | 
			
		||||
							
								
								
									
										520
									
								
								src/psycstore/psycstore.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										520
									
								
								src/psycstore/psycstore.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,520 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of GNUnet
 | 
			
		||||
 * Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file psycstore/psycstore.h
 | 
			
		||||
 * @brief Common type definitions for the PSYCstore service and API.
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef GNUNET_PSYCSTORE_H
 | 
			
		||||
#define GNUNET_PSYCSTORE_H
 | 
			
		||||
 | 
			
		||||
#include "gnunet_common.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GNUNET_NETWORK_STRUCT_BEGIN
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Answer from service to client about last operation.
 | 
			
		||||
 */
 | 
			
		||||
struct OperationResult
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t reserved GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operation ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**lowed by
 | 
			
		||||
   * Status code for the operation.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t result_code GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /* followed by 0-terminated error message (on error) */
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Answer from service to client about master counters.
 | 
			
		||||
 *
 | 
			
		||||
 * @see GNUNET_PSYCSTORE_counters_get()
 | 
			
		||||
 */
 | 
			
		||||
struct CountersResult
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_COUNTERS
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Status code for the operation:
 | 
			
		||||
   * #GNUNET_OK: success, counter values are returned.
 | 
			
		||||
   * #GNUNET_NO: no message has been sent to the channel yet.
 | 
			
		||||
   * #GNUNET_SYSERR: an error occurred.
 | 
			
		||||
   */
 | 
			
		||||
  uint32_t result_code GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operation ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  uint64_t max_fragment_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  uint64_t max_message_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  uint64_t max_group_generation GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  uint64_t max_state_message_id GNUNET_PACKED;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Answer from service to client containing a message fragment.
 | 
			
		||||
 */
 | 
			
		||||
struct FragmentResult
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t psycstore_flags GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operation ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /* Followed by GNUNET_MULTICAST_MessageHeader */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Answer from service to client containing a state variable.
 | 
			
		||||
 */
 | 
			
		||||
struct StateResult
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_RESULT_CODE
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint16_t name_size GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  uint16_t reserved GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operation ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /* Followed by name and value */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generic operation request.
 | 
			
		||||
 */
 | 
			
		||||
struct OperationRequest
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t reserved GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operation ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPublicKey channel_key;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see GNUNET_PSYCSTORE_membership_store()
 | 
			
		||||
 */
 | 
			
		||||
struct MembershipStoreRequest
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_MEMBERSHIP_STORE
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t reserved GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operation ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Channel's public key.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPublicKey channel_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Slave's public key.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaPublicKey slave_key;
 | 
			
		||||
 | 
			
		||||
  uint64_t announced_at GNUNET_PACKED;
 | 
			
		||||
  uint64_t effective_since GNUNET_PACKED;
 | 
			
		||||
  uint64_t group_generation GNUNET_PACKED;
 | 
			
		||||
  uint8_t did_join;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see GNUNET_PSYCSTORE_membership_test()
 | 
			
		||||
 */
 | 
			
		||||
struct MembershipTestRequest
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_MEMBERSHIP_TEST
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t reserved GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operation ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Channel's public key.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPublicKey channel_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Slave's public key.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaPublicKey slave_key;
 | 
			
		||||
 | 
			
		||||
  uint64_t message_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  uint64_t group_generation GNUNET_PACKED;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see GNUNET_PSYCSTORE_fragment_store()
 | 
			
		||||
 */
 | 
			
		||||
struct FragmentStoreRequest
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_FRAGMENT_STORE
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * enum GNUNET_PSYCSTORE_MessageFlags
 | 
			
		||||
   */
 | 
			
		||||
  uint32_t psycstore_flags GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Channel's public key.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPublicKey channel_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operation ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id;
 | 
			
		||||
 | 
			
		||||
  /* Followed by fragment */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see GNUNET_PSYCSTORE_fragment_get()
 | 
			
		||||
 */
 | 
			
		||||
struct FragmentGetRequest
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_FRAGMENT_GET
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t reserved GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operation ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Channel's public key.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPublicKey channel_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Slave's public key.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaPublicKey slave_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * First fragment ID to request.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t first_fragment_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Last fragment ID to request.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t last_fragment_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Maximum number of fragments to retrieve.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t fragment_limit GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Do membership test with @a slave_key before returning fragment?
 | 
			
		||||
   * #GNUNET_YES or #GNUNET_NO
 | 
			
		||||
   */
 | 
			
		||||
  uint8_t do_membership_test;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see GNUNET_PSYCSTORE_message_get()
 | 
			
		||||
 */
 | 
			
		||||
struct MessageGetRequest
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_MESSAGE_GET
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t reserved GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operation ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Channel's public key.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPublicKey channel_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Slave's public key.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaPublicKey slave_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * First message ID to request.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t first_message_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Last message ID to request.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t last_message_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Maximum number of messages to retrieve.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t message_limit GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Maximum number of fragments to retrieve.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t fragment_limit GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Do membership test with @a slave_key before returning fragment?
 | 
			
		||||
   * #GNUNET_YES or #GNUNET_NO
 | 
			
		||||
   */
 | 
			
		||||
  uint8_t do_membership_test;
 | 
			
		||||
 | 
			
		||||
  /* Followed by method_prefix */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see GNUNET_PSYCSTORE_message_get_fragment()
 | 
			
		||||
 */
 | 
			
		||||
struct MessageGetFragmentRequest
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_MESSAGE_FRAGMENT_GET
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t reserved GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operation ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Channel's public key.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPublicKey channel_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Slave's public key.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaPublicKey slave_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Requested message ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t message_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Requested fragment offset.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t fragment_offset GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Do membership test with @a slave_key before returning fragment?
 | 
			
		||||
   * #GNUNET_YES or #GNUNET_NO
 | 
			
		||||
   */
 | 
			
		||||
  uint8_t do_membership_test;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see GNUNET_PSYCSTORE_state_hash_update()
 | 
			
		||||
 */
 | 
			
		||||
struct StateHashUpdateRequest
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_STATE_HASH_UPDATE
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  uint32_t reserved GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operation ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Channel's public key.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPublicKey channel_key;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_HashCode hash;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
enum StateOpFlags
 | 
			
		||||
{
 | 
			
		||||
  STATE_OP_FIRST = 1 << 0,
 | 
			
		||||
  STATE_OP_LAST = 1 << 1
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see GNUNET_PSYCSTORE_state_modify()
 | 
			
		||||
 */
 | 
			
		||||
struct StateModifyRequest
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_STATE_MODIFY
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operation ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ID of the message to apply the state changes in.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t message_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * State delta of the message with ID @a message_id.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t state_delta GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Channel's public key.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPublicKey channel_key;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @see GNUNET_PSYCSTORE_state_sync()
 | 
			
		||||
 */
 | 
			
		||||
struct StateSyncRequest
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Type: GNUNET_MESSAGE_TYPE_PSYCSTORE_STATE_SYNC
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_MessageHeader header;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Size of name, including NUL terminator.
 | 
			
		||||
   */
 | 
			
		||||
  uint16_t name_size GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * OR'd StateOpFlags
 | 
			
		||||
   */
 | 
			
		||||
  uint8_t flags;
 | 
			
		||||
 | 
			
		||||
  uint8_t reserved;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operation ID.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t op_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ID of the message that contains the state_hash PSYC header variable.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t state_hash_message_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ID of the last stateful message before @a state_hash_message_id.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t max_state_message_id GNUNET_PACKED;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Channel's public key.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EddsaPublicKey channel_key;
 | 
			
		||||
 | 
			
		||||
  /* Followed by NUL-terminated name, then the value. */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GNUNET_NETWORK_STRUCT_END
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										1285
									
								
								src/psycstore/psycstore_api.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1285
									
								
								src/psycstore/psycstore_api.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										532
									
								
								src/psycstore/test_plugin_psycstore.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										532
									
								
								src/psycstore/test_plugin_psycstore.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,532 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of GNUnet
 | 
			
		||||
 * Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 * @author Christian Grothoff
 | 
			
		||||
 *
 | 
			
		||||
 * @file
 | 
			
		||||
 * Test for the PSYCstore plugins.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
#include "gnunet_testing_lib.h"
 | 
			
		||||
#include "gnunet_psycstore_plugin.h"
 | 
			
		||||
#include "gnunet_psycstore_service.h"
 | 
			
		||||
#include "gnunet_multicast_service.h"
 | 
			
		||||
 | 
			
		||||
#define DEBUG_PSYCSTORE GNUNET_EXTRA_LOGGING
 | 
			
		||||
#if DEBUG_PSYCSTORE
 | 
			
		||||
# define LOG_LEVEL "DEBUG"
 | 
			
		||||
#else
 | 
			
		||||
# define LOG_LEVEL "WARNING"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define C2ARG(str) str, (sizeof (str) - 1)
 | 
			
		||||
 | 
			
		||||
#define LOG(kind,...)                                                          \
 | 
			
		||||
  GNUNET_log_from (kind, "test-plugin-psycstore", __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
static int ok;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Name of plugin under test.
 | 
			
		||||
 */
 | 
			
		||||
static const char *plugin_name;
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key;
 | 
			
		||||
static struct GNUNET_CRYPTO_EcdsaPrivateKey *slave_key;
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_CRYPTO_EddsaPublicKey channel_pub_key;
 | 
			
		||||
static struct GNUNET_CRYPTO_EcdsaPublicKey slave_pub_key;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Function called when the service shuts down.  Unloads our psycstore
 | 
			
		||||
 * plugin.
 | 
			
		||||
 *
 | 
			
		||||
 * @param api api to unload
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
unload_plugin (struct GNUNET_PSYCSTORE_PluginFunctions *api)
 | 
			
		||||
{
 | 
			
		||||
  char *libname;
 | 
			
		||||
 | 
			
		||||
  GNUNET_asprintf (&libname, "libgnunet_plugin_psycstore_%s", plugin_name);
 | 
			
		||||
  GNUNET_break (NULL == GNUNET_PLUGIN_unload (libname, api));
 | 
			
		||||
  GNUNET_free (libname);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Load the psycstore plugin.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cfg configuration to pass
 | 
			
		||||
 * @return NULL on error
 | 
			
		||||
 */
 | 
			
		||||
static struct GNUNET_PSYCSTORE_PluginFunctions *
 | 
			
		||||
load_plugin (const struct GNUNET_CONFIGURATION_Handle *cfg)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_PSYCSTORE_PluginFunctions *ret;
 | 
			
		||||
  char *libname;
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Loading `%s' psycstore plugin\n"),
 | 
			
		||||
              plugin_name);
 | 
			
		||||
  GNUNET_asprintf (&libname, "libgnunet_plugin_psycstore_%s", plugin_name);
 | 
			
		||||
  if (NULL == (ret = GNUNET_PLUGIN_load (libname, (void*) cfg)))
 | 
			
		||||
  {
 | 
			
		||||
    FPRINTF (stderr, "Failed to load plugin `%s'!\n", plugin_name);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  GNUNET_free (libname);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define MAX_MSG 16
 | 
			
		||||
 | 
			
		||||
struct FragmentClosure
 | 
			
		||||
{
 | 
			
		||||
  uint8_t n;
 | 
			
		||||
  uint64_t flags[MAX_MSG];
 | 
			
		||||
  struct GNUNET_MULTICAST_MessageHeader *msg[MAX_MSG];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
fragment_cb (void *cls, struct GNUNET_MULTICAST_MessageHeader *msg2,
 | 
			
		||||
             enum GNUNET_PSYCSTORE_MessageFlags flags)
 | 
			
		||||
{
 | 
			
		||||
  struct FragmentClosure *fcls = cls;
 | 
			
		||||
  struct GNUNET_MULTICAST_MessageHeader *msg1;
 | 
			
		||||
  uint64_t flags1;
 | 
			
		||||
  int ret;
 | 
			
		||||
 | 
			
		||||
  if (fcls->n >= MAX_MSG)
 | 
			
		||||
    {
 | 
			
		||||
      GNUNET_break (0);
 | 
			
		||||
      return GNUNET_SYSERR;
 | 
			
		||||
    }
 | 
			
		||||
  msg1 = fcls->msg[fcls->n];
 | 
			
		||||
  flags1 = fcls->flags[fcls->n++];
 | 
			
		||||
  if (NULL == msg1)
 | 
			
		||||
    {
 | 
			
		||||
      GNUNET_break (0);
 | 
			
		||||
      return GNUNET_SYSERR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (flags1 == flags && msg1->header.size == msg2->header.size
 | 
			
		||||
      && 0 == memcmp (msg1, msg2, ntohs (msg1->header.size)))
 | 
			
		||||
  {
 | 
			
		||||
    LOG (GNUNET_ERROR_TYPE_DEBUG, "Fragment %llu matches\n",
 | 
			
		||||
         GNUNET_ntohll (msg1->fragment_id));
 | 
			
		||||
    ret = GNUNET_YES;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    LOG (GNUNET_ERROR_TYPE_ERROR, "Fragment %llu differs\n",
 | 
			
		||||
         GNUNET_ntohll (msg1->fragment_id));
 | 
			
		||||
    ret = GNUNET_SYSERR;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  GNUNET_free (msg2);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct StateClosure {
 | 
			
		||||
  size_t n;
 | 
			
		||||
  char *name[16];
 | 
			
		||||
  void *value[16];
 | 
			
		||||
  size_t value_size[16];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
state_cb (void *cls, const char *name, const void *value, uint32_t value_size)
 | 
			
		||||
{
 | 
			
		||||
  struct StateClosure *scls = cls;
 | 
			
		||||
  const void *val = scls->value[scls->n]; // FIXME: check for n out-of-bounds FIRST!
 | 
			
		||||
  size_t val_size = scls->value_size[scls->n++];
 | 
			
		||||
 | 
			
		||||
  /* FIXME: check name */
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_DEBUG,
 | 
			
		||||
       "  name = %s, value_size = %u\n",
 | 
			
		||||
       name, value_size);
 | 
			
		||||
 | 
			
		||||
  return GNUNET_YES;
 | 
			
		||||
  return value_size == val_size && 0 == memcmp (value, val, val_size)
 | 
			
		||||
    ? GNUNET_YES
 | 
			
		||||
    : GNUNET_SYSERR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
run (void *cls, char *const *args, const char *cfgfile,
 | 
			
		||||
     const struct GNUNET_CONFIGURATION_Handle *cfg)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_PSYCSTORE_PluginFunctions *db;
 | 
			
		||||
 | 
			
		||||
  ok = 1;
 | 
			
		||||
  db = load_plugin (cfg);
 | 
			
		||||
  if (NULL == db)
 | 
			
		||||
  {
 | 
			
		||||
    FPRINTF (stderr,
 | 
			
		||||
             "%s",
 | 
			
		||||
	     "Failed to initialize PSYCstore.  "
 | 
			
		||||
             "Database likely not setup, skipping test.\n");
 | 
			
		||||
    ok = 77;
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Store & test membership */
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "MEMBERSHIP\n");
 | 
			
		||||
 | 
			
		||||
  channel_key = GNUNET_CRYPTO_eddsa_key_create ();
 | 
			
		||||
  slave_key = GNUNET_CRYPTO_ecdsa_key_create ();
 | 
			
		||||
 | 
			
		||||
  GNUNET_CRYPTO_eddsa_key_get_public (channel_key,
 | 
			
		||||
                                                  &channel_pub_key);
 | 
			
		||||
  GNUNET_CRYPTO_ecdsa_key_get_public (slave_key, &slave_pub_key);
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "membership_store()\n");
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->membership_store (db->cls, &channel_pub_key,
 | 
			
		||||
                                                    &slave_pub_key, GNUNET_YES,
 | 
			
		||||
                                                    4, 2, 1));
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "membership_test()\n");
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_YES == db->membership_test (db->cls, &channel_pub_key,
 | 
			
		||||
                                                    &slave_pub_key, 4));
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_YES == db->membership_test (db->cls, &channel_pub_key,
 | 
			
		||||
                                                    &slave_pub_key, 2));
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_NO == db->membership_test (db->cls, &channel_pub_key,
 | 
			
		||||
                                                   &slave_pub_key, 1));
 | 
			
		||||
 | 
			
		||||
  /* Store & get messages */
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "MESSAGES\n");
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_MULTICAST_MessageHeader *msg
 | 
			
		||||
    = GNUNET_malloc (sizeof (*msg) + sizeof (channel_pub_key));
 | 
			
		||||
  GNUNET_assert (msg != NULL);
 | 
			
		||||
 | 
			
		||||
  msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE);
 | 
			
		||||
  msg->header.size = htons (sizeof (*msg) + sizeof (channel_pub_key));
 | 
			
		||||
 | 
			
		||||
  uint64_t fragment_id = INT64_MAX - 1;
 | 
			
		||||
  msg->fragment_id = GNUNET_htonll (fragment_id);
 | 
			
		||||
 | 
			
		||||
  uint64_t message_id = INT64_MAX - 10;
 | 
			
		||||
  msg->message_id = GNUNET_htonll (message_id);
 | 
			
		||||
 | 
			
		||||
  uint64_t group_generation = INT64_MAX - 3;
 | 
			
		||||
  msg->group_generation = GNUNET_htonll (group_generation);
 | 
			
		||||
 | 
			
		||||
  msg->hop_counter = htonl (9);
 | 
			
		||||
  msg->fragment_offset = GNUNET_htonll (0);
 | 
			
		||||
  msg->flags = htonl (GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT);
 | 
			
		||||
 | 
			
		||||
  GNUNET_memcpy (&msg[1], &channel_pub_key, sizeof (channel_pub_key));
 | 
			
		||||
 | 
			
		||||
  msg->purpose.size = htonl (ntohs (msg->header.size)
 | 
			
		||||
                             - sizeof (msg->header)
 | 
			
		||||
                             - sizeof (msg->hop_counter)
 | 
			
		||||
                             - sizeof (msg->signature));
 | 
			
		||||
  msg->purpose.purpose = htonl (234);
 | 
			
		||||
  GNUNET_assert (GNUNET_OK ==
 | 
			
		||||
                 GNUNET_CRYPTO_eddsa_sign (channel_key, &msg->purpose, &msg->signature));
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "fragment_store()\n");
 | 
			
		||||
 | 
			
		||||
  struct FragmentClosure fcls = { 0 };
 | 
			
		||||
  fcls.n = 0;
 | 
			
		||||
  fcls.msg[0] = msg;
 | 
			
		||||
  fcls.flags[0] = GNUNET_PSYCSTORE_MESSAGE_STATE;
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (
 | 
			
		||||
    GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg,
 | 
			
		||||
                                     fcls.flags[0]));
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "fragment_get(%" PRIu64 ")\n", fragment_id);
 | 
			
		||||
 | 
			
		||||
  uint64_t ret_frags = 0;
 | 
			
		||||
  GNUNET_assert (
 | 
			
		||||
    GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key,
 | 
			
		||||
                                   fragment_id, fragment_id,
 | 
			
		||||
                                   &ret_frags, fragment_cb, &fcls));
 | 
			
		||||
  GNUNET_assert (fcls.n == 1);
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "message_get_fragment()\n");
 | 
			
		||||
 | 
			
		||||
  fcls.n = 0;
 | 
			
		||||
  GNUNET_assert (
 | 
			
		||||
    GNUNET_OK == db->message_get_fragment (db->cls, &channel_pub_key,
 | 
			
		||||
                                           GNUNET_ntohll (msg->message_id),
 | 
			
		||||
                                           GNUNET_ntohll (msg->fragment_offset),
 | 
			
		||||
                                           fragment_cb, &fcls));
 | 
			
		||||
  GNUNET_assert (fcls.n == 1);
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "message_add_flags()\n");
 | 
			
		||||
  GNUNET_assert (
 | 
			
		||||
    GNUNET_OK == db->message_add_flags (db->cls, &channel_pub_key,
 | 
			
		||||
                                        GNUNET_ntohll (msg->message_id),
 | 
			
		||||
                                        GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED));
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "fragment_get(%" PRIu64 ")\n", fragment_id);
 | 
			
		||||
 | 
			
		||||
  fcls.n = 0;
 | 
			
		||||
  fcls.flags[0] |= GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED;
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (
 | 
			
		||||
    GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key,
 | 
			
		||||
                                   fragment_id, fragment_id,
 | 
			
		||||
                                   &ret_frags, fragment_cb, &fcls));
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (fcls.n == 1);
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "fragment_store()\n");
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_MULTICAST_MessageHeader *msg1
 | 
			
		||||
    = GNUNET_malloc (sizeof (*msg1) + sizeof (channel_pub_key));
 | 
			
		||||
 | 
			
		||||
  GNUNET_memcpy (msg1, msg, sizeof (*msg1) + sizeof (channel_pub_key));
 | 
			
		||||
 | 
			
		||||
  msg1->fragment_id = GNUNET_htonll (INT64_MAX);
 | 
			
		||||
  msg1->fragment_offset = GNUNET_htonll (32768);
 | 
			
		||||
 | 
			
		||||
  fcls.n = 0;
 | 
			
		||||
  fcls.msg[1] = msg1;
 | 
			
		||||
  fcls.flags[1] = GNUNET_PSYCSTORE_MESSAGE_STATE_HASH;
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg1,
 | 
			
		||||
                                                  fcls.flags[1]));
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "message_get()\n");
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (
 | 
			
		||||
    GNUNET_OK == db->message_get (db->cls, &channel_pub_key,
 | 
			
		||||
                                  message_id, message_id, 0,
 | 
			
		||||
                                  &ret_frags, fragment_cb, &fcls));
 | 
			
		||||
  GNUNET_assert (fcls.n == 2 && ret_frags == 2);
 | 
			
		||||
 | 
			
		||||
  /* Message counters */
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "counters_message_get()\n");
 | 
			
		||||
 | 
			
		||||
  fragment_id = 0;
 | 
			
		||||
  message_id = 0;
 | 
			
		||||
  group_generation = 0;
 | 
			
		||||
  GNUNET_assert (
 | 
			
		||||
    GNUNET_OK == db->counters_message_get (db->cls, &channel_pub_key,
 | 
			
		||||
                                           &fragment_id, &message_id,
 | 
			
		||||
                                           &group_generation)
 | 
			
		||||
    && fragment_id == GNUNET_ntohll (msg1->fragment_id)
 | 
			
		||||
    && message_id == GNUNET_ntohll (msg1->message_id)
 | 
			
		||||
    && group_generation == GNUNET_ntohll (msg1->group_generation));
 | 
			
		||||
 | 
			
		||||
  /* Modify state */
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "STATE\n");
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "state_modify_*()\n");
 | 
			
		||||
 | 
			
		||||
  message_id = GNUNET_ntohll (fcls.msg[0]->message_id) + 1;
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_modify_begin (db->cls, &channel_pub_key,
 | 
			
		||||
                                                      message_id, 0));
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_modify_op (db->cls, &channel_pub_key,
 | 
			
		||||
                                                   GNUNET_PSYC_OP_ASSIGN,
 | 
			
		||||
                                                   "_foo",
 | 
			
		||||
                                                   C2ARG("one two three")));
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_modify_op (db->cls, &channel_pub_key,
 | 
			
		||||
                                                   GNUNET_PSYC_OP_ASSIGN,
 | 
			
		||||
                                                   "_foo_bar", slave_key,
 | 
			
		||||
                                                   sizeof (*slave_key)));
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_modify_end (db->cls, &channel_pub_key,
 | 
			
		||||
                                                    message_id));
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "state_get()\n");
 | 
			
		||||
 | 
			
		||||
  struct StateClosure scls = { 0 };
 | 
			
		||||
  scls.n = 0;
 | 
			
		||||
  scls.value[0] = "one two three";
 | 
			
		||||
  scls.value_size[0] = strlen ("one two three");
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_get (db->cls, &channel_pub_key, "_foo",
 | 
			
		||||
                                             state_cb, &scls));
 | 
			
		||||
  GNUNET_assert (scls.n == 1);
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "state_get_prefix()\n");
 | 
			
		||||
 | 
			
		||||
  scls.n = 0;
 | 
			
		||||
  scls.value[1] = slave_key;
 | 
			
		||||
  scls.value_size[1] = sizeof (*slave_key);
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_get_prefix (db->cls, &channel_pub_key,
 | 
			
		||||
                                                    "_foo", state_cb, &scls));
 | 
			
		||||
  GNUNET_assert (scls.n == 2);
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "state_get_signed()\n");
 | 
			
		||||
 | 
			
		||||
  scls.n = 0;
 | 
			
		||||
  GNUNET_assert (GNUNET_NO == db->state_get_signed (db->cls, &channel_pub_key,
 | 
			
		||||
                                                    state_cb, &scls));
 | 
			
		||||
  GNUNET_assert (scls.n == 0);
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "state_update_signed()\n");
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_update_signed (db->cls,
 | 
			
		||||
                                                       &channel_pub_key));
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "state_get_signed()\n");
 | 
			
		||||
 | 
			
		||||
  scls.n = 0;
 | 
			
		||||
  GNUNET_assert (GNUNET_YES == db->state_get_signed (db->cls, &channel_pub_key,
 | 
			
		||||
                                                     state_cb, &scls));
 | 
			
		||||
  GNUNET_assert (scls.n == 2);
 | 
			
		||||
 | 
			
		||||
  /* State counters */
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "counters_state_get()\n");
 | 
			
		||||
 | 
			
		||||
  uint64_t max_state_msg_id = 0;
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->counters_state_get (db->cls, &channel_pub_key,
 | 
			
		||||
                                                      &max_state_msg_id)
 | 
			
		||||
                 && max_state_msg_id == message_id);
 | 
			
		||||
 | 
			
		||||
  /* State sync */
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "state_sync_*()\n");
 | 
			
		||||
 | 
			
		||||
  scls.n = 0;
 | 
			
		||||
  scls.value[0] = channel_key;
 | 
			
		||||
  scls.value_size[0] = sizeof (*channel_key);
 | 
			
		||||
  scls.value[1] = "three two one";
 | 
			
		||||
  scls.value_size[1] = strlen ("three two one");
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_sync_begin (db->cls, &channel_pub_key));
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_sync_assign (db->cls, &channel_pub_key,
 | 
			
		||||
                                                     "_sync_bar", scls.value[0],
 | 
			
		||||
                                                     scls.value_size[0]));
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_sync_assign (db->cls, &channel_pub_key,
 | 
			
		||||
                                                     "_sync_foo", scls.value[1],
 | 
			
		||||
                                                     scls.value_size[1]));
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_sync_end (db->cls, &channel_pub_key,
 | 
			
		||||
                                                  max_state_msg_id,
 | 
			
		||||
                                                  INT64_MAX - 5));
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_NO == db->state_get_prefix (db->cls, &channel_pub_key,
 | 
			
		||||
                                                    "_foo", state_cb, &scls));
 | 
			
		||||
  GNUNET_assert (scls.n == 0);
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_get_prefix (db->cls, &channel_pub_key,
 | 
			
		||||
                                                    "_sync", state_cb, &scls));
 | 
			
		||||
  GNUNET_assert (scls.n == 2);
 | 
			
		||||
 | 
			
		||||
  scls.n = 0;
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_get_signed (db->cls, &channel_pub_key,
 | 
			
		||||
                                                    state_cb, &scls));
 | 
			
		||||
  GNUNET_assert (scls.n == 2);
 | 
			
		||||
 | 
			
		||||
  /* Modify state after sync */
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "state_modify_*()\n");
 | 
			
		||||
 | 
			
		||||
  message_id = GNUNET_ntohll (fcls.msg[0]->message_id) + 6;
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_modify_begin (db->cls, &channel_pub_key,
 | 
			
		||||
                                                      message_id,
 | 
			
		||||
                                                      message_id - max_state_msg_id));
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_modify_op (db->cls, &channel_pub_key,
 | 
			
		||||
                                                   GNUNET_PSYC_OP_ASSIGN,
 | 
			
		||||
                                                   "_sync_foo",
 | 
			
		||||
                                                   C2ARG("five six seven")));
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_modify_end (db->cls, &channel_pub_key,
 | 
			
		||||
                                                    message_id));
 | 
			
		||||
 | 
			
		||||
  /* Reset state */
 | 
			
		||||
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_INFO, "state_reset()\n");
 | 
			
		||||
 | 
			
		||||
  scls.n = 0;
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == db->state_reset (db->cls, &channel_pub_key));
 | 
			
		||||
  GNUNET_assert (scls.n == 0);
 | 
			
		||||
 | 
			
		||||
  ok = 0;
 | 
			
		||||
 | 
			
		||||
  if (NULL != channel_key)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_free (channel_key);
 | 
			
		||||
    channel_key = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  if (NULL != slave_key)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_free (slave_key);
 | 
			
		||||
    slave_key = NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  unload_plugin (db);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
  char cfg_name[128];
 | 
			
		||||
  char *const xargv[] = {
 | 
			
		||||
    "test-plugin-psycstore",
 | 
			
		||||
    "-c", cfg_name,
 | 
			
		||||
    "-L", LOG_LEVEL,
 | 
			
		||||
    NULL
 | 
			
		||||
  };
 | 
			
		||||
  struct GNUNET_GETOPT_CommandLineOption options[] = {
 | 
			
		||||
    GNUNET_GETOPT_OPTION_END
 | 
			
		||||
  };
 | 
			
		||||
  GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-psycstore-sqlite");
 | 
			
		||||
  GNUNET_log_setup ("test-plugin-psycstore", LOG_LEVEL, NULL);
 | 
			
		||||
  plugin_name = GNUNET_TESTING_get_testname_from_underscore (argv[0]);
 | 
			
		||||
  GNUNET_snprintf (cfg_name, sizeof (cfg_name), "test_plugin_psycstore_%s.conf",
 | 
			
		||||
                   plugin_name);
 | 
			
		||||
  GNUNET_PROGRAM_run ((sizeof (xargv) / sizeof (char *)) - 1, xargv,
 | 
			
		||||
                      "test-plugin-psycstore", "nohelp", options, &run, NULL);
 | 
			
		||||
 | 
			
		||||
  if ( (0 != ok) &&
 | 
			
		||||
       (77 != ok) )
 | 
			
		||||
    FPRINTF (stderr, "Missed some testcases: %d\n", ok);
 | 
			
		||||
 | 
			
		||||
#if ! DEBUG_PSYCSTORE
 | 
			
		||||
  GNUNET_DISK_directory_remove ("/tmp/gnunet-test-plugin-psycstore-sqlite");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return ok;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* end of test_plugin_psycstore.c */
 | 
			
		||||
							
								
								
									
										7
									
								
								src/psycstore/test_plugin_psycstore_mysql.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/psycstore/test_plugin_psycstore_mysql.conf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
			
		||||
[psycstore-mysql]
 | 
			
		||||
DATABASE = test
 | 
			
		||||
# CONFIG = ~/.my.cnf
 | 
			
		||||
# USER = gnunet
 | 
			
		||||
# PASSWORD =
 | 
			
		||||
# HOST = localhost
 | 
			
		||||
# PORT = 3306
 | 
			
		||||
							
								
								
									
										2
									
								
								src/psycstore/test_plugin_psycstore_postgres.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/psycstore/test_plugin_psycstore_postgres.conf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
[psycstore-postgres]
 | 
			
		||||
CONFIG = connect_timeout=10; dbname=template1
 | 
			
		||||
							
								
								
									
										2
									
								
								src/psycstore/test_plugin_psycstore_sqlite.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/psycstore/test_plugin_psycstore_sqlite.conf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
[psycstore-sqlite]
 | 
			
		||||
FILENAME = $GNUNET_TMP/gnunet-test-plugin-psycstore-sqlite/sqlite.db
 | 
			
		||||
							
								
								
									
										586
									
								
								src/psycstore/test_psycstore.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										586
									
								
								src/psycstore/test_psycstore.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,586 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of GNUnet
 | 
			
		||||
 * Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file psycstore/test_psycstore.c
 | 
			
		||||
 * @brief Test for the PSYCstore service.
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 * @author Christian Grothoff
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
#include "gnunet_common.h"
 | 
			
		||||
#include "gnunet_testing_lib.h"
 | 
			
		||||
#include "gnunet_psycstore_service.h"
 | 
			
		||||
 | 
			
		||||
#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return value from 'main'.
 | 
			
		||||
 */
 | 
			
		||||
static int res;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle to PSYCstore service.
 | 
			
		||||
 */
 | 
			
		||||
static struct GNUNET_PSYCSTORE_Handle *h;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle to PSYCstore operation.
 | 
			
		||||
 */
 | 
			
		||||
static struct GNUNET_PSYCSTORE_OperationHandle *op;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle for task for timeout termination.
 | 
			
		||||
 */
 | 
			
		||||
static struct GNUNET_SCHEDULER_Task *end_badly_task;
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_CRYPTO_EddsaPrivateKey *channel_key;
 | 
			
		||||
static struct GNUNET_CRYPTO_EcdsaPrivateKey *slave_key;
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_CRYPTO_EddsaPublicKey channel_pub_key;
 | 
			
		||||
static struct GNUNET_CRYPTO_EcdsaPublicKey slave_pub_key;
 | 
			
		||||
 | 
			
		||||
static struct FragmentClosure
 | 
			
		||||
{
 | 
			
		||||
  uint8_t n;
 | 
			
		||||
  uint8_t n_expected;
 | 
			
		||||
  uint64_t flags[16];
 | 
			
		||||
  struct GNUNET_MULTICAST_MessageHeader *msg[16];
 | 
			
		||||
} fcls;
 | 
			
		||||
 | 
			
		||||
struct StateClosure {
 | 
			
		||||
  size_t n;
 | 
			
		||||
  char *name[16];
 | 
			
		||||
  void *value[16];
 | 
			
		||||
  size_t value_size[16];
 | 
			
		||||
} scls;
 | 
			
		||||
 | 
			
		||||
static struct GNUNET_PSYC_Modifier modifiers[16];
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Clean up all resources used.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
cleanup ()
 | 
			
		||||
{
 | 
			
		||||
  if (NULL != op)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_PSYCSTORE_operation_cancel (op);
 | 
			
		||||
    op = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  if (NULL != h)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_PSYCSTORE_disconnect (h);
 | 
			
		||||
    h = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  if (NULL != channel_key)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_free (channel_key);
 | 
			
		||||
    channel_key = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  if (NULL != slave_key)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_free (slave_key);
 | 
			
		||||
    slave_key = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  GNUNET_SCHEDULER_shutdown ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Terminate the testcase (failure).
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls NULL
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
end_badly (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  res = 1;
 | 
			
		||||
  cleanup ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Terminate the testcase (success).
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls NULL
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
end_normally (void *cls)
 | 
			
		||||
{
 | 
			
		||||
  res = 0;
 | 
			
		||||
  cleanup ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Finish the testcase (successfully).
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
end ()
 | 
			
		||||
{
 | 
			
		||||
  if (NULL != end_badly_task)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_SCHEDULER_cancel (end_badly_task);
 | 
			
		||||
    end_badly_task = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
 | 
			
		||||
				&end_normally, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
state_reset_result (void *cls,
 | 
			
		||||
                    int64_t result,
 | 
			
		||||
                    const char *err_msg,
 | 
			
		||||
                    uint16_t err_msg_size)
 | 
			
		||||
{
 | 
			
		||||
  op = NULL;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
 | 
			
		||||
              "state_reset_result:\t%d\n",
 | 
			
		||||
              (int) result);
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == result);
 | 
			
		||||
 | 
			
		||||
  op = GNUNET_PSYCSTORE_state_reset (h, &channel_pub_key,
 | 
			
		||||
                                     &state_reset_result, cls);
 | 
			
		||||
  GNUNET_PSYCSTORE_operation_cancel (op);
 | 
			
		||||
  op = NULL;
 | 
			
		||||
  end ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
state_result (void *cls,
 | 
			
		||||
              const char *name,
 | 
			
		||||
              const void *value,
 | 
			
		||||
              uint32_t value_size)
 | 
			
		||||
{
 | 
			
		||||
  struct StateClosure *scls = cls;
 | 
			
		||||
  const char *nam = scls->name[scls->n];
 | 
			
		||||
  const void *val = scls->value[scls->n];
 | 
			
		||||
  size_t val_size = scls->value_size[scls->n++];
 | 
			
		||||
 | 
			
		||||
  if (value_size == val_size
 | 
			
		||||
      && 0 == memcmp (value, val, val_size)
 | 
			
		||||
      && 0 == strcmp (name, nam))
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
 | 
			
		||||
                "  variable %s matches\n",
 | 
			
		||||
                name);
 | 
			
		||||
    return GNUNET_YES;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
 | 
			
		||||
                "  variable %s differs\nReceived: %.*s\nExpected: %.*s\n",
 | 
			
		||||
                name, (int) value_size, (char*) value, (int) val_size, (char*) val);
 | 
			
		||||
    GNUNET_assert (0);
 | 
			
		||||
    return GNUNET_SYSERR;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
state_get_prefix_result (void *cls, int64_t result,
 | 
			
		||||
                         const char *err_msg, uint16_t err_msg_size)
 | 
			
		||||
{
 | 
			
		||||
  struct StateClosure *scls = cls;
 | 
			
		||||
  op = NULL;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "state_get_prefix_result:\t%ld\n", (long int) result);
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == result && 2 == scls->n);
 | 
			
		||||
 | 
			
		||||
  op = GNUNET_PSYCSTORE_state_reset (h, &channel_pub_key,
 | 
			
		||||
                                     &state_reset_result, cls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
state_get_result (void *cls, int64_t result,
 | 
			
		||||
                  const char *err_msg, uint16_t err_msg_size)
 | 
			
		||||
{
 | 
			
		||||
  op = NULL;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "state_get_result:\t%ld\n", (long int) result);
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == result);
 | 
			
		||||
 | 
			
		||||
  scls.n = 0;
 | 
			
		||||
 | 
			
		||||
  scls.name[0] = "_sync_bar";
 | 
			
		||||
  scls.value[0] = "ten eleven twelve";
 | 
			
		||||
  scls.value_size[0] = sizeof ("ten eleven twelve") - 1;
 | 
			
		||||
 | 
			
		||||
  scls.name[1] = "_sync_foo";
 | 
			
		||||
  scls.value[1] = "three two one";
 | 
			
		||||
  scls.value_size[1] = sizeof ("three two one") - 1;
 | 
			
		||||
 | 
			
		||||
  op = GNUNET_PSYCSTORE_state_get_prefix (h, &channel_pub_key, "_sync",
 | 
			
		||||
                                          &state_result,
 | 
			
		||||
                                          &state_get_prefix_result, &scls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
counters_result (void *cls, int status, uint64_t max_fragment_id,
 | 
			
		||||
                 uint64_t max_message_id, uint64_t max_group_generation,
 | 
			
		||||
                 uint64_t max_state_message_id)
 | 
			
		||||
{
 | 
			
		||||
  struct FragmentClosure *fcls = cls;
 | 
			
		||||
  int result = 0;
 | 
			
		||||
  op = NULL;
 | 
			
		||||
 | 
			
		||||
  if (GNUNET_OK == status
 | 
			
		||||
      && max_fragment_id == GNUNET_ntohll (fcls->msg[2]->fragment_id)
 | 
			
		||||
      && max_message_id == GNUNET_ntohll (fcls->msg[2]->message_id)
 | 
			
		||||
      && max_group_generation == GNUNET_ntohll (fcls->msg[2]->group_generation)
 | 
			
		||||
      && max_state_message_id == GNUNET_ntohll (fcls->msg[0]->message_id))
 | 
			
		||||
    result = 1;
 | 
			
		||||
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "counters_get:\t%d\n", result);
 | 
			
		||||
  GNUNET_assert (result == 1);
 | 
			
		||||
 | 
			
		||||
  scls.n = 0;
 | 
			
		||||
  scls.name[0] = "_sync_bar";
 | 
			
		||||
  scls.value[0] = "ten eleven twelve";
 | 
			
		||||
  scls.value_size[0] = sizeof ("ten eleven twelve") - 1;
 | 
			
		||||
 | 
			
		||||
  op = GNUNET_PSYCSTORE_state_get (h, &channel_pub_key, "_sync_bar_x_yy_zzz",
 | 
			
		||||
                                   &state_result, &state_get_result, &scls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
state_modify_result (void *cls, int64_t result,
 | 
			
		||||
                     const char *err_msg, uint16_t err_msg_size)
 | 
			
		||||
{
 | 
			
		||||
  op = NULL;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "state_modify_result:\t%ld\n", (long int) result);
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == result);
 | 
			
		||||
 | 
			
		||||
  op = GNUNET_PSYCSTORE_counters_get (h, &channel_pub_key,
 | 
			
		||||
                                      &counters_result, cls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
state_sync_result (void *cls, int64_t result,
 | 
			
		||||
                   const char *err_msg, uint16_t err_msg_size)
 | 
			
		||||
{
 | 
			
		||||
  struct FragmentClosure *fcls = cls;
 | 
			
		||||
  op = NULL;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "state_sync_result:\t%ld\n", (long int) result);
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == result);
 | 
			
		||||
 | 
			
		||||
  op = GNUNET_PSYCSTORE_state_modify (h, &channel_pub_key,
 | 
			
		||||
                                      GNUNET_ntohll (fcls->msg[0]->message_id),
 | 
			
		||||
                                      0, state_modify_result, fcls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
fragment_result (void *cls,
 | 
			
		||||
                 struct GNUNET_MULTICAST_MessageHeader *msg,
 | 
			
		||||
                 enum GNUNET_PSYCSTORE_MessageFlags flags)
 | 
			
		||||
{
 | 
			
		||||
  struct FragmentClosure *fcls = cls;
 | 
			
		||||
  GNUNET_assert (fcls->n < fcls->n_expected);
 | 
			
		||||
  struct GNUNET_MULTICAST_MessageHeader *msg0 = fcls->msg[fcls->n];
 | 
			
		||||
  uint64_t flags0 = fcls->flags[fcls->n++];
 | 
			
		||||
 | 
			
		||||
  if (flags == flags0 && msg->header.size == msg0->header.size
 | 
			
		||||
      && 0 == memcmp (msg, msg0, ntohs (msg->header.size)))
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "  fragment %" PRIu64 " matches\n",
 | 
			
		||||
                GNUNET_ntohll (msg->fragment_id));
 | 
			
		||||
    return GNUNET_YES;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
 | 
			
		||||
                "  fragment differs: expected %" PRIu64 ", got %" PRIu64 "\n",
 | 
			
		||||
                GNUNET_ntohll (msg0->fragment_id),
 | 
			
		||||
                GNUNET_ntohll (msg->fragment_id));
 | 
			
		||||
    GNUNET_assert (0);
 | 
			
		||||
    return GNUNET_SYSERR;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
message_get_latest_result (void *cls, int64_t result,
 | 
			
		||||
                           const char *err_msg, uint16_t err_msg_size)
 | 
			
		||||
{
 | 
			
		||||
  struct FragmentClosure *fcls = cls;
 | 
			
		||||
  op = NULL;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "message_get_latest:\t%ld\n", (long int) result);
 | 
			
		||||
  GNUNET_assert (0 < result && fcls->n == fcls->n_expected);
 | 
			
		||||
 | 
			
		||||
  modifiers[0] = (struct GNUNET_PSYC_Modifier) {
 | 
			
		||||
    .oper = '=',
 | 
			
		||||
    .name = "_sync_foo",
 | 
			
		||||
    .value = "three two one",
 | 
			
		||||
    .value_size = sizeof ("three two one") - 1
 | 
			
		||||
  };
 | 
			
		||||
  modifiers[1] = (struct GNUNET_PSYC_Modifier) {
 | 
			
		||||
    .oper = '=',
 | 
			
		||||
    .name = "_sync_bar",
 | 
			
		||||
    .value = "ten eleven twelve",
 | 
			
		||||
    .value_size = sizeof ("ten eleven twelve") - 1
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  op = GNUNET_PSYCSTORE_state_sync (h, &channel_pub_key,
 | 
			
		||||
                                    GNUNET_ntohll (fcls->msg[0]->message_id) + 1,
 | 
			
		||||
                                    GNUNET_ntohll (fcls->msg[0]->message_id) + 2,
 | 
			
		||||
                                    2, modifiers, state_sync_result, fcls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
message_get_result (void *cls, int64_t result,
 | 
			
		||||
                    const char *err_msg, uint16_t err_msg_size)
 | 
			
		||||
{
 | 
			
		||||
  struct FragmentClosure *fcls = cls;
 | 
			
		||||
  op = NULL;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "message_get:\t%ld\n", (long int) result);
 | 
			
		||||
  GNUNET_assert (0 < result && fcls->n == fcls->n_expected);
 | 
			
		||||
 | 
			
		||||
  fcls->n = 0;
 | 
			
		||||
  fcls->n_expected = 3;
 | 
			
		||||
  op = GNUNET_PSYCSTORE_message_get_latest (h, &channel_pub_key, &slave_pub_key,
 | 
			
		||||
                                            1, "", &fragment_result,
 | 
			
		||||
                                            &message_get_latest_result, fcls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
message_get_fragment_result (void *cls, int64_t result,
 | 
			
		||||
                             const char *err_msg, uint16_t err_msg_size)
 | 
			
		||||
{
 | 
			
		||||
  struct FragmentClosure *fcls = cls;
 | 
			
		||||
  op = NULL;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "message_get_fragment:\t%ld\n", (long int) result);
 | 
			
		||||
  GNUNET_assert (0 < result && fcls->n == fcls->n_expected);
 | 
			
		||||
 | 
			
		||||
  fcls->n = 0;
 | 
			
		||||
  fcls->n_expected = 3;
 | 
			
		||||
  uint64_t message_id = GNUNET_ntohll (fcls->msg[0]->message_id);
 | 
			
		||||
  op = GNUNET_PSYCSTORE_message_get (h, &channel_pub_key, &slave_pub_key,
 | 
			
		||||
                                     message_id, message_id, 0, "",
 | 
			
		||||
                                     &fragment_result,
 | 
			
		||||
                                     &message_get_result, fcls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
fragment_get_latest_result (void *cls, int64_t result,
 | 
			
		||||
                            const char *err_msg, uint16_t err_msg_size)
 | 
			
		||||
{
 | 
			
		||||
  struct FragmentClosure *fcls = cls;
 | 
			
		||||
  op = NULL;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "fragment_get_latest:\t%ld\n", (long int) result);
 | 
			
		||||
  GNUNET_assert (0 < result && fcls->n == fcls->n_expected);
 | 
			
		||||
 | 
			
		||||
  fcls->n = 1;
 | 
			
		||||
  fcls->n_expected = 2;
 | 
			
		||||
  op = GNUNET_PSYCSTORE_message_get_fragment (h, &channel_pub_key, &slave_pub_key,
 | 
			
		||||
                                              GNUNET_ntohll (fcls->msg[1]->message_id),
 | 
			
		||||
                                              GNUNET_ntohll (fcls->msg[1]->fragment_offset),
 | 
			
		||||
                                              &fragment_result,
 | 
			
		||||
                                              &message_get_fragment_result, fcls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
fragment_get_result (void *cls, int64_t result,
 | 
			
		||||
                     const char *err_msg, uint16_t err_msg_size)
 | 
			
		||||
{
 | 
			
		||||
  struct FragmentClosure *fcls = cls;
 | 
			
		||||
  op = NULL;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
 | 
			
		||||
              "fragment_get:\t%d\n",
 | 
			
		||||
              (int) result);
 | 
			
		||||
  GNUNET_assert (0 < result && fcls->n == fcls->n_expected);
 | 
			
		||||
 | 
			
		||||
  fcls->n = 0;
 | 
			
		||||
  fcls->n_expected = 3;
 | 
			
		||||
  op = GNUNET_PSYCSTORE_fragment_get_latest (h, &channel_pub_key,
 | 
			
		||||
                                             &slave_pub_key, fcls->n_expected,
 | 
			
		||||
                                             &fragment_result,
 | 
			
		||||
                                             &fragment_get_latest_result, fcls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
fragment_store_result (void *cls, int64_t result,
 | 
			
		||||
                       const char *err_msg, uint16_t err_msg_size)
 | 
			
		||||
{
 | 
			
		||||
  op = NULL;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "fragment_store:\t%ld\n", (long int) result);
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == result);
 | 
			
		||||
 | 
			
		||||
  if ((intptr_t) cls == GNUNET_YES)
 | 
			
		||||
  { /* last fragment */
 | 
			
		||||
    fcls.n = 0;
 | 
			
		||||
    fcls.n_expected = 1;
 | 
			
		||||
    uint64_t fragment_id = GNUNET_ntohll (fcls.msg[0]->fragment_id);
 | 
			
		||||
    op = GNUNET_PSYCSTORE_fragment_get (h, &channel_pub_key, &slave_pub_key,
 | 
			
		||||
                                        fragment_id, fragment_id,
 | 
			
		||||
                                        &fragment_result,
 | 
			
		||||
                                        &fragment_get_result, &fcls);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
fragment_store ()
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_MULTICAST_MessageHeader *msg;
 | 
			
		||||
  fcls.flags[0] = GNUNET_PSYCSTORE_MESSAGE_STATE;
 | 
			
		||||
  fcls.msg[0] = msg = GNUNET_malloc (sizeof (*msg) + sizeof (channel_pub_key));
 | 
			
		||||
  GNUNET_assert (msg != NULL);
 | 
			
		||||
 | 
			
		||||
  msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE);
 | 
			
		||||
  msg->header.size = htons (sizeof (*msg) + sizeof (channel_pub_key));
 | 
			
		||||
 | 
			
		||||
  msg->hop_counter = htonl (9);
 | 
			
		||||
  msg->fragment_id = GNUNET_htonll (INT64_MAX - 8);
 | 
			
		||||
  msg->fragment_offset = GNUNET_htonll (0);
 | 
			
		||||
  msg->message_id = GNUNET_htonll (INT64_MAX - 10);
 | 
			
		||||
  msg->group_generation = GNUNET_htonll (INT64_MAX - 3);
 | 
			
		||||
  msg->flags = htonl (GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT);
 | 
			
		||||
 | 
			
		||||
  GNUNET_memcpy (&msg[1], &channel_pub_key, sizeof (channel_pub_key));
 | 
			
		||||
 | 
			
		||||
  msg->purpose.size = htonl (ntohs (msg->header.size)
 | 
			
		||||
                             - sizeof (msg->header)
 | 
			
		||||
                             - sizeof (msg->hop_counter)
 | 
			
		||||
                             - sizeof (msg->signature));
 | 
			
		||||
  msg->purpose.purpose = htonl (234);
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (channel_key, &msg->purpose,
 | 
			
		||||
                                                        &msg->signature));
 | 
			
		||||
 | 
			
		||||
  op = GNUNET_PSYCSTORE_fragment_store (h, &channel_pub_key, msg, fcls.flags[0],
 | 
			
		||||
                                        &fragment_store_result, GNUNET_NO);
 | 
			
		||||
 | 
			
		||||
  fcls.flags[1] = GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED;
 | 
			
		||||
  fcls.msg[1] = msg = GNUNET_malloc (sizeof (*msg) + sizeof (channel_pub_key));
 | 
			
		||||
  GNUNET_memcpy (msg, fcls.msg[0], sizeof (*msg) + sizeof (channel_pub_key));
 | 
			
		||||
  msg->fragment_id = GNUNET_htonll (INT64_MAX - 4);
 | 
			
		||||
  msg->fragment_offset = GNUNET_htonll (1024);
 | 
			
		||||
 | 
			
		||||
  op = GNUNET_PSYCSTORE_fragment_store (h, &channel_pub_key, msg, fcls.flags[1],
 | 
			
		||||
                                        &fragment_store_result, GNUNET_NO);
 | 
			
		||||
 | 
			
		||||
  fcls.flags[2] = GNUNET_PSYCSTORE_MESSAGE_STATE_HASH;
 | 
			
		||||
  fcls.msg[2] = msg = GNUNET_malloc (sizeof (*msg) + sizeof (channel_pub_key));
 | 
			
		||||
  GNUNET_memcpy (msg, fcls.msg[1], sizeof (*msg) + sizeof (channel_pub_key));
 | 
			
		||||
  msg->fragment_id = GNUNET_htonll (INT64_MAX);
 | 
			
		||||
  msg->fragment_offset = GNUNET_htonll (16384);
 | 
			
		||||
 | 
			
		||||
  op = GNUNET_PSYCSTORE_fragment_store (h, &channel_pub_key, msg, fcls.flags[2],
 | 
			
		||||
                                        &fragment_store_result, (void *) GNUNET_YES);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
membership_test_result (void *cls, int64_t result,
 | 
			
		||||
                        const char *err_msg, uint16_t err_msg_size)
 | 
			
		||||
{
 | 
			
		||||
  op = NULL;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "membership_test:\t%ld\n", (long int) result);
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == result);
 | 
			
		||||
 | 
			
		||||
  fragment_store ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
membership_store_result (void *cls, int64_t result,
 | 
			
		||||
                         const char *err_msg, uint16_t err_msg_size)
 | 
			
		||||
{
 | 
			
		||||
  op = NULL;
 | 
			
		||||
  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "membership_store:\t%ld\n", (long int) result);
 | 
			
		||||
  GNUNET_assert (GNUNET_OK == result);
 | 
			
		||||
 | 
			
		||||
  op = GNUNET_PSYCSTORE_membership_test (h, &channel_pub_key, &slave_pub_key,
 | 
			
		||||
                                         INT64_MAX - 10, 2,
 | 
			
		||||
                                         &membership_test_result, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Main function of the test, run from scheduler.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls NULL
 | 
			
		||||
 * @param cfg configuration we use (also to connect to PSYCstore service)
 | 
			
		||||
 * @param peer handle to access more of the peer (not used)
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
#if DEBUG_TEST_PSYCSTORE
 | 
			
		||||
run (void *cls, char *const *args, const char *cfgfile,
 | 
			
		||||
     const struct GNUNET_CONFIGURATION_Handle *cfg)
 | 
			
		||||
#else
 | 
			
		||||
run (void *cls,
 | 
			
		||||
     const struct GNUNET_CONFIGURATION_Handle *cfg,
 | 
			
		||||
     struct GNUNET_TESTING_Peer *peer)
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
  end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
 | 
			
		||||
 | 
			
		||||
  h = GNUNET_PSYCSTORE_connect (cfg);
 | 
			
		||||
  GNUNET_assert (NULL != h);
 | 
			
		||||
 | 
			
		||||
  channel_key = GNUNET_CRYPTO_eddsa_key_create ();
 | 
			
		||||
  slave_key = GNUNET_CRYPTO_ecdsa_key_create ();
 | 
			
		||||
 | 
			
		||||
  GNUNET_CRYPTO_eddsa_key_get_public (channel_key, &channel_pub_key);
 | 
			
		||||
  GNUNET_CRYPTO_ecdsa_key_get_public (slave_key, &slave_pub_key);
 | 
			
		||||
 | 
			
		||||
  op = GNUNET_PSYCSTORE_membership_store (h, &channel_pub_key, &slave_pub_key,
 | 
			
		||||
                                          GNUNET_YES, INT64_MAX - 5,
 | 
			
		||||
                                          INT64_MAX - 10, 2,
 | 
			
		||||
                                          &membership_store_result, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
  res = 1;
 | 
			
		||||
#if DEBUG_TEST_PSYCSTORE
 | 
			
		||||
  const struct GNUNET_GETOPT_CommandLineOption opts[] = {
 | 
			
		||||
    GNUNET_GETOPT_OPTION_END
 | 
			
		||||
  };
 | 
			
		||||
  if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "test-psycstore",
 | 
			
		||||
                                       "test-psycstore [options]",
 | 
			
		||||
                                       opts, &run, NULL))
 | 
			
		||||
    return 1;
 | 
			
		||||
#else
 | 
			
		||||
  if (0 != GNUNET_TESTING_service_run ("test-psycstore", "psycstore",
 | 
			
		||||
                                       "test_psycstore.conf", &run, NULL))
 | 
			
		||||
    return 1;
 | 
			
		||||
#endif
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* end of test_psycstore.c */
 | 
			
		||||
							
								
								
									
										8
									
								
								src/psycstore/test_psycstore.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/psycstore/test_psycstore.conf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
[PATHS]
 | 
			
		||||
GNUNET_TEST_HOME = $GNUNET_TMP/test-gnunet-psycstore/
 | 
			
		||||
 | 
			
		||||
[psycstore]
 | 
			
		||||
DATABASE = sqlite
 | 
			
		||||
 | 
			
		||||
[psycstore-sqlite]
 | 
			
		||||
FILENAME = $GNUNET_TEST_HOME/psycstore/sqlite.db
 | 
			
		||||
							
								
								
									
										1
									
								
								src/psycutil/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/psycutil/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
test_psyc_env
 | 
			
		||||
							
								
								
									
										45
									
								
								src/psycutil/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/psycutil/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,45 @@
 | 
			
		||||
# This Makefile.am is in the public domain
 | 
			
		||||
AM_CPPFLAGS = -I$(top_srcdir)/src/include
 | 
			
		||||
 | 
			
		||||
pkgcfgdir= $(pkgdatadir)/config.d/
 | 
			
		||||
 | 
			
		||||
libexecdir= $(pkglibdir)/libexec/
 | 
			
		||||
 | 
			
		||||
if MINGW
 | 
			
		||||
 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if USE_COVERAGE
 | 
			
		||||
  AM_CFLAGS = --coverage -O0
 | 
			
		||||
  XLIB = -lgcov
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
lib_LTLIBRARIES = libgnunetpsycutil.la
 | 
			
		||||
 | 
			
		||||
libgnunetpsycutil_la_SOURCES = \
 | 
			
		||||
  psyc_env.c \
 | 
			
		||||
  psyc_message.c \
 | 
			
		||||
  psyc_slicer.c
 | 
			
		||||
libgnunetpsycutil_la_LIBADD = \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la \
 | 
			
		||||
  $(GN_LIBINTL) $(XLIB)
 | 
			
		||||
libgnunetpsycutil_la_LDFLAGS = \
 | 
			
		||||
  $(GN_LIB_LDFLAGS)  $(WINFLAGS) \
 | 
			
		||||
  -version-info 0:0:0
 | 
			
		||||
 | 
			
		||||
if HAVE_TESTING
 | 
			
		||||
check_PROGRAMS = \
 | 
			
		||||
 test_psyc_env
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if ENABLE_TEST_RUN
 | 
			
		||||
AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
 | 
			
		||||
TESTS = $(check_PROGRAMS)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
test_psyc_env_SOURCES = \
 | 
			
		||||
 test_psyc_env.c
 | 
			
		||||
test_psyc_env_LDADD = \
 | 
			
		||||
  libgnunetpsycutil.la \
 | 
			
		||||
  $(top_builddir)/src/testing/libgnunettesting.la \
 | 
			
		||||
  $(top_builddir)/src/util/libgnunetutil.la
 | 
			
		||||
							
								
								
									
										196
									
								
								src/psycutil/psyc_env.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								src/psycutil/psyc_env.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,196 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of GNUnet.
 | 
			
		||||
 * Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 *
 | 
			
		||||
 * @file
 | 
			
		||||
 * Library providing operations for the @e environment of
 | 
			
		||||
 * PSYC and Social messages.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
#include "gnunet_psyc_env.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Environment for a message.
 | 
			
		||||
 *
 | 
			
		||||
 * Contains modifiers.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_Environment
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_PSYC_Modifier *mod_head;
 | 
			
		||||
  struct GNUNET_PSYC_Modifier *mod_tail;
 | 
			
		||||
  size_t mod_count;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create an environment.
 | 
			
		||||
 *
 | 
			
		||||
 * @return A newly allocated environment.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_Environment *
 | 
			
		||||
GNUNET_PSYC_env_create ()
 | 
			
		||||
{
 | 
			
		||||
  return GNUNET_new (struct GNUNET_PSYC_Environment);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Add a modifier to the environment.
 | 
			
		||||
 *
 | 
			
		||||
 * @param env The environment.
 | 
			
		||||
 * @param oper Operation to perform.
 | 
			
		||||
 * @param name Name of the variable.
 | 
			
		||||
 * @param value Value of the variable.
 | 
			
		||||
 * @param value_size Size of @a value.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_env_add (struct GNUNET_PSYC_Environment *env,
 | 
			
		||||
                     enum GNUNET_PSYC_Operator oper, const char *name,
 | 
			
		||||
                     const void *value, size_t value_size)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_PSYC_Modifier *mod = GNUNET_new (struct GNUNET_PSYC_Modifier);
 | 
			
		||||
  mod->oper = oper;
 | 
			
		||||
  mod->name = name;
 | 
			
		||||
  mod->value = value;
 | 
			
		||||
  mod->value_size = value_size;
 | 
			
		||||
  GNUNET_CONTAINER_DLL_insert_tail (env->mod_head, env->mod_tail, mod);
 | 
			
		||||
  env->mod_count++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the first modifier of the environment.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_Modifier *
 | 
			
		||||
GNUNET_PSYC_env_head (const struct GNUNET_PSYC_Environment *env)
 | 
			
		||||
{
 | 
			
		||||
  return env->mod_head;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the last modifier of the environment.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_Modifier *
 | 
			
		||||
GNUNET_PSYC_env_tail (const struct GNUNET_PSYC_Environment *env)
 | 
			
		||||
{
 | 
			
		||||
  return env->mod_tail;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove a modifier from the environment.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_env_remove (struct GNUNET_PSYC_Environment *env,
 | 
			
		||||
                        struct GNUNET_PSYC_Modifier *mod)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_CONTAINER_DLL_remove (env->mod_head, env->mod_tail, mod);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the modifier at the beginning of an environment and remove it.
 | 
			
		||||
 *
 | 
			
		||||
 * @param env
 | 
			
		||||
 * @param oper
 | 
			
		||||
 * @param name
 | 
			
		||||
 * @param value
 | 
			
		||||
 * @param value_size
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYC_env_shift (struct GNUNET_PSYC_Environment *env,
 | 
			
		||||
                       enum GNUNET_PSYC_Operator *oper, const char **name,
 | 
			
		||||
                       const void **value, size_t *value_size)
 | 
			
		||||
{
 | 
			
		||||
  if (NULL == env->mod_head)
 | 
			
		||||
    return GNUNET_NO;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_PSYC_Modifier *mod = env->mod_head;
 | 
			
		||||
  *oper = mod->oper;
 | 
			
		||||
  *name = mod->name;
 | 
			
		||||
  *value = mod->value;
 | 
			
		||||
  *value_size = mod->value_size;
 | 
			
		||||
 | 
			
		||||
  GNUNET_CONTAINER_DLL_remove (env->mod_head, env->mod_tail, mod);
 | 
			
		||||
  GNUNET_free (mod);
 | 
			
		||||
  env->mod_count--;
 | 
			
		||||
 | 
			
		||||
  return GNUNET_YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Iterate through all modifiers in the environment.
 | 
			
		||||
 *
 | 
			
		||||
 * @param env The environment.
 | 
			
		||||
 * @param it Iterator.
 | 
			
		||||
 * @param it_cls Closure for iterator.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_env_iterate (const struct GNUNET_PSYC_Environment *env,
 | 
			
		||||
                         GNUNET_PSYC_Iterator it, void *it_cls)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_PSYC_Modifier *mod;
 | 
			
		||||
  for (mod = env->mod_head; NULL != mod; mod = mod->next)
 | 
			
		||||
    it (it_cls, mod->oper, mod->name, mod->value, mod->value_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the number of modifiers in the environment.
 | 
			
		||||
 *
 | 
			
		||||
 * @param env The environment.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Number of modifiers.
 | 
			
		||||
 */
 | 
			
		||||
size_t
 | 
			
		||||
GNUNET_PSYC_env_get_count (const struct GNUNET_PSYC_Environment *env)
 | 
			
		||||
{
 | 
			
		||||
  return env->mod_count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Destroy an environment.
 | 
			
		||||
 *
 | 
			
		||||
 * @param env The environment to destroy.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_env_destroy (struct GNUNET_PSYC_Environment *env)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_PSYC_Modifier *mod, *prev = NULL;
 | 
			
		||||
  for (mod = env->mod_head; NULL != mod; mod = mod->next)
 | 
			
		||||
  {
 | 
			
		||||
    if (NULL != prev)
 | 
			
		||||
      GNUNET_free (prev);
 | 
			
		||||
    prev = mod;
 | 
			
		||||
  }
 | 
			
		||||
  if (NULL != prev)
 | 
			
		||||
    GNUNET_free (prev);
 | 
			
		||||
 | 
			
		||||
  GNUNET_free (env);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1355
									
								
								src/psycutil/psyc_message.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1355
									
								
								src/psycutil/psyc_message.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										711
									
								
								src/psycutil/psyc_slicer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										711
									
								
								src/psycutil/psyc_slicer.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,711 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of GNUnet
 | 
			
		||||
 * Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 *
 | 
			
		||||
 * @file
 | 
			
		||||
 * PSYC Slicer API
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
#include "gnunet_psyc_util_lib.h"
 | 
			
		||||
 | 
			
		||||
#define LOG(kind,...) GNUNET_log_from (kind, "psyc-util-slicer",__VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle for a try-and-slice instance.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_Slicer
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
   * Method handlers: H(method_name) -> SlicerMethodCallbacks
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CONTAINER_MultiHashMap *method_handlers;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Modifier handlers: H(modifier_name) -> SlicerModifierCallbacks
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CONTAINER_MultiHashMap *modifier_handlers;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Receive handle for incoming messages.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_PSYC_ReceiveHandle *recv;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Currently being processed message.
 | 
			
		||||
   */
 | 
			
		||||
  const struct GNUNET_PSYC_MessageHeader *msg;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Currently being processed message part.
 | 
			
		||||
   */
 | 
			
		||||
  const struct GNUNET_MessageHeader *pmsg;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * ID of currently being received message.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t message_id;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Fragment offset of currently being received message.
 | 
			
		||||
   */
 | 
			
		||||
  uint64_t fragment_offset;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Flags of currently being received message.
 | 
			
		||||
   */
 | 
			
		||||
  uint32_t flags;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Method name of currently being received message.
 | 
			
		||||
   */
 | 
			
		||||
  char *method_name;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Name of currently processed modifier.
 | 
			
		||||
   */
 | 
			
		||||
  char *mod_name;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Value of currently processed modifier.
 | 
			
		||||
   */
 | 
			
		||||
  char *mod_value;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Public key of the nym the current message originates from.
 | 
			
		||||
   */
 | 
			
		||||
  struct GNUNET_CRYPTO_EcdsaPublicKey nym_pub_key;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Size of @a method_name (including terminating \0).
 | 
			
		||||
   */
 | 
			
		||||
  uint16_t method_name_size;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Size of @a modifier_name (including terminating \0).
 | 
			
		||||
   */
 | 
			
		||||
  uint16_t mod_name_size;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Size of modifier value fragment.
 | 
			
		||||
   */
 | 
			
		||||
  uint16_t mod_value_size;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Full size of modifier value.
 | 
			
		||||
   */
 | 
			
		||||
  uint16_t mod_full_value_size;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Remaining bytes from the value of the current modifier.
 | 
			
		||||
   */
 | 
			
		||||
  uint16_t mod_value_remaining;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Operator of currently processed modifier.
 | 
			
		||||
   */
 | 
			
		||||
  uint8_t mod_oper;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Callbacks for a slicer method handler.
 | 
			
		||||
 */
 | 
			
		||||
struct SlicerMethodCallbacks
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_PSYC_MessageCallback msg_cb;
 | 
			
		||||
  GNUNET_PSYC_MethodCallback method_cb;
 | 
			
		||||
  GNUNET_PSYC_ModifierCallback modifier_cb;
 | 
			
		||||
  GNUNET_PSYC_DataCallback data_cb;
 | 
			
		||||
  GNUNET_PSYC_EndOfMessageCallback eom_cb;
 | 
			
		||||
  void *cls;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct SlicerMethodRemoveClosure
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_PSYC_Slicer *slicer;
 | 
			
		||||
  struct SlicerMethodCallbacks rm_cbs;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Callbacks for a slicer method handler.
 | 
			
		||||
 */
 | 
			
		||||
struct SlicerModifierCallbacks
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_PSYC_ModifierCallback modifier_cb;
 | 
			
		||||
  void *cls;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct SlicerModifierRemoveClosure
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_PSYC_Slicer *slicer;
 | 
			
		||||
  struct SlicerModifierCallbacks rm_cbs;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Call a method handler for an incoming message part.
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
slicer_method_handler_notify (void *cls, const struct GNUNET_HashCode *key,
 | 
			
		||||
                              void *value)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_PSYC_Slicer *slicer = cls;
 | 
			
		||||
  const struct GNUNET_MessageHeader *pmsg = slicer->pmsg;
 | 
			
		||||
  struct SlicerMethodCallbacks *cbs = value;
 | 
			
		||||
 | 
			
		||||
  uint16_t ptype = ntohs (pmsg->type);
 | 
			
		||||
  switch (ptype)
 | 
			
		||||
  {
 | 
			
		||||
  case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD:
 | 
			
		||||
  {
 | 
			
		||||
    if (NULL != cbs->msg_cb)
 | 
			
		||||
      cbs->msg_cb (cbs->cls, slicer->msg);
 | 
			
		||||
    if (NULL == cbs->method_cb)
 | 
			
		||||
      break;
 | 
			
		||||
    struct GNUNET_PSYC_MessageMethod *
 | 
			
		||||
      meth = (struct GNUNET_PSYC_MessageMethod *) pmsg;
 | 
			
		||||
    cbs->method_cb (cbs->cls, slicer->msg, meth, slicer->message_id,
 | 
			
		||||
                    slicer->method_name);
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER:
 | 
			
		||||
  {
 | 
			
		||||
    if (NULL == cbs->modifier_cb)
 | 
			
		||||
      break;
 | 
			
		||||
    struct GNUNET_PSYC_MessageModifier *
 | 
			
		||||
      mod = (struct GNUNET_PSYC_MessageModifier *) pmsg;
 | 
			
		||||
    cbs->modifier_cb (cbs->cls, slicer->msg, &mod->header, slicer->message_id,
 | 
			
		||||
                      mod->oper, (const char *) &mod[1],
 | 
			
		||||
                      (const void *) &mod[1] + ntohs (mod->name_size),
 | 
			
		||||
                      ntohs (mod->header.size) - sizeof (*mod) - ntohs (mod->name_size),
 | 
			
		||||
                      ntohs (mod->value_size));
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT:
 | 
			
		||||
  {
 | 
			
		||||
    if (NULL == cbs->modifier_cb)
 | 
			
		||||
      break;
 | 
			
		||||
    cbs->modifier_cb (cbs->cls, slicer->msg, pmsg, slicer->message_id,
 | 
			
		||||
                      slicer->mod_oper, slicer->mod_name, &pmsg[1],
 | 
			
		||||
                      ntohs (pmsg->size) - sizeof (*pmsg),
 | 
			
		||||
                      slicer->mod_full_value_size);
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_DATA:
 | 
			
		||||
  {
 | 
			
		||||
    if (NULL == cbs->data_cb)
 | 
			
		||||
      break;
 | 
			
		||||
    cbs->data_cb (cbs->cls, slicer->msg, pmsg, slicer->message_id,
 | 
			
		||||
                  &pmsg[1], ntohs (pmsg->size) - sizeof (*pmsg));
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END:
 | 
			
		||||
    if (NULL == cbs->eom_cb)
 | 
			
		||||
      break;
 | 
			
		||||
    cbs->eom_cb (cbs->cls, slicer->msg, pmsg, slicer->message_id, GNUNET_NO);
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL:
 | 
			
		||||
    if (NULL == cbs->eom_cb)
 | 
			
		||||
      break;
 | 
			
		||||
    cbs->eom_cb (cbs->cls, slicer->msg, pmsg, slicer->message_id, GNUNET_YES);
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
  return GNUNET_YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Call a method handler for an incoming message part.
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
slicer_modifier_handler_notify (void *cls, const struct GNUNET_HashCode *key,
 | 
			
		||||
                                void *value)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_PSYC_Slicer *slicer = cls;
 | 
			
		||||
  struct SlicerModifierCallbacks *cbs = value;
 | 
			
		||||
 | 
			
		||||
  cbs->modifier_cb (cbs->cls, slicer->msg, slicer->pmsg, slicer->message_id,
 | 
			
		||||
                    slicer->mod_oper, slicer->mod_name, slicer->mod_value,
 | 
			
		||||
                    slicer->mod_value_size, slicer->mod_full_value_size);
 | 
			
		||||
  return GNUNET_YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Process an incoming message and call matching handlers.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        The slicer to use.
 | 
			
		||||
 * @param msg
 | 
			
		||||
 *        The message as it arrived from the network.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_message (struct GNUNET_PSYC_Slicer *slicer,
 | 
			
		||||
                            const struct GNUNET_PSYC_MessageHeader *msg)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_PSYC_receive_message (slicer->recv, msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Process an incoming message part and call matching handlers.
 | 
			
		||||
 *
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure.
 | 
			
		||||
 * @param message_id
 | 
			
		||||
 *        ID of the message.
 | 
			
		||||
 * @param flags
 | 
			
		||||
 *        Flags for the message.
 | 
			
		||||
 *        @see enum GNUNET_PSYC_MessageFlags
 | 
			
		||||
 * @param msg
 | 
			
		||||
 *        The message part. as it arrived from the network.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_message_part (struct GNUNET_PSYC_Slicer *slicer,
 | 
			
		||||
                                 const struct GNUNET_PSYC_MessageHeader *msg,
 | 
			
		||||
                                 const struct GNUNET_MessageHeader *pmsg)
 | 
			
		||||
{
 | 
			
		||||
  slicer->msg = msg;
 | 
			
		||||
  slicer->pmsg = pmsg;
 | 
			
		||||
 | 
			
		||||
  uint64_t message_id = GNUNET_ntohll (msg->message_id);
 | 
			
		||||
 | 
			
		||||
  uint16_t ptype = ntohs (pmsg->type);
 | 
			
		||||
  if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD == ptype)
 | 
			
		||||
  {
 | 
			
		||||
    struct GNUNET_PSYC_MessageMethod *
 | 
			
		||||
      meth = (struct GNUNET_PSYC_MessageMethod *) pmsg;
 | 
			
		||||
    slicer->method_name_size = ntohs (meth->header.size) - sizeof (*meth);
 | 
			
		||||
    slicer->method_name = GNUNET_malloc (slicer->method_name_size);
 | 
			
		||||
    GNUNET_memcpy (slicer->method_name, &meth[1], slicer->method_name_size);
 | 
			
		||||
     slicer->message_id = message_id;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_assert (message_id == slicer->message_id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  char *nym_str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&msg->slave_pub_key);
 | 
			
		||||
  LOG (GNUNET_ERROR_TYPE_DEBUG,
 | 
			
		||||
       "Slicer received message of type %u and size %u, "
 | 
			
		||||
       "with ID %" PRIu64 " and method %s from %s\n",
 | 
			
		||||
       ptype, ntohs (pmsg->size), message_id, slicer->method_name, nym_str);
 | 
			
		||||
  GNUNET_free (nym_str);
 | 
			
		||||
 | 
			
		||||
  /* try-and-slice modifier */
 | 
			
		||||
 | 
			
		||||
  switch (ptype)
 | 
			
		||||
  {
 | 
			
		||||
  case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MODIFIER:
 | 
			
		||||
  {
 | 
			
		||||
    struct GNUNET_PSYC_MessageModifier *
 | 
			
		||||
      mod = (struct GNUNET_PSYC_MessageModifier *) pmsg;
 | 
			
		||||
    slicer->mod_oper = mod->oper;
 | 
			
		||||
    slicer->mod_name_size = ntohs (mod->name_size);
 | 
			
		||||
    slicer->mod_name = GNUNET_malloc (slicer->mod_name_size);
 | 
			
		||||
    GNUNET_memcpy (slicer->mod_name, &mod[1], slicer->mod_name_size);
 | 
			
		||||
    slicer->mod_value = (char *) &mod[1] + slicer->mod_name_size;
 | 
			
		||||
    slicer->mod_full_value_size = ntohs (mod->value_size);
 | 
			
		||||
    slicer->mod_value_remaining = slicer->mod_full_value_size;
 | 
			
		||||
    slicer->mod_value_size
 | 
			
		||||
      = ntohs (mod->header.size) - sizeof (*mod) - slicer->mod_name_size;
 | 
			
		||||
    // fall through
 | 
			
		||||
  }
 | 
			
		||||
  case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT:
 | 
			
		||||
    if (ptype == GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_MOD_CONT)
 | 
			
		||||
    {
 | 
			
		||||
      slicer->mod_value = (char *) &pmsg[1];
 | 
			
		||||
      slicer->mod_value_size = ntohs (pmsg->size) - sizeof (*pmsg);
 | 
			
		||||
    }
 | 
			
		||||
    slicer->mod_value_remaining -= slicer->mod_value_size;
 | 
			
		||||
    char *name = GNUNET_malloc (slicer->mod_name_size);
 | 
			
		||||
    GNUNET_memcpy (name, slicer->mod_name, slicer->mod_name_size);
 | 
			
		||||
    do
 | 
			
		||||
    {
 | 
			
		||||
      struct GNUNET_HashCode key;
 | 
			
		||||
      uint16_t name_len = strlen (name);
 | 
			
		||||
      GNUNET_CRYPTO_hash (name, name_len, &key);
 | 
			
		||||
      GNUNET_CONTAINER_multihashmap_get_multiple (slicer->modifier_handlers, &key,
 | 
			
		||||
                                                  slicer_modifier_handler_notify,
 | 
			
		||||
                                                  slicer);
 | 
			
		||||
      char *p = strrchr (name, '_');
 | 
			
		||||
      if (NULL == p)
 | 
			
		||||
        break;
 | 
			
		||||
      *p = '\0';
 | 
			
		||||
    } while (1);
 | 
			
		||||
    GNUNET_free (name);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* try-and-slice method */
 | 
			
		||||
 | 
			
		||||
  char *name = GNUNET_malloc (slicer->method_name_size);
 | 
			
		||||
  GNUNET_memcpy (name, slicer->method_name, slicer->method_name_size);
 | 
			
		||||
  do
 | 
			
		||||
  {
 | 
			
		||||
    struct GNUNET_HashCode key;
 | 
			
		||||
    uint16_t name_len = strlen (name);
 | 
			
		||||
    GNUNET_CRYPTO_hash (name, name_len, &key);
 | 
			
		||||
    GNUNET_CONTAINER_multihashmap_get_multiple (slicer->method_handlers, &key,
 | 
			
		||||
                                                slicer_method_handler_notify,
 | 
			
		||||
                                                slicer);
 | 
			
		||||
    char *p = strrchr (name, '_');
 | 
			
		||||
    if (NULL == p)
 | 
			
		||||
      break;
 | 
			
		||||
    *p = '\0';
 | 
			
		||||
  } while (1);
 | 
			
		||||
  GNUNET_free (name);
 | 
			
		||||
 | 
			
		||||
  if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END <= ptype)
 | 
			
		||||
    GNUNET_free (slicer->method_name);
 | 
			
		||||
 | 
			
		||||
  if (0 == slicer->mod_value_remaining && NULL != slicer->mod_name)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_free (slicer->mod_name);
 | 
			
		||||
    slicer->mod_name = NULL;
 | 
			
		||||
    slicer->mod_name_size = 0;
 | 
			
		||||
    slicer->mod_value_size = 0;
 | 
			
		||||
    slicer->mod_full_value_size = 0;
 | 
			
		||||
    slicer->mod_oper = 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  slicer->msg = NULL;
 | 
			
		||||
  slicer->pmsg = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a try-and-slice instance.
 | 
			
		||||
 *
 | 
			
		||||
 * A slicer processes incoming messages and notifies callbacks about matching
 | 
			
		||||
 * methods or modifiers encountered.
 | 
			
		||||
 *
 | 
			
		||||
 * @return A new try-and-slice construct.
 | 
			
		||||
 */
 | 
			
		||||
struct GNUNET_PSYC_Slicer *
 | 
			
		||||
GNUNET_PSYC_slicer_create (void)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_PSYC_Slicer *slicer = GNUNET_malloc (sizeof (*slicer));
 | 
			
		||||
  slicer->method_handlers = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
 | 
			
		||||
  slicer->modifier_handlers = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
 | 
			
		||||
  slicer->recv = GNUNET_PSYC_receive_create (NULL,
 | 
			
		||||
                                             (GNUNET_PSYC_MessagePartCallback)
 | 
			
		||||
                                             GNUNET_PSYC_slicer_message_part,
 | 
			
		||||
                                             slicer);
 | 
			
		||||
  return slicer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Add a method to the try-and-slice instance.
 | 
			
		||||
 *
 | 
			
		||||
 * The callbacks are called for messages with a matching @a method_name prefix.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        The try-and-slice instance to extend.
 | 
			
		||||
 * @param method_name
 | 
			
		||||
 *        Name of the given method, use empty string to match all.
 | 
			
		||||
 * @param method_cb
 | 
			
		||||
 *        Method handler invoked upon a matching message.
 | 
			
		||||
 * @param modifier_cb
 | 
			
		||||
 *        Modifier handler, invoked after @a method_cb
 | 
			
		||||
 *        for each modifier in the message.
 | 
			
		||||
 * @param data_cb
 | 
			
		||||
 *        Data handler, invoked after @a modifier_cb for each data fragment.
 | 
			
		||||
 * @param eom_cb
 | 
			
		||||
 *        Invoked upon reaching the end of a matching message.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for the callbacks.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_method_add (struct GNUNET_PSYC_Slicer *slicer,
 | 
			
		||||
                               const char *method_name,
 | 
			
		||||
                               GNUNET_PSYC_MessageCallback msg_cb,
 | 
			
		||||
                               GNUNET_PSYC_MethodCallback method_cb,
 | 
			
		||||
                               GNUNET_PSYC_ModifierCallback modifier_cb,
 | 
			
		||||
                               GNUNET_PSYC_DataCallback data_cb,
 | 
			
		||||
                               GNUNET_PSYC_EndOfMessageCallback eom_cb,
 | 
			
		||||
                               void *cls)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_HashCode key;
 | 
			
		||||
  GNUNET_CRYPTO_hash (method_name, strlen (method_name), &key);
 | 
			
		||||
 | 
			
		||||
  struct SlicerMethodCallbacks *cbs = GNUNET_malloc (sizeof (*cbs));
 | 
			
		||||
  cbs->msg_cb = msg_cb,
 | 
			
		||||
  cbs->method_cb = method_cb;
 | 
			
		||||
  cbs->modifier_cb = modifier_cb;
 | 
			
		||||
  cbs->data_cb = data_cb;
 | 
			
		||||
  cbs->eom_cb = eom_cb;
 | 
			
		||||
  cbs->cls = cls;
 | 
			
		||||
 | 
			
		||||
  GNUNET_CONTAINER_multihashmap_put (slicer->method_handlers, &key, cbs,
 | 
			
		||||
                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
slicer_method_remove (void *cls, const struct GNUNET_HashCode *key, void *value)
 | 
			
		||||
{
 | 
			
		||||
  struct SlicerMethodRemoveClosure *rm_cls = cls;
 | 
			
		||||
  struct GNUNET_PSYC_Slicer *slicer = rm_cls->slicer;
 | 
			
		||||
  struct SlicerMethodCallbacks *rm_cbs = &rm_cls->rm_cbs;
 | 
			
		||||
  struct SlicerMethodCallbacks *cbs = value;
 | 
			
		||||
 | 
			
		||||
  if ((NULL == rm_cbs->msg_cb || cbs->msg_cb == rm_cbs->msg_cb)
 | 
			
		||||
      && (NULL == rm_cbs->method_cb || cbs->method_cb == rm_cbs->method_cb)
 | 
			
		||||
      && (NULL == rm_cbs->modifier_cb || cbs->modifier_cb == rm_cbs->modifier_cb)
 | 
			
		||||
      && (NULL == rm_cbs->data_cb || cbs->data_cb == rm_cbs->data_cb)
 | 
			
		||||
      && (NULL == rm_cbs->eom_cb || cbs->eom_cb == rm_cbs->eom_cb))
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_CONTAINER_multihashmap_remove (slicer->method_handlers, key, cbs);
 | 
			
		||||
    GNUNET_free (cbs);
 | 
			
		||||
    return GNUNET_NO;
 | 
			
		||||
  }
 | 
			
		||||
  return GNUNET_YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove a registered method from the try-and-slice instance.
 | 
			
		||||
 *
 | 
			
		||||
 * Removes one matching handler registered with the given
 | 
			
		||||
 * @a method_name and  callbacks.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        The try-and-slice instance.
 | 
			
		||||
 * @param method_name
 | 
			
		||||
 *        Name of the method to remove.
 | 
			
		||||
 * @param method_cb
 | 
			
		||||
 *        Method handler.
 | 
			
		||||
 * @param modifier_cb
 | 
			
		||||
 *        Modifier handler.
 | 
			
		||||
 * @param data_cb
 | 
			
		||||
 *        Data handler.
 | 
			
		||||
 * @param eom_cb
 | 
			
		||||
 *        End of message handler.
 | 
			
		||||
 *
 | 
			
		||||
 * @return #GNUNET_OK if a method handler was removed,
 | 
			
		||||
 *         #GNUNET_NO if no handler matched the given method name and callbacks.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYC_slicer_method_remove (struct GNUNET_PSYC_Slicer *slicer,
 | 
			
		||||
                                  const char *method_name,
 | 
			
		||||
                                  GNUNET_PSYC_MessageCallback msg_cb,
 | 
			
		||||
                                  GNUNET_PSYC_MethodCallback method_cb,
 | 
			
		||||
                                  GNUNET_PSYC_ModifierCallback modifier_cb,
 | 
			
		||||
                                  GNUNET_PSYC_DataCallback data_cb,
 | 
			
		||||
                                  GNUNET_PSYC_EndOfMessageCallback eom_cb)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_HashCode key;
 | 
			
		||||
  GNUNET_CRYPTO_hash (method_name, strlen (method_name), &key);
 | 
			
		||||
 | 
			
		||||
  struct SlicerMethodRemoveClosure rm_cls;
 | 
			
		||||
  rm_cls.slicer = slicer;
 | 
			
		||||
  struct SlicerMethodCallbacks *rm_cbs = &rm_cls.rm_cbs;
 | 
			
		||||
  rm_cbs->msg_cb = msg_cb;
 | 
			
		||||
  rm_cbs->method_cb = method_cb;
 | 
			
		||||
  rm_cbs->modifier_cb = modifier_cb;
 | 
			
		||||
  rm_cbs->data_cb = data_cb;
 | 
			
		||||
  rm_cbs->eom_cb = eom_cb;
 | 
			
		||||
 | 
			
		||||
  return
 | 
			
		||||
    (GNUNET_SYSERR
 | 
			
		||||
     == GNUNET_CONTAINER_multihashmap_get_multiple (slicer->method_handlers, &key,
 | 
			
		||||
                                                    slicer_method_remove,
 | 
			
		||||
                                                    &rm_cls))
 | 
			
		||||
    ? GNUNET_NO
 | 
			
		||||
    : GNUNET_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Watch a place for changed objects.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        The try-and-slice instance.
 | 
			
		||||
 * @param object_filter
 | 
			
		||||
 *        Object prefix to match.
 | 
			
		||||
 * @param modifier_cb
 | 
			
		||||
 *        Function to call when encountering a state modifier.
 | 
			
		||||
 * @param cls
 | 
			
		||||
 *        Closure for callback.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_modifier_add (struct GNUNET_PSYC_Slicer *slicer,
 | 
			
		||||
                                 const char *object_filter,
 | 
			
		||||
                                 GNUNET_PSYC_ModifierCallback modifier_cb,
 | 
			
		||||
                                 void *cls)
 | 
			
		||||
{
 | 
			
		||||
  struct SlicerModifierCallbacks *cbs = GNUNET_malloc (sizeof *cbs);
 | 
			
		||||
  cbs->modifier_cb = modifier_cb;
 | 
			
		||||
  cbs->cls = cls;
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_HashCode key;
 | 
			
		||||
  GNUNET_CRYPTO_hash (object_filter, strlen (object_filter), &key);
 | 
			
		||||
  GNUNET_CONTAINER_multihashmap_put (slicer->modifier_handlers, &key, cbs,
 | 
			
		||||
                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
slicer_modifier_remove (void *cls, const struct GNUNET_HashCode *key, void *value)
 | 
			
		||||
{
 | 
			
		||||
  struct SlicerModifierRemoveClosure *rm_cls = cls;
 | 
			
		||||
  struct GNUNET_PSYC_Slicer *slicer = rm_cls->slicer;
 | 
			
		||||
  struct SlicerModifierCallbacks *rm_cbs = &rm_cls->rm_cbs;
 | 
			
		||||
  struct SlicerModifierCallbacks *cbs = value;
 | 
			
		||||
 | 
			
		||||
  if (cbs->modifier_cb == rm_cbs->modifier_cb)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_CONTAINER_multihashmap_remove (slicer->modifier_handlers, key, cbs);
 | 
			
		||||
    GNUNET_free (cbs);
 | 
			
		||||
    return GNUNET_NO;
 | 
			
		||||
  }
 | 
			
		||||
  return GNUNET_YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove a registered modifier from the try-and-slice instance.
 | 
			
		||||
 *
 | 
			
		||||
 * Removes one matching handler registered with the given
 | 
			
		||||
 * @a object_filter and @a modifier_cb.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        The try-and-slice instance.
 | 
			
		||||
 * @param object_filter
 | 
			
		||||
 *        Object prefix to match.
 | 
			
		||||
 * @param modifier_cb
 | 
			
		||||
 *        Function to call when encountering a state modifier changes.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
GNUNET_PSYC_slicer_modifier_remove (struct GNUNET_PSYC_Slicer *slicer,
 | 
			
		||||
                                    const char *object_filter,
 | 
			
		||||
                                    GNUNET_PSYC_ModifierCallback modifier_cb)
 | 
			
		||||
{
 | 
			
		||||
  struct GNUNET_HashCode key;
 | 
			
		||||
  GNUNET_CRYPTO_hash (object_filter, strlen (object_filter), &key);
 | 
			
		||||
 | 
			
		||||
  struct SlicerModifierRemoveClosure rm_cls;
 | 
			
		||||
  rm_cls.slicer = slicer;
 | 
			
		||||
  struct SlicerModifierCallbacks *rm_cbs = &rm_cls.rm_cbs;
 | 
			
		||||
  rm_cbs->modifier_cb = modifier_cb;
 | 
			
		||||
 | 
			
		||||
  return
 | 
			
		||||
    (GNUNET_SYSERR
 | 
			
		||||
     == GNUNET_CONTAINER_multihashmap_get_multiple (slicer->modifier_handlers, &key,
 | 
			
		||||
                                                    slicer_modifier_remove,
 | 
			
		||||
                                                    &rm_cls))
 | 
			
		||||
    ? GNUNET_NO
 | 
			
		||||
    : GNUNET_OK;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
slicer_method_free (void *cls, const struct GNUNET_HashCode *key, void *value)
 | 
			
		||||
{
 | 
			
		||||
  struct SlicerMethodCallbacks *cbs = value;
 | 
			
		||||
  GNUNET_free (cbs);
 | 
			
		||||
  return GNUNET_YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
slicer_modifier_free (void *cls, const struct GNUNET_HashCode *key, void *value)
 | 
			
		||||
{
 | 
			
		||||
  struct SlicerModifierCallbacks *cbs = value;
 | 
			
		||||
  GNUNET_free (cbs);
 | 
			
		||||
  return GNUNET_YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove all registered method handlers.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        Slicer to clear.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_method_clear (struct GNUNET_PSYC_Slicer *slicer)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_CONTAINER_multihashmap_iterate (slicer->method_handlers,
 | 
			
		||||
                                         slicer_method_free, NULL);
 | 
			
		||||
  GNUNET_CONTAINER_multihashmap_clear (slicer->method_handlers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove all registered modifier handlers.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        Slicer to clear.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_modifier_clear (struct GNUNET_PSYC_Slicer *slicer)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_CONTAINER_multihashmap_iterate (slicer->modifier_handlers,
 | 
			
		||||
                                         slicer_modifier_free, NULL);
 | 
			
		||||
  GNUNET_CONTAINER_multihashmap_clear (slicer->modifier_handlers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove all registered method & modifier handlers.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        Slicer to clear.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_clear (struct GNUNET_PSYC_Slicer *slicer)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_PSYC_slicer_method_clear (slicer);
 | 
			
		||||
  GNUNET_PSYC_slicer_modifier_clear (slicer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Destroy a given try-and-slice instance.
 | 
			
		||||
 *
 | 
			
		||||
 * @param slicer
 | 
			
		||||
 *        Slicer to destroy
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
GNUNET_PSYC_slicer_destroy (struct GNUNET_PSYC_Slicer *slicer)
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_PSYC_slicer_clear (slicer);
 | 
			
		||||
  GNUNET_CONTAINER_multihashmap_destroy (slicer->method_handlers);
 | 
			
		||||
  GNUNET_CONTAINER_multihashmap_destroy (slicer->modifier_handlers);
 | 
			
		||||
  GNUNET_PSYC_receive_destroy (slicer->recv);
 | 
			
		||||
  GNUNET_free (slicer);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										96
									
								
								src/psycutil/test_psyc_env.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/psycutil/test_psyc_env.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,96 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file is part of GNUnet.
 | 
			
		||||
 * Copyright (C) 2013 GNUnet e.V.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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.
 | 
			
		||||
 *
 | 
			
		||||
 * GNUnet 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/>.
 | 
			
		||||
 | 
			
		||||
     SPDX-License-Identifier: AGPL3.0-or-later
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author Gabor X Toth
 | 
			
		||||
 *
 | 
			
		||||
 * @file
 | 
			
		||||
 * Tests for the environment library.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "gnunet_util_lib.h"
 | 
			
		||||
#include "gnunet_testing_lib.h"
 | 
			
		||||
#include "gnunet_psyc_util_lib.h"
 | 
			
		||||
 | 
			
		||||
struct GNUNET_PSYC_Modifier mods[] = {
 | 
			
		||||
  { .oper = GNUNET_PSYC_OP_SET,
 | 
			
		||||
    .name = "_foo", .value = "foo", .value_size = 3 },
 | 
			
		||||
 | 
			
		||||
  { .oper = GNUNET_PSYC_OP_ASSIGN,
 | 
			
		||||
    .name = "_foo_bar", .value = "foo bar", .value_size = 7 },
 | 
			
		||||
 | 
			
		||||
  { .oper = GNUNET_PSYC_OP_AUGMENT,
 | 
			
		||||
    .name = "_foo_bar_baz", .value = "foo bar baz", .value_size = 11 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ItCls
 | 
			
		||||
{
 | 
			
		||||
  size_t n;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
iterator (void *cls, enum GNUNET_PSYC_Operator oper,
 | 
			
		||||
          const char *name, const char *value, uint32_t value_size)
 | 
			
		||||
{
 | 
			
		||||
  struct ItCls *it_cls = cls;
 | 
			
		||||
  struct GNUNET_PSYC_Modifier *m = &mods[it_cls->n++];
 | 
			
		||||
 | 
			
		||||
  GNUNET_assert (oper == m->oper);
 | 
			
		||||
  GNUNET_assert (value_size == m->value_size);
 | 
			
		||||
  GNUNET_assert (0 == memcmp (name, m->name, strlen (m->name)));
 | 
			
		||||
  GNUNET_assert (0 == memcmp (value, m->value, m->value_size));
 | 
			
		||||
 | 
			
		||||
  return GNUNET_YES;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
  GNUNET_log_setup ("test-env", "WARNING", NULL);
 | 
			
		||||
 | 
			
		||||
  struct GNUNET_PSYC_Environment *env = GNUNET_PSYC_env_create ();
 | 
			
		||||
  GNUNET_assert (NULL != env);
 | 
			
		||||
  int i, len = 3;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < len; i++)
 | 
			
		||||
  {
 | 
			
		||||
    GNUNET_PSYC_env_add (env, mods[i].oper, mods[i].name,
 | 
			
		||||
                         mods[i].value, mods[i].value_size);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  struct ItCls it_cls = { .n = 0 };
 | 
			
		||||
  GNUNET_PSYC_env_iterate (env, iterator, &it_cls);
 | 
			
		||||
  GNUNET_assert (len == it_cls.n);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < len; i++)
 | 
			
		||||
  {
 | 
			
		||||
    enum GNUNET_PSYC_Operator oper;
 | 
			
		||||
    const char *name;
 | 
			
		||||
    const void *value;
 | 
			
		||||
    size_t value_size;
 | 
			
		||||
    GNUNET_PSYC_env_shift (env, &oper, &name, &value, &value_size);
 | 
			
		||||
    GNUNET_assert (len - i - 1 == GNUNET_PSYC_env_get_count (env));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  GNUNET_PSYC_env_destroy (env);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								src/social/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/social/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
gnunet-social
 | 
			
		||||
gnunet-service-social
 | 
			
		||||
test_social
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user