diff --git a/LICENSES/LGPL-2.0-only.txt b/LICENSES/LGPL-2.0-only.txt
new file mode 100644
index 0000000..5c96471
--- /dev/null
+++ b/LICENSES/LGPL-2.0-only.txt
@@ -0,0 +1,446 @@
+GNU LIBRARY GENERAL PUBLIC LICENSE
+
+Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc.
+
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is numbered 2 because
+it goes with version 2 of the ordinary GPL.]
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share
+and change it. By contrast, the GNU General Public Licenses are intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users.
+
+This license, the Library General Public License, applies to some specially
+designated Free Software Foundation software, and to any other libraries whose
+authors decide to use it. You can use it for your libraries, 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 this service 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 make restrictions that forbid anyone to
+deny you these rights or to ask you to surrender the rights. These restrictions
+translate to certain responsibilities for you if you distribute copies of
+the library, or if you modify it.
+
+For example, if you distribute copies of the library, whether gratis or for
+a fee, you must give the recipients all the rights that we gave you. You must
+make sure that they, too, receive or can get the source code. If you link
+a program with the library, you must provide complete object files to the
+recipients so that they can relink them with the library, after making changes
+to the library and recompiling it. And you must show them these terms so they
+know their rights.
+
+Our method of protecting your rights has two steps: (1) copyright the library,
+and (2) offer you this license which gives you legal permission to copy, distribute
+and/or modify the library.
+
+Also, for each distributor's protection, we want to make certain that everyone
+understands that there is no warranty for this free library. If the library
+is modified by someone else and passed on, we want its recipients to know
+that what they have is not the original version, so that any problems introduced
+by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We
+wish to avoid the danger that companies distributing free software will individually
+obtain patent licenses, thus in effect transforming the program into proprietary
+software. To prevent this, we have made it clear that any patent must be licensed
+for everyone's free use or not licensed at all.
+
+Most GNU software, including some libraries, is covered by the ordinary GNU
+General Public License, which was designed for utility programs. This license,
+the GNU Library General Public License, applies to certain designated libraries.
+This license is quite different from the ordinary one; be sure to read it
+in full, and don't assume that anything in it is the same as in the ordinary
+license.
+
+The reason we have a separate public license for some libraries is that they
+blur the distinction we usually make between modifying or adding to a program
+and simply using it. Linking a program with a library, without changing the
+library, is in some sense simply using the library, and is analogous to running
+a utility program or application program. However, in a textual and legal
+sense, the linked executable is a combined work, a derivative of the original
+library, and the ordinary General Public License treats it as such.
+
+Because of this blurred distinction, using the ordinary General Public License
+for libraries did not effectively promote software sharing, because most developers
+did not use the libraries. We concluded that weaker conditions might promote
+sharing better.
+
+However, unrestricted linking of non-free programs would deprive the users
+of those programs of all benefit from the free status of the libraries themselves.
+This Library General Public License is intended to permit developers of non-free
+programs to use free libraries, while preserving your freedom as a user of
+such programs to change the free libraries that are incorporated in them.
+(We have not seen how to achieve this as regards changes in header files,
+but we have achieved it as regards changes in the actual functions of the
+Library.) The hope is that this will lead to faster development of free libraries.
+
+The precise terms and conditions for copying, distribution and modification
+follow. Pay close attention to the difference between a "work based on the
+library" and a "work that uses the library". The former contains code derived
+from the library, while the latter only works together with the library.
+
+Note that it is possible for a library to be covered by the ordinary General
+Public License rather than by this special one.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License Agreement applies to any software library which contains a
+notice placed by the copyright holder or other authorized party saying it
+may be distributed under the terms of this Library General Public License
+(also called "this License"). Each licensee is addressed as "you".
+
+A "library" means a collection of software functions and/or data prepared
+so as to be conveniently linked with application programs (which use some
+of those functions and data) to form executables.
+
+The "Library", below, refers to any such software library or work which has
+been distributed under these terms. A "work based on the Library" means either
+the Library or any derivative work under copyright law: that is to say, a
+work containing the Library or a portion of it, either verbatim or with modifications
+and/or translated straightforwardly into another language. (Hereinafter, translation
+is included without limitation in the term "modification".)
+
+"Source code" for a work means the preferred form of the work for making modifications
+to it. For a library, complete source code means all the source code for all
+modules it contains, plus any associated interface definition files, plus
+the scripts used to control compilation and installation of the library.
+
+Activities other than copying, distribution and modification are not covered
+by this License; they are outside its scope. The act of running a program
+using the Library is not restricted, and output from such a program is covered
+only if its contents constitute a work based on the Library (independent of
+the use of the Library in a tool for writing it). Whether that is true depends
+on what the Library does and what the program that uses the Library does.
+
+1. You may copy and distribute verbatim copies of the Library's complete source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and disclaimer
+of warranty; keep intact all the notices that refer to this License and to
+the absence of any warranty; and distribute a copy of this License along with
+the Library.
+
+You may charge a fee for the physical act of transferring a copy, and you
+may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Library or any portion of it,
+thus forming a work based on the Library, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all
+of these conditions:
+
+ a) The modified work must itself be a software library.
+
+b) You must cause the files modified to carry prominent notices stating that
+you changed the files and the date of any change.
+
+c) You must cause the whole of the work to be licensed at no charge to all
+third parties under the terms of this License.
+
+d) If a facility in the modified Library refers to a function or a table of
+data to be supplied by an application program that uses the facility, other
+than as an argument passed when the facility is invoked, then you must make
+a good faith effort to ensure that, in the event an application does not supply
+such function or table, the facility still operates, and performs whatever
+part of its purpose remains meaningful.
+
+(For example, a function in a library to compute square roots has a purpose
+that is entirely well-defined independent of the application. Therefore, Subsection
+2d requires that any application-supplied function or table used by this function
+must be optional: if the application does not supply it, the square root function
+must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Library, and can be reasonably
+considered independent and separate works in themselves, then this License,
+and its terms, do not apply to those sections when you distribute them as
+separate works. But when you distribute the same sections as part of a whole
+which is a work based on the Library, the distribution of the whole must be
+on the terms of this License, whose permissions for other licensees extend
+to the entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise
+the right to control the distribution of derivative or collective works based
+on the Library.
+
+In addition, mere aggregation of another work not based on the Library with
+the Library (or with a work based on the Library) on a volume of a storage
+or distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may opt to apply the terms of the ordinary GNU General Public License
+instead of this License to a given copy of the Library. To do this, you must
+alter all the notices that refer to this License, so that they refer to the
+ordinary GNU General Public License, version 2, instead of to this License.
+(If a newer version than version 2 of the ordinary GNU General Public License
+has appeared, then you can specify that version instead if you wish.) Do not
+make any other change in these notices.
+
+Once this change is made in a given copy, it is irreversible for that copy,
+so the ordinary GNU General Public License applies to all subsequent copies
+and derivative works made from that copy.
+
+This option is useful when you wish to copy part of the code of the Library
+into a program that is not a library.
+
+4. You may copy and distribute the Library (or a portion or derivative of
+it, under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you accompany it with the complete corresponding
+machine-readable source code, which must be distributed under the terms of
+Sections 1 and 2 above on a medium customarily used for software interchange.
+
+If distribution of object code is made by offering access to copy from a designated
+place, then offering equivalent access to copy the source code from the same
+place satisfies the requirement to distribute the source code, even though
+third parties are not compelled to copy the source along with the object code.
+
+5. A program that contains no derivative of any portion of the Library, but
+is designed to work with the Library by being compiled or linked with it,
+is called a "work that uses the Library". Such a work, in isolation, is not
+a derivative work of the Library, and therefore falls outside the scope of
+this License.
+
+However, linking a "work that uses the Library" with the Library creates an
+executable that is a derivative of the Library (because it contains portions
+of the Library), rather than a "work that uses the library". The executable
+is therefore covered by this License. Section 6 states terms for distribution
+of such executables.
+
+When a "work that uses the Library" uses material from a header file that
+is part of the Library, the object code for the work may be a derivative work
+of the Library even though the source code is not. Whether this is true is
+especially significant if the work can be linked without the Library, or if
+the work is itself a library. The threshold for this to be true is not precisely
+defined by law.
+
+If such an object file uses only numerical parameters, data structure layouts
+and accessors, and small macros and small inline functions (ten lines or less
+in length), then the use of the object file is unrestricted, regardless of
+whether it is legally a derivative work. (Executables containing this object
+code plus portions of the Library will still fall under Section 6.)
+
+Otherwise, if the work is a derivative of the Library, you may distribute
+the object code for the work under the terms of Section 6. Any executables
+containing that work also fall under Section 6, whether or not they are linked
+directly with the Library itself.
+
+6. As an exception to the Sections above, you may also compile or link a "work
+that uses the Library" with the Library to produce a work containing portions
+of the Library, and distribute that work under terms of your choice, provided
+that the terms permit modification of the work for the customer's own use
+and reverse engineering for debugging such modifications.
+
+You must give prominent notice with each copy of the work that the Library
+is used in it and that the Library and its use are covered by this License.
+You must supply a copy of this License. If the work during execution displays
+copyright notices, you must include the copyright notice for the Library among
+them, as well as a reference directing the user to the copy of this License.
+Also, you must do one of these things:
+
+a) Accompany the work with the complete corresponding machine-readable source
+code for the Library including whatever changes were used in the work (which
+must be distributed under Sections 1 and 2 above); and, if the work is an
+executable linked with the Library, with the complete machine-readable "work
+that uses the Library", as object code and/or source code, so that the user
+can modify the Library and then relink to produce a modified executable containing
+the modified Library. (It is understood that the user who changes the contents
+of definitions files in the Library will not necessarily be able to recompile
+the application to use the modified definitions.)
+
+b) Accompany the work with a written offer, valid for at least three years,
+to give the same user the materials specified in Subsection 6a, above, for
+a charge no more than the cost of performing this distribution.
+
+c) If distribution of the work is made by offering access to copy from a designated
+place, offer equivalent access to copy the above specified materials from
+the same place.
+
+d) Verify that the user has already received a copy of these materials or
+that you have already sent this user a copy.
+
+For an executable, the required form of the "work that uses the Library" must
+include any data and utility programs needed for reproducing the executable
+from it. However, as a special exception, the source code distributed need
+not include anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the operating
+system on which the executable runs, unless that component itself accompanies
+the executable.
+
+It may happen that this requirement contradicts the license restrictions of
+other proprietary libraries that do not normally accompany the operating system.
+Such a contradiction means you cannot use both them and the Library together
+in an executable that you distribute.
+
+7. You may place library facilities that are a work based on the Library side-by-side
+in a single library together with other library facilities not covered by
+this License, and distribute such a combined library, provided that the separate
+distribution of the work based on the Library and of the other library facilities
+is otherwise permitted, and provided that you do these two things:
+
+a) Accompany the combined library with a copy of the same work based on the
+Library, uncombined with any other library facilities. This must be distributed
+under the terms of the Sections above.
+
+b) Give prominent notice with the combined library of the fact that part of
+it is a work based on the Library, and explaining where to find the accompanying
+uncombined form of the same work.
+
+8. You may not copy, modify, sublicense, link with, or distribute the Library
+except as expressly provided under this License. Any attempt otherwise to
+copy, modify, sublicense, link with, or distribute the Library is void, and
+will automatically terminate your rights under this License. However, parties
+who have received copies, or rights, from you under this License will not
+have their licenses terminated so long as such parties remain in full compliance.
+
+9. You are not required to accept this License, since you have not signed
+it. However, nothing else grants you permission to modify or distribute the
+Library or its derivative works. These actions are prohibited by law if you
+do not accept this License. Therefore, by modifying or distributing the Library
+(or any work based on the Library), you indicate your acceptance of this License
+to do so, and all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+10. Each time you redistribute the Library (or any work based on the Library),
+the recipient automatically receives a license from the original licensor
+to copy, distribute, link with or modify the Library subject to these terms
+and conditions. You may not impose any further restrictions on the recipients'
+exercise of the rights granted herein. You are not responsible for enforcing
+compliance by third parties to this License.
+
+11. If, as a consequence of a court judgment or allegation of patent infringement
+or for any other reason (not limited to patent issues), 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 distribute so as to satisfy simultaneously your
+obligations under this License and any other pertinent obligations, then as
+a consequence you may not distribute the Library at all. For example, if a
+patent license would not permit royalty-free redistribution of the Library
+by all those who receive copies directly or indirectly through you, then the
+only way you could satisfy both it and this License would be to refrain entirely
+from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents
+or other property right claims or to contest validity of any such claims;
+this section has the sole purpose of protecting the integrity of the free
+software distribution system which is implemented by public license practices.
+Many people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose
+that choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+12. If the distribution and/or use of the Library is restricted in certain
+countries either by patents or by copyrighted interfaces, the original copyright
+holder who places the Library under this License may add an explicit geographical
+distribution limitation excluding those countries, so that distribution is
+permitted only in or among countries not thus excluded. In such case, this
+License incorporates the limitation as if written in the body of this License.
+
+13. The Free Software Foundation may publish revised and/or new versions of
+the Library 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 Library specifies
+a version number of this License which applies to it and "any later version",
+you have the option of following the terms and conditions either of that version
+or of any later version published by the Free Software Foundation. If the
+Library does not specify a license version number, you may choose any version
+ever published by the Free Software Foundation.
+
+14. If you wish to incorporate parts of the Library into other free programs
+whose distribution conditions are incompatible with these, write to the author
+to ask for permission. For software which is copyrighted by the Free Software
+Foundation, write to the Free Software Foundation; we sometimes make exceptions
+for this. Our decision will be guided by the two goals of preserving the free
+status of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY
+"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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
+THE LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
+HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Libraries
+
+If you develop a new library, and you want it to be of the greatest possible
+use to the public, we recommend making it free software that everyone can
+redistribute and change. You can do so by permitting redistribution under
+these terms (or, alternatively, under the terms of the ordinary General Public
+License).
+
+To apply these terms, attach the following notices to the library. It is safest
+to attach them to the start of each source file to most effectively convey
+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 library's name and an idea of what it does.
+
+Copyright (C) year name of author
+
+This library is free software; you can redistribute it and/or modify it under
+the terms of the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+This library 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 Library General Public License for more
+details.
+
+You should have received a copy of the GNU Library General Public License
+along with this library; if not, write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your school,
+if any, to sign a "copyright disclaimer" for the library, if necessary. Here
+is a sample; alter the names:
+
+Yoyodyne, Inc., hereby disclaims all copyright interest in
+
+the library `Frob' (a library for tweaking knobs) written
+
+by James Random Hacker.
+
+signature of Ty Coon, 1 April 1990
+
+Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/LICENSES/LGPL-2.0-or-later.txt b/LICENSES/LGPL-2.0-or-later.txt
new file mode 100644
index 0000000..5c96471
--- /dev/null
+++ b/LICENSES/LGPL-2.0-or-later.txt
@@ -0,0 +1,446 @@
+GNU LIBRARY GENERAL PUBLIC LICENSE
+
+Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc.
+
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is numbered 2 because
+it goes with version 2 of the ordinary GPL.]
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share
+and change it. By contrast, the GNU General Public Licenses are intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users.
+
+This license, the Library General Public License, applies to some specially
+designated Free Software Foundation software, and to any other libraries whose
+authors decide to use it. You can use it for your libraries, 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 this service 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 make restrictions that forbid anyone to
+deny you these rights or to ask you to surrender the rights. These restrictions
+translate to certain responsibilities for you if you distribute copies of
+the library, or if you modify it.
+
+For example, if you distribute copies of the library, whether gratis or for
+a fee, you must give the recipients all the rights that we gave you. You must
+make sure that they, too, receive or can get the source code. If you link
+a program with the library, you must provide complete object files to the
+recipients so that they can relink them with the library, after making changes
+to the library and recompiling it. And you must show them these terms so they
+know their rights.
+
+Our method of protecting your rights has two steps: (1) copyright the library,
+and (2) offer you this license which gives you legal permission to copy, distribute
+and/or modify the library.
+
+Also, for each distributor's protection, we want to make certain that everyone
+understands that there is no warranty for this free library. If the library
+is modified by someone else and passed on, we want its recipients to know
+that what they have is not the original version, so that any problems introduced
+by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We
+wish to avoid the danger that companies distributing free software will individually
+obtain patent licenses, thus in effect transforming the program into proprietary
+software. To prevent this, we have made it clear that any patent must be licensed
+for everyone's free use or not licensed at all.
+
+Most GNU software, including some libraries, is covered by the ordinary GNU
+General Public License, which was designed for utility programs. This license,
+the GNU Library General Public License, applies to certain designated libraries.
+This license is quite different from the ordinary one; be sure to read it
+in full, and don't assume that anything in it is the same as in the ordinary
+license.
+
+The reason we have a separate public license for some libraries is that they
+blur the distinction we usually make between modifying or adding to a program
+and simply using it. Linking a program with a library, without changing the
+library, is in some sense simply using the library, and is analogous to running
+a utility program or application program. However, in a textual and legal
+sense, the linked executable is a combined work, a derivative of the original
+library, and the ordinary General Public License treats it as such.
+
+Because of this blurred distinction, using the ordinary General Public License
+for libraries did not effectively promote software sharing, because most developers
+did not use the libraries. We concluded that weaker conditions might promote
+sharing better.
+
+However, unrestricted linking of non-free programs would deprive the users
+of those programs of all benefit from the free status of the libraries themselves.
+This Library General Public License is intended to permit developers of non-free
+programs to use free libraries, while preserving your freedom as a user of
+such programs to change the free libraries that are incorporated in them.
+(We have not seen how to achieve this as regards changes in header files,
+but we have achieved it as regards changes in the actual functions of the
+Library.) The hope is that this will lead to faster development of free libraries.
+
+The precise terms and conditions for copying, distribution and modification
+follow. Pay close attention to the difference between a "work based on the
+library" and a "work that uses the library". The former contains code derived
+from the library, while the latter only works together with the library.
+
+Note that it is possible for a library to be covered by the ordinary General
+Public License rather than by this special one.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License Agreement applies to any software library which contains a
+notice placed by the copyright holder or other authorized party saying it
+may be distributed under the terms of this Library General Public License
+(also called "this License"). Each licensee is addressed as "you".
+
+A "library" means a collection of software functions and/or data prepared
+so as to be conveniently linked with application programs (which use some
+of those functions and data) to form executables.
+
+The "Library", below, refers to any such software library or work which has
+been distributed under these terms. A "work based on the Library" means either
+the Library or any derivative work under copyright law: that is to say, a
+work containing the Library or a portion of it, either verbatim or with modifications
+and/or translated straightforwardly into another language. (Hereinafter, translation
+is included without limitation in the term "modification".)
+
+"Source code" for a work means the preferred form of the work for making modifications
+to it. For a library, complete source code means all the source code for all
+modules it contains, plus any associated interface definition files, plus
+the scripts used to control compilation and installation of the library.
+
+Activities other than copying, distribution and modification are not covered
+by this License; they are outside its scope. The act of running a program
+using the Library is not restricted, and output from such a program is covered
+only if its contents constitute a work based on the Library (independent of
+the use of the Library in a tool for writing it). Whether that is true depends
+on what the Library does and what the program that uses the Library does.
+
+1. You may copy and distribute verbatim copies of the Library's complete source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and disclaimer
+of warranty; keep intact all the notices that refer to this License and to
+the absence of any warranty; and distribute a copy of this License along with
+the Library.
+
+You may charge a fee for the physical act of transferring a copy, and you
+may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Library or any portion of it,
+thus forming a work based on the Library, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all
+of these conditions:
+
+ a) The modified work must itself be a software library.
+
+b) You must cause the files modified to carry prominent notices stating that
+you changed the files and the date of any change.
+
+c) You must cause the whole of the work to be licensed at no charge to all
+third parties under the terms of this License.
+
+d) If a facility in the modified Library refers to a function or a table of
+data to be supplied by an application program that uses the facility, other
+than as an argument passed when the facility is invoked, then you must make
+a good faith effort to ensure that, in the event an application does not supply
+such function or table, the facility still operates, and performs whatever
+part of its purpose remains meaningful.
+
+(For example, a function in a library to compute square roots has a purpose
+that is entirely well-defined independent of the application. Therefore, Subsection
+2d requires that any application-supplied function or table used by this function
+must be optional: if the application does not supply it, the square root function
+must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Library, and can be reasonably
+considered independent and separate works in themselves, then this License,
+and its terms, do not apply to those sections when you distribute them as
+separate works. But when you distribute the same sections as part of a whole
+which is a work based on the Library, the distribution of the whole must be
+on the terms of this License, whose permissions for other licensees extend
+to the entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise
+the right to control the distribution of derivative or collective works based
+on the Library.
+
+In addition, mere aggregation of another work not based on the Library with
+the Library (or with a work based on the Library) on a volume of a storage
+or distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may opt to apply the terms of the ordinary GNU General Public License
+instead of this License to a given copy of the Library. To do this, you must
+alter all the notices that refer to this License, so that they refer to the
+ordinary GNU General Public License, version 2, instead of to this License.
+(If a newer version than version 2 of the ordinary GNU General Public License
+has appeared, then you can specify that version instead if you wish.) Do not
+make any other change in these notices.
+
+Once this change is made in a given copy, it is irreversible for that copy,
+so the ordinary GNU General Public License applies to all subsequent copies
+and derivative works made from that copy.
+
+This option is useful when you wish to copy part of the code of the Library
+into a program that is not a library.
+
+4. You may copy and distribute the Library (or a portion or derivative of
+it, under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you accompany it with the complete corresponding
+machine-readable source code, which must be distributed under the terms of
+Sections 1 and 2 above on a medium customarily used for software interchange.
+
+If distribution of object code is made by offering access to copy from a designated
+place, then offering equivalent access to copy the source code from the same
+place satisfies the requirement to distribute the source code, even though
+third parties are not compelled to copy the source along with the object code.
+
+5. A program that contains no derivative of any portion of the Library, but
+is designed to work with the Library by being compiled or linked with it,
+is called a "work that uses the Library". Such a work, in isolation, is not
+a derivative work of the Library, and therefore falls outside the scope of
+this License.
+
+However, linking a "work that uses the Library" with the Library creates an
+executable that is a derivative of the Library (because it contains portions
+of the Library), rather than a "work that uses the library". The executable
+is therefore covered by this License. Section 6 states terms for distribution
+of such executables.
+
+When a "work that uses the Library" uses material from a header file that
+is part of the Library, the object code for the work may be a derivative work
+of the Library even though the source code is not. Whether this is true is
+especially significant if the work can be linked without the Library, or if
+the work is itself a library. The threshold for this to be true is not precisely
+defined by law.
+
+If such an object file uses only numerical parameters, data structure layouts
+and accessors, and small macros and small inline functions (ten lines or less
+in length), then the use of the object file is unrestricted, regardless of
+whether it is legally a derivative work. (Executables containing this object
+code plus portions of the Library will still fall under Section 6.)
+
+Otherwise, if the work is a derivative of the Library, you may distribute
+the object code for the work under the terms of Section 6. Any executables
+containing that work also fall under Section 6, whether or not they are linked
+directly with the Library itself.
+
+6. As an exception to the Sections above, you may also compile or link a "work
+that uses the Library" with the Library to produce a work containing portions
+of the Library, and distribute that work under terms of your choice, provided
+that the terms permit modification of the work for the customer's own use
+and reverse engineering for debugging such modifications.
+
+You must give prominent notice with each copy of the work that the Library
+is used in it and that the Library and its use are covered by this License.
+You must supply a copy of this License. If the work during execution displays
+copyright notices, you must include the copyright notice for the Library among
+them, as well as a reference directing the user to the copy of this License.
+Also, you must do one of these things:
+
+a) Accompany the work with the complete corresponding machine-readable source
+code for the Library including whatever changes were used in the work (which
+must be distributed under Sections 1 and 2 above); and, if the work is an
+executable linked with the Library, with the complete machine-readable "work
+that uses the Library", as object code and/or source code, so that the user
+can modify the Library and then relink to produce a modified executable containing
+the modified Library. (It is understood that the user who changes the contents
+of definitions files in the Library will not necessarily be able to recompile
+the application to use the modified definitions.)
+
+b) Accompany the work with a written offer, valid for at least three years,
+to give the same user the materials specified in Subsection 6a, above, for
+a charge no more than the cost of performing this distribution.
+
+c) If distribution of the work is made by offering access to copy from a designated
+place, offer equivalent access to copy the above specified materials from
+the same place.
+
+d) Verify that the user has already received a copy of these materials or
+that you have already sent this user a copy.
+
+For an executable, the required form of the "work that uses the Library" must
+include any data and utility programs needed for reproducing the executable
+from it. However, as a special exception, the source code distributed need
+not include anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the operating
+system on which the executable runs, unless that component itself accompanies
+the executable.
+
+It may happen that this requirement contradicts the license restrictions of
+other proprietary libraries that do not normally accompany the operating system.
+Such a contradiction means you cannot use both them and the Library together
+in an executable that you distribute.
+
+7. You may place library facilities that are a work based on the Library side-by-side
+in a single library together with other library facilities not covered by
+this License, and distribute such a combined library, provided that the separate
+distribution of the work based on the Library and of the other library facilities
+is otherwise permitted, and provided that you do these two things:
+
+a) Accompany the combined library with a copy of the same work based on the
+Library, uncombined with any other library facilities. This must be distributed
+under the terms of the Sections above.
+
+b) Give prominent notice with the combined library of the fact that part of
+it is a work based on the Library, and explaining where to find the accompanying
+uncombined form of the same work.
+
+8. You may not copy, modify, sublicense, link with, or distribute the Library
+except as expressly provided under this License. Any attempt otherwise to
+copy, modify, sublicense, link with, or distribute the Library is void, and
+will automatically terminate your rights under this License. However, parties
+who have received copies, or rights, from you under this License will not
+have their licenses terminated so long as such parties remain in full compliance.
+
+9. You are not required to accept this License, since you have not signed
+it. However, nothing else grants you permission to modify or distribute the
+Library or its derivative works. These actions are prohibited by law if you
+do not accept this License. Therefore, by modifying or distributing the Library
+(or any work based on the Library), you indicate your acceptance of this License
+to do so, and all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+10. Each time you redistribute the Library (or any work based on the Library),
+the recipient automatically receives a license from the original licensor
+to copy, distribute, link with or modify the Library subject to these terms
+and conditions. You may not impose any further restrictions on the recipients'
+exercise of the rights granted herein. You are not responsible for enforcing
+compliance by third parties to this License.
+
+11. If, as a consequence of a court judgment or allegation of patent infringement
+or for any other reason (not limited to patent issues), 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 distribute so as to satisfy simultaneously your
+obligations under this License and any other pertinent obligations, then as
+a consequence you may not distribute the Library at all. For example, if a
+patent license would not permit royalty-free redistribution of the Library
+by all those who receive copies directly or indirectly through you, then the
+only way you could satisfy both it and this License would be to refrain entirely
+from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents
+or other property right claims or to contest validity of any such claims;
+this section has the sole purpose of protecting the integrity of the free
+software distribution system which is implemented by public license practices.
+Many people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose
+that choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+12. If the distribution and/or use of the Library is restricted in certain
+countries either by patents or by copyrighted interfaces, the original copyright
+holder who places the Library under this License may add an explicit geographical
+distribution limitation excluding those countries, so that distribution is
+permitted only in or among countries not thus excluded. In such case, this
+License incorporates the limitation as if written in the body of this License.
+
+13. The Free Software Foundation may publish revised and/or new versions of
+the Library 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 Library specifies
+a version number of this License which applies to it and "any later version",
+you have the option of following the terms and conditions either of that version
+or of any later version published by the Free Software Foundation. If the
+Library does not specify a license version number, you may choose any version
+ever published by the Free Software Foundation.
+
+14. If you wish to incorporate parts of the Library into other free programs
+whose distribution conditions are incompatible with these, write to the author
+to ask for permission. For software which is copyrighted by the Free Software
+Foundation, write to the Free Software Foundation; we sometimes make exceptions
+for this. Our decision will be guided by the two goals of preserving the free
+status of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY
+"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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
+THE LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
+HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Libraries
+
+If you develop a new library, and you want it to be of the greatest possible
+use to the public, we recommend making it free software that everyone can
+redistribute and change. You can do so by permitting redistribution under
+these terms (or, alternatively, under the terms of the ordinary General Public
+License).
+
+To apply these terms, attach the following notices to the library. It is safest
+to attach them to the start of each source file to most effectively convey
+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 library's name and an idea of what it does.
+
+Copyright (C) year name of author
+
+This library is free software; you can redistribute it and/or modify it under
+the terms of the GNU Library General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+This library 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 Library General Public License for more
+details.
+
+You should have received a copy of the GNU Library General Public License
+along with this library; if not, write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your school,
+if any, to sign a "copyright disclaimer" for the library, if necessary. Here
+is a sample; alter the names:
+
+Yoyodyne, Inc., hereby disclaims all copyright interest in
+
+the library `Frob' (a library for tweaking knobs) written
+
+by James Random Hacker.
+
+signature of Ty Coon, 1 April 1990
+
+Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/LICENSES/LGPL-2.1-only.txt b/LICENSES/LGPL-2.1-only.txt
new file mode 100644
index 0000000..130dffb
--- /dev/null
+++ b/LICENSES/LGPL-2.1-only.txt
@@ -0,0 +1,467 @@
+GNU LESSER GENERAL PUBLIC LICENSE
+
+Version 2.1, February 1999
+
+Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts as the
+successor of the GNU Library Public License, version 2, hence the version
+number 2.1.]
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share
+and change it. By contrast, the GNU General Public Licenses are intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users.
+
+This license, the Lesser General Public License, applies to some specially
+designated software packages--typically libraries--of the Free Software Foundation
+and other authors who decide to use it. You can use it too, but we suggest
+you first think carefully about whether this license or the ordinary General
+Public License is the better strategy to use in any particular case, based
+on the explanations below.
+
+When we speak of free software, we are referring to freedom of use, 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 this service if you
+wish); that you receive source code or can get it if you want it; that you
+can change the software and use pieces of it in new free programs; and that
+you are informed that you can do these things.
+
+To protect your rights, we need to make restrictions that forbid distributors
+to deny you these rights or to ask you to surrender these rights. These restrictions
+translate to certain responsibilities for you if you distribute copies of
+the library or if you modify it.
+
+For example, if you distribute copies of the library, whether gratis or for
+a fee, you must give the recipients all the rights that we gave you. You must
+make sure that they, too, receive or can get the source code. If you link
+other code with the library, you must provide complete object files to the
+recipients, so that they can relink them with the library after making changes
+to the library and recompiling it. And you must show them these terms so they
+know their rights.
+
+We protect your rights with a two-step method: (1) we copyright the library,
+and (2) we offer you this license, which gives you legal permission to copy,
+distribute and/or modify the library.
+
+To protect each distributor, we want to make it very clear that there is no
+warranty for the free library. Also, if the library is modified by someone
+else and passed on, the recipients should know that what they have is not
+the original version, so that the original author's reputation will not be
+affected by problems that might be introduced by others.
+
+Finally, software patents pose a constant threat to the existence of any free
+program. We wish to make sure that a company cannot effectively restrict the
+users of a free program by obtaining a restrictive license from a patent holder.
+Therefore, we insist that any patent license obtained for a version of the
+library must be consistent with the full freedom of use specified in this
+license.
+
+Most GNU software, including some libraries, is covered by the ordinary GNU
+General Public License. This license, the GNU Lesser General Public License,
+applies to certain designated libraries, and is quite different from the ordinary
+General Public License. We use this license for certain libraries in order
+to permit linking those libraries into non-free programs.
+
+When a program is linked with a library, whether statically or using a shared
+library, the combination of the two is legally speaking a combined work, a
+derivative of the original library. The ordinary General Public License therefore
+permits such linking only if the entire combination fits its criteria of freedom.
+The Lesser General Public License permits more lax criteria for linking other
+code with the library.
+
+We call this license the "Lesser" General Public License because it does Less
+to protect the user's freedom than the ordinary General Public License. It
+also provides other free software developers Less of an advantage over competing
+non-free programs. These disadvantages are the reason we use the ordinary
+General Public License for many libraries. However, the Lesser license provides
+advantages in certain special circumstances.
+
+For example, on rare occasions, there may be a special need to encourage the
+widest possible use of a certain library, so that it becomes a de-facto standard.
+To achieve this, non-free programs must be allowed to use the library. A more
+frequent case is that a free library does the same job as widely used non-free
+libraries. In this case, there is little to gain by limiting the free library
+to free software only, so we use the Lesser General Public License.
+
+In other cases, permission to use a particular library in non-free programs
+enables a greater number of people to use a large body of free software. For
+example, permission to use the GNU C Library in non-free programs enables
+many more people to use the whole GNU operating system, as well as its variant,
+the GNU/Linux operating system.
+
+Although the Lesser General Public License is Less protective of the users'
+freedom, it does ensure that the user of a program that is linked with the
+Library has the freedom and the wherewithal to run that program using a modified
+version of the Library.
+
+The precise terms and conditions for copying, distribution and modification
+follow. Pay close attention to the difference between a "work based on the
+library" and a "work that uses the library". The former contains code derived
+from the library, whereas the latter must be combined with the library in
+order to run.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License Agreement applies to any software library or other program
+which contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Lesser General
+Public License (also called "this License"). Each licensee is addressed as
+"you".
+
+A "library" means a collection of software functions and/or data prepared
+so as to be conveniently linked with application programs (which use some
+of those functions and data) to form executables.
+
+The "Library", below, refers to any such software library or work which has
+been distributed under these terms. A "work based on the Library" means either
+the Library or any derivative work under copyright law: that is to say, a
+work containing the Library or a portion of it, either verbatim or with modifications
+and/or translated straightforwardly into another language. (Hereinafter, translation
+is included without limitation in the term "modification".)
+
+"Source code" for a work means the preferred form of the work for making modifications
+to it. For a library, complete source code means all the source code for all
+modules it contains, plus any associated interface definition files, plus
+the scripts used to control compilation and installation of the library.
+
+Activities other than copying, distribution and modification are not covered
+by this License; they are outside its scope. The act of running a program
+using the Library is not restricted, and output from such a program is covered
+only if its contents constitute a work based on the Library (independent of
+the use of the Library in a tool for writing it). Whether that is true depends
+on what the Library does and what the program that uses the Library does.
+
+1. You may copy and distribute verbatim copies of the Library's complete source
+code as you receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice and disclaimer
+of warranty; keep intact all the notices that refer to this License and to
+the absence of any warranty; and distribute a copy of this License along with
+the Library.
+
+You may charge a fee for the physical act of transferring a copy, and you
+may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Library or any portion of it,
+thus forming a work based on the Library, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all
+of these conditions:
+
+ a) The modified work must itself be a software library.
+
+b) You must cause the files modified to carry prominent notices stating that
+you changed the files and the date of any change.
+
+c) You must cause the whole of the work to be licensed at no charge to all
+third parties under the terms of this License.
+
+d) If a facility in the modified Library refers to a function or a table of
+data to be supplied by an application program that uses the facility, other
+than as an argument passed when the facility is invoked, then you must make
+a good faith effort to ensure that, in the event an application does not supply
+such function or table, the facility still operates, and performs whatever
+part of its purpose remains meaningful.
+
+(For example, a function in a library to compute square roots has a purpose
+that is entirely well-defined independent of the application. Therefore, Subsection
+2d requires that any application-supplied function or table used by this function
+must be optional: if the application does not supply it, the square root function
+must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Library, and can be reasonably
+considered independent and separate works in themselves, then this License,
+and its terms, do not apply to those sections when you distribute them as
+separate works. But when you distribute the same sections as part of a whole
+which is a work based on the Library, the distribution of the whole must be
+on the terms of this License, whose permissions for other licensees extend
+to the entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise
+the right to control the distribution of derivative or collective works based
+on the Library.
+
+In addition, mere aggregation of another work not based on the Library with
+the Library (or with a work based on the Library) on a volume of a storage
+or distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may opt to apply the terms of the ordinary GNU General Public License
+instead of this License to a given copy of the Library. To do this, you must
+alter all the notices that refer to this License, so that they refer to the
+ordinary GNU General Public License, version 2, instead of to this License.
+(If a newer version than version 2 of the ordinary GNU General Public License
+has appeared, then you can specify that version instead if you wish.) Do not
+make any other change in these notices.
+
+Once this change is made in a given copy, it is irreversible for that copy,
+so the ordinary GNU General Public License applies to all subsequent copies
+and derivative works made from that copy.
+
+This option is useful when you wish to copy part of the code of the Library
+into a program that is not a library.
+
+4. You may copy and distribute the Library (or a portion or derivative of
+it, under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you accompany it with the complete corresponding
+machine-readable source code, which must be distributed under the terms of
+Sections 1 and 2 above on a medium customarily used for software interchange.
+
+If distribution of object code is made by offering access to copy from a designated
+place, then offering equivalent access to copy the source code from the same
+place satisfies the requirement to distribute the source code, even though
+third parties are not compelled to copy the source along with the object code.
+
+5. A program that contains no derivative of any portion of the Library, but
+is designed to work with the Library by being compiled or linked with it,
+is called a "work that uses the Library". Such a work, in isolation, is not
+a derivative work of the Library, and therefore falls outside the scope of
+this License.
+
+However, linking a "work that uses the Library" with the Library creates an
+executable that is a derivative of the Library (because it contains portions
+of the Library), rather than a "work that uses the library". The executable
+is therefore covered by this License. Section 6 states terms for distribution
+of such executables.
+
+When a "work that uses the Library" uses material from a header file that
+is part of the Library, the object code for the work may be a derivative work
+of the Library even though the source code is not. Whether this is true is
+especially significant if the work can be linked without the Library, or if
+the work is itself a library. The threshold for this to be true is not precisely
+defined by law.
+
+If such an object file uses only numerical parameters, data structure layouts
+and accessors, and small macros and small inline functions (ten lines or less
+in length), then the use of the object file is unrestricted, regardless of
+whether it is legally a derivative work. (Executables containing this object
+code plus portions of the Library will still fall under Section 6.)
+
+Otherwise, if the work is a derivative of the Library, you may distribute
+the object code for the work under the terms of Section 6. Any executables
+containing that work also fall under Section 6, whether or not they are linked
+directly with the Library itself.
+
+6. As an exception to the Sections above, you may also combine or link a "work
+that uses the Library" with the Library to produce a work containing portions
+of the Library, and distribute that work under terms of your choice, provided
+that the terms permit modification of the work for the customer's own use
+and reverse engineering for debugging such modifications.
+
+You must give prominent notice with each copy of the work that the Library
+is used in it and that the Library and its use are covered by this License.
+You must supply a copy of this License. If the work during execution displays
+copyright notices, you must include the copyright notice for the Library among
+them, as well as a reference directing the user to the copy of this License.
+Also, you must do one of these things:
+
+a) Accompany the work with the complete corresponding machine-readable source
+code for the Library including whatever changes were used in the work (which
+must be distributed under Sections 1 and 2 above); and, if the work is an
+executable linked with the Library, with the complete machine-readable "work
+that uses the Library", as object code and/or source code, so that the user
+can modify the Library and then relink to produce a modified executable containing
+the modified Library. (It is understood that the user who changes the contents
+of definitions files in the Library will not necessarily be able to recompile
+the application to use the modified definitions.)
+
+b) Use a suitable shared library mechanism for linking with the Library. A
+suitable mechanism is one that (1) uses at run time a copy of the library
+already present on the user's computer system, rather than copying library
+functions into the executable, and (2) will operate properly with a modified
+version of the library, if the user installs one, as long as the modified
+version is interface-compatible with the version that the work was made with.
+
+c) Accompany the work with a written offer, valid for at least three years,
+to give the same user the materials specified in Subsection 6a, above, for
+a charge no more than the cost of performing this distribution.
+
+d) If distribution of the work is made by offering access to copy from a designated
+place, offer equivalent access to copy the above specified materials from
+the same place.
+
+e) Verify that the user has already received a copy of these materials or
+that you have already sent this user a copy.
+
+For an executable, the required form of the "work that uses the Library" must
+include any data and utility programs needed for reproducing the executable
+from it. However, as a special exception, the materials to be distributed
+need not include anything that is normally distributed (in either source or
+binary form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component itself
+accompanies the executable.
+
+It may happen that this requirement contradicts the license restrictions of
+other proprietary libraries that do not normally accompany the operating system.
+Such a contradiction means you cannot use both them and the Library together
+in an executable that you distribute.
+
+7. You may place library facilities that are a work based on the Library side-by-side
+in a single library together with other library facilities not covered by
+this License, and distribute such a combined library, provided that the separate
+distribution of the work based on the Library and of the other library facilities
+is otherwise permitted, and provided that you do these two things:
+
+a) Accompany the combined library with a copy of the same work based on the
+Library, uncombined with any other library facilities. This must be distributed
+under the terms of the Sections above.
+
+b) Give prominent notice with the combined library of the fact that part of
+it is a work based on the Library, and explaining where to find the accompanying
+uncombined form of the same work.
+
+8. You may not copy, modify, sublicense, link with, or distribute the Library
+except as expressly provided under this License. Any attempt otherwise to
+copy, modify, sublicense, link with, or distribute the Library is void, and
+will automatically terminate your rights under this License. However, parties
+who have received copies, or rights, from you under this License will not
+have their licenses terminated so long as such parties remain in full compliance.
+
+9. You are not required to accept this License, since you have not signed
+it. However, nothing else grants you permission to modify or distribute the
+Library or its derivative works. These actions are prohibited by law if you
+do not accept this License. Therefore, by modifying or distributing the Library
+(or any work based on the Library), you indicate your acceptance of this License
+to do so, and all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+10. Each time you redistribute the Library (or any work based on the Library),
+the recipient automatically receives a license from the original licensor
+to copy, distribute, link with or modify the Library subject to these terms
+and conditions. You may not impose any further restrictions on the recipients'
+exercise of the rights granted herein. You are not responsible for enforcing
+compliance by third parties with this License.
+
+11. If, as a consequence of a court judgment or allegation of patent infringement
+or for any other reason (not limited to patent issues), 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 distribute so as to satisfy simultaneously your
+obligations under this License and any other pertinent obligations, then as
+a consequence you may not distribute the Library at all. For example, if a
+patent license would not permit royalty-free redistribution of the Library
+by all those who receive copies directly or indirectly through you, then the
+only way you could satisfy both it and this License would be to refrain entirely
+from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents
+or other property right claims or to contest validity of any such claims;
+this section has the sole purpose of protecting the integrity of the free
+software distribution system which is implemented by public license practices.
+Many people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose
+that choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+12. If the distribution and/or use of the Library is restricted in certain
+countries either by patents or by copyrighted interfaces, the original copyright
+holder who places the Library under this License may add an explicit geographical
+distribution limitation excluding those countries, so that distribution is
+permitted only in or among countries not thus excluded. In such case, this
+License incorporates the limitation as if written in the body of this License.
+
+13. The Free Software Foundation may publish revised and/or new versions of
+the Lesser 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 Library specifies
+a version number of this License which applies to it and "any later version",
+you have the option of following the terms and conditions either of that version
+or of any later version published by the Free Software Foundation. If the
+Library does not specify a license version number, you may choose any version
+ever published by the Free Software Foundation.
+
+14. If you wish to incorporate parts of the Library into other free programs
+whose distribution conditions are incompatible with these, write to the author
+to ask for permission. For software which is copyrighted by the Free Software
+Foundation, write to the Free Software Foundation; we sometimes make exceptions
+for this. Our decision will be guided by the two goals of preserving the free
+status of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY
+"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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
+THE LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
+HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Libraries
+
+If you develop a new library, and you want it to be of the greatest possible
+use to the public, we recommend making it free software that everyone can
+redistribute and change. You can do so by permitting redistribution under
+these terms (or, alternatively, under the terms of the ordinary General Public
+License).
+
+To apply these terms, attach the following notices to the library. It is safest
+to attach them to the start of each source file to most effectively convey
+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 library's name and an idea of what it does. >
+
+Copyright (C) < year > < name of author >
+
+This library is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free
+Software Foundation; either version 2.1 of the License, or (at your option)
+any later version.
+
+This library is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this library; if not, write to the Free Software Foundation, Inc., 51
+Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information
+on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your school,
+if any, to sign a "copyright disclaimer" for the library, if necessary. Here
+is a sample; alter the names:
+
+Yoyodyne, Inc., hereby disclaims all copyright interest in
+
+the library `Frob' (a library for tweaking knobs) written
+
+by James Random Hacker.
+
+< signature of Ty Coon > , 1 April 1990
+
+Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/LICENSES/LGPL-3.0-only.txt b/LICENSES/LGPL-3.0-only.txt
new file mode 100644
index 0000000..bd405af
--- /dev/null
+++ b/LICENSES/LGPL-3.0-only.txt
@@ -0,0 +1,163 @@
+GNU LESSER GENERAL PUBLIC LICENSE
+
+Version 3, 29 June 2007
+
+Copyright (C) 2007 Free Software Foundation, Inc.
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+This version of the GNU Lesser General Public License incorporates the terms
+and conditions of version 3 of the GNU General Public License, supplemented
+by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+
+
+As used herein, "this License" refers to version 3 of the GNU Lesser General
+Public License, and the "GNU GPL" refers to version 3 of the GNU General Public
+License.
+
+
+
+"The Library" refers to a covered work governed by this License, other than
+an Application or a Combined Work as defined below.
+
+
+
+An "Application" is any work that makes use of an interface provided by the
+Library, but which is not otherwise based on the Library. Defining a subclass
+of a class defined by the Library is deemed a mode of using an interface provided
+by the Library.
+
+
+
+A "Combined Work" is a work produced by combining or linking an Application
+with the Library. The particular version of the Library with which the Combined
+Work was made is also called the "Linked Version".
+
+
+
+The "Minimal Corresponding Source" for a Combined Work means the Corresponding
+Source for the Combined Work, excluding any source code for portions of the
+Combined Work that, considered in isolation, are based on the Application,
+and not on the Linked Version.
+
+
+
+The "Corresponding Application Code" for a Combined Work means the object
+code and/or source code for the Application, including any data and utility
+programs needed for reproducing the Combined Work from the Application, but
+excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+You may convey a covered work under sections 3 and 4 of this License without
+being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+If you modify a copy of the Library, and, in your modifications, a facility
+refers to a function or data to be supplied by an Application that uses the
+facility (other than as an argument passed when the facility is invoked),
+then you may convey a copy of the modified version:
+
+a) under this License, provided that you make a good faith effort to ensure
+that, in the event an Application does not supply the function or data, the
+facility still operates, and performs whatever part of its purpose remains
+meaningful, or
+
+b) under the GNU GPL, with none of the additional permissions of this License
+applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+The object code form of an Application may incorporate material from a header
+file that is part of the Library. You may convey such object code under terms
+of your choice, provided that, if the incorporated material is not limited
+to numerical parameters, data structure layouts and accessors, or small macros,
+inline functions and templates (ten or fewer lines in length), you do both
+of the following:
+
+a) Give prominent notice with each copy of the object code that the Library
+is used in it and that the Library and its use are covered by this License.
+
+b) Accompany the object code with a copy of the GNU GPL and this license document.
+
+ 4. Combined Works.
+
+You may convey a Combined Work under terms of your choice that, taken together,
+effectively do not restrict modification of the portions of the Library contained
+in the Combined Work and reverse engineering for debugging such modifications,
+if you also do each of the following:
+
+a) Give prominent notice with each copy of the Combined Work that the Library
+is used in it and that the Library and its use are covered by this License.
+
+b) Accompany the Combined Work with a copy of the GNU GPL and this license
+document.
+
+c) For a Combined Work that displays copyright notices during execution, include
+the copyright notice for the Library among these notices, as well as a reference
+directing the user to the copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+0) Convey the Minimal Corresponding Source under the terms of this License,
+and the Corresponding Application Code in a form suitable for, and under terms
+that permit, the user to recombine or relink the Application with a modified
+version of the Linked Version to produce a modified Combined Work, in the
+manner specified by section 6 of the GNU GPL for conveying Corresponding Source.
+
+1) Use a suitable shared library mechanism for linking with the Library. A
+suitable mechanism is one that (a) uses at run time a copy of the Library
+already present on the user's computer system, and (b) will operate properly
+with a modified version of the Library that is interface-compatible with the
+Linked Version.
+
+e) Provide Installation Information, but only if you would otherwise be required
+to provide such information under section 6 of the GNU GPL, and only to the
+extent that such information is necessary to install and execute a modified
+version of the Combined Work produced by recombining or relinking the Application
+with a modified version of the Linked Version. (If you use option 4d0, the
+Installation Information must accompany the Minimal Corresponding Source and
+Corresponding Application Code. If you use option 4d1, you must provide the
+Installation Information in the manner specified by section 6 of the GNU GPL
+for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+You may place library facilities that are a work based on the Library side
+by side in a single library together with other library facilities that are
+not Applications and are not covered by this License, and convey such a combined
+library under terms of your choice, if you do both of the following:
+
+a) Accompany the combined library with a copy of the same work based on the
+Library, uncombined with any other library facilities, conveyed under the
+terms of this License.
+
+b) Give prominent notice with the combined library that part of it is a work
+based on the Library, and explaining where to find the accompanying uncombined
+form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+The Free Software Foundation may publish revised and/or new versions of the
+GNU Lesser 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 Library as you
+received it specifies that a certain numbered version of the GNU Lesser General
+Public License "or any later version" applies to it, you have the option of
+following the terms and conditions either of that published version or of
+any later version published by the Free Software Foundation. If the Library
+as you received it does not specify a version number of the GNU Lesser General
+Public License, you may choose any version of the GNU Lesser General Public
+License ever published by the Free Software Foundation.
+
+If the Library as you received it specifies that a proxy can decide whether
+future versions of the GNU Lesser General Public License shall apply, that
+proxy's public statement of acceptance of any version is permanent authorization
+for you to choose that version for the Library.
diff --git a/LICENSES/LicenseRef-KDE-Accepted-LGPL.txt b/LICENSES/LicenseRef-KDE-Accepted-LGPL.txt
new file mode 100644
index 0000000..232b3c5
--- /dev/null
+++ b/LICENSES/LicenseRef-KDE-Accepted-LGPL.txt
@@ -0,0 +1,12 @@
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 3 of the license or (at your option) any later version
+that is accepted by the membership of KDE e.V. (or its successor
+approved by the membership of KDE e.V.), which shall act as a
+proxy as defined in Section 6 of version 3 of the license.
+
+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.
diff --git a/autotests/deadservicetest.cpp b/autotests/deadservicetest.cpp
index 876f7fe..a794d75 100644
--- a/autotests/deadservicetest.cpp
+++ b/autotests/deadservicetest.cpp
@@ -1,114 +1,103 @@
-/* This file is part of libkdbus
+/*
+ This file is part of libkdbus
- Copyright (c) 2019 Harald Sitter
+ SPDX-FileCopyrightText: 2019 Harald Sitter
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License version 2 as published by the Free Software Foundation.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
+ SPDX-License-Identifier: LGPL-2.0-only
*/
#include
#include
#include
#include
#include
#include
#include
#include
static const QString s_serviceName = QStringLiteral("org.kde.kdbussimpleservice");
class TestObject : public QObject
{
Q_OBJECT
QList m_danglingPids;
private Q_SLOTS:
void cleanupTestCase()
{
// Make sure we don't leave dangling processes even when we had an
// error and the process is stopped.
for (int pid : m_danglingPids) {
kill(pid, SIGKILL);
}
}
void testDeadService()
{
QVERIFY(!QDBusConnection::sessionBus().interface()->isServiceRegistered(s_serviceName).value());
QProcess proc1;
proc1.setProgram(QFINDTESTDATA("kdbussimpleservice"));
proc1.setProcessChannelMode(QProcess::ForwardedChannels);
proc1.start();
QVERIFY(proc1.waitForStarted());
m_danglingPids << proc1.pid();
// Spy isn't very suitable here because we'd be racing with proc1 or
// signal blocking since we'd need to unblock before spying but then
// there is an É› between unblock and spy.
Q_PID pid1 = proc1.pid(); // store local, in case the proc disappears
QVERIFY(pid1 >= 0);
bool proc1Registered = QTest::qWaitFor([&]() {
QTest::qSleep(1000);
return QDBusConnection::sessionBus().interface()->servicePid(s_serviceName).value() == pid1;
}, 8000);
QVERIFY(proc1Registered);
// suspend proc1, we don't want it responding on dbus anymore, but still
// be running so it holds the name.
QCOMPARE(kill(proc1.pid(), SIGSTOP), 0);
// start second instance
QProcess proc2;
proc2.setProgram(QFINDTESTDATA("kdbussimpleservice"));
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("KCRASH_AUTO_RESTARTED", "1");
proc2.setProcessEnvironment(env);
proc2.setProcessChannelMode(QProcess::ForwardedChannels);
proc2.start();
QVERIFY(proc2.waitForStarted());
m_danglingPids << proc2.pid();
// sleep a bit. fairly awkward. we need proc2 to be waiting on the name
// but we can't easily determine when it started waiting. in lieu of
// better instrumentation let's just sleep a bit.
qDebug() << "sleeping";
QTest::qSleep(4000);
// Let proc1 go up in flames so that dbus-daemon reclaims the name and
// gives it to proc2.
qDebug() << "murder on the orient express";
QCOMPARE(0, kill(proc1.pid(), SIGUSR1));
QCOMPARE(0, kill(proc1.pid(), SIGCONT));
Q_PID pid2 = proc2.pid(); // store local, in case the proc disappears
QVERIFY(pid2 >= 0);
// Wait for service to be owned by proc2.
bool proc2Registered = QTest::qWaitFor([&]() {
QTest::qSleep(1000);
return QDBusConnection::sessionBus().interface()->servicePid(s_serviceName).value() == pid2;
}, 8000);
QVERIFY(proc2Registered);
proc1.kill();
m_danglingPids.removeAll(pid1);
proc2.kill();
m_danglingPids.removeAll(pid2);
}
};
QTEST_MAIN(TestObject)
#include "deadservicetest.moc"
diff --git a/autotests/kdbusinterprocesslocktest.cpp b/autotests/kdbusinterprocesslocktest.cpp
index e19dde7..aed4023 100644
--- a/autotests/kdbusinterprocesslocktest.cpp
+++ b/autotests/kdbusinterprocesslocktest.cpp
@@ -1,136 +1,125 @@
-/* This file is part of libkdbus
+/*
+ This file is part of libkdbus
- Copyright (c) 2011 Kevin Ottens
+ SPDX-FileCopyrightText: 2011 Kevin Ottens
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License version 2 as published by the Free Software Foundation.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
+ SPDX-License-Identifier: LGPL-2.0-only
*/
#include
#include
#include
#include
#include
#include
#include
static const char *counterFileName = "kdbusinterprocesslocktest.counter";
void writeCounter(int value)
{
QFile file(counterFileName);
file.open(QFile::WriteOnly);
QTextStream stream(&file);
stream << value;
file.close();
}
int readCounter()
{
QFile file(counterFileName);
file.open(QFile::ReadOnly);
QTextStream stream(&file);
int value = 0;
stream >> value;
file.close();
return value;
}
void removeCounter()
{
QFile::remove(counterFileName);
}
QProcess *executeNewChild()
{
qDebug() << "executeNewChild";
// Duplicated from kglobalsettingstest.cpp - make a shared helper method?
QProcess *proc = new QProcess();
QString appName = QStringLiteral("kdbusinterprocesslocktest");
#ifdef Q_OS_WIN
appName += ".exe";
#else
if (QFile::exists(appName + ".shell")) {
appName = "./" + appName + ".shell";
} else {
Q_ASSERT(QFile::exists(appName));
appName = "./" + appName;
}
#endif
proc->setProcessChannelMode(QProcess::ForwardedChannels);
proc->start(appName, QStringList() << QStringLiteral("child"));
return proc;
}
void work(int id, KDBusInterProcessLock &lock)
{
for (int i = 0; i < 10; i++) {
qDebug("%d: retrieve lock...", id);
lock.lock();
qDebug("%d: waiting...", id);
lock.waitForLockGranted();
qDebug("%d: retrieved lock", id);
int value = readCounter() + 1;
writeCounter(value);
qDebug("%d: counter updated to %d", id, value);
lock.unlock();
qDebug("%d: sleeping", id);
QTest::qSleep(20);
}
qDebug("%d: done", id);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QCoreApplication::setApplicationName(QStringLiteral("kdbusinterprocesslocktest"));
QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org"));
QDir::setCurrent(QCoreApplication::applicationDirPath());
KDBusInterProcessLock lock(QStringLiteral("myfunnylock"));
if (argc >= 2) {
work(2, lock);
return 0;
}
writeCounter(0);
QProcess *proc = executeNewChild();
work(1, lock);
proc->waitForFinished();
delete proc;
int value = readCounter();
qDebug("Final value: %d", value);
const bool ok = (value == 20);
removeCounter();
return ok ? 0 : 1;
}
diff --git a/autotests/kdbusservicetest.cpp b/autotests/kdbusservicetest.cpp
index 8a219d0..fa8be0d 100644
--- a/autotests/kdbusservicetest.cpp
+++ b/autotests/kdbusservicetest.cpp
@@ -1,169 +1,158 @@
-/* This file is part of libkdbus
+/*
+ This file is part of libkdbus
- Copyright (c) 1999 Waldo Bastian
- Copyright (c) 2011 David Faure
- Copyright (c) 2011 Kevin Ottens
+ SPDX-FileCopyrightText: 1999 Waldo Bastian
+ SPDX-FileCopyrightText: 2011 David Faure
+ SPDX-FileCopyrightText: 2011 Kevin Ottens
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License version 2 as published by the Free Software Foundation.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
+ SPDX-License-Identifier: LGPL-2.0-only
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
class TestObject : public QObject
{
Q_OBJECT
public:
TestObject(KDBusService *service)
: m_proc(nullptr), m_callCount(0),
m_service(service)
{}
~TestObject()
{
if (m_proc) {
m_proc->waitForFinished();
}
}
int callCount() const
{
return m_callCount;
}
private Q_SLOTS:
void slotActivateRequested(const QStringList &args, const QString &workingDirectory)
{
Q_UNUSED(workingDirectory);
qDebug() << "Application executed with args" << args;
++m_callCount;
if (m_callCount == 1) {
Q_ASSERT(args.count() == 1);
Q_ASSERT(args.at(0) == QLatin1String("dummy call"));
} else if (m_callCount == 2) {
Q_ASSERT(args.count() == 2);
Q_ASSERT(args.at(1) == QLatin1String("bad call"));
m_service->setExitValue(4);
} else if (m_callCount == 3) {
Q_ASSERT(args.count() == 3);
Q_ASSERT(args.at(1) == QLatin1String("real call"));
Q_ASSERT(args.at(2) == QLatin1String("second arg"));
// OK, all done, quit
QCoreApplication::instance()->quit();
}
}
void slotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
Q_UNUSED(exitStatus)
qDebug() << "Process exited with code" << exitCode;
m_proc = nullptr;
if (m_callCount == 2) {
Q_ASSERT(exitCode == 4);
secondCall();
}
}
void firstCall()
{
QStringList args;
args << QStringLiteral("bad call");
executeNewChild(args);
}
void secondCall()
{
QStringList args;
args << QStringLiteral("real call") << QStringLiteral("second arg");
executeNewChild(args);
}
private:
void executeNewChild(const QStringList &args)
{
// Duplicated from kglobalsettingstest.cpp - make a shared helper method?
m_proc = new QProcess(this);
connect(m_proc, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(slotProcessFinished(int,QProcess::ExitStatus)));
QString appName = QStringLiteral("kdbusservicetest");
#ifdef Q_OS_WIN
appName += ".exe";
#else
if (QFile::exists(appName + ".shell")) {
appName = "./" + appName + ".shell";
} else {
Q_ASSERT(QFile::exists(appName));
appName = "./" + appName;
}
#endif
qDebug() << "about to run" << appName << args;
m_proc->start(appName, args);
}
QProcess *m_proc;
int m_callCount;
KDBusService *m_service;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QCoreApplication::setApplicationName(QStringLiteral("kdbusservicetest"));
QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org"));
QDir::setCurrent(QCoreApplication::applicationDirPath());
KDBusService service(KDBusService::Unique);
TestObject testObject(&service);
QObject::connect(&service, SIGNAL(activateRequested(QStringList,QString)),
&testObject, SLOT(slotActivateRequested(QStringList,QString)));
// Testcase for the problem coming from the old fork-on-startup solution:
// the "Activate" D-Bus call would time out if the app took too much time
// to be ready.
//printf("Sleeping.\n");
//sleep(200);
QStringList args;
args << QStringLiteral("dummy call");
QMetaObject::invokeMethod(&service, "activateRequested",
Qt::QueuedConnection,
Q_ARG(QStringList, args),
Q_ARG(QString, QDir::currentPath()));
QTimer::singleShot(400, &testObject, SLOT(firstCall()));
qDebug() << "Running.";
a.exec();
qDebug() << "Terminating.";
Q_ASSERT(testObject.callCount() == 3);
const bool ok = testObject.callCount() == 3;
return ok ? 0 : 1;
}
#include "kdbusservicetest.moc"
diff --git a/autotests/kdbussimpleservice.cpp b/autotests/kdbussimpleservice.cpp
index b83746d..c2b1bcd 100644
--- a/autotests/kdbussimpleservice.cpp
+++ b/autotests/kdbussimpleservice.cpp
@@ -1,90 +1,79 @@
-/* This file is part of libkdbus
+/*
+ This file is part of libkdbus
- Copyright (c) 2019 Harald Sitter
+ SPDX-FileCopyrightText: 2019 Harald Sitter
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License version 2 as published by the Free Software Foundation.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
+ SPDX-License-Identifier: LGPL-2.0-only
*/
#include
#include
#include
#include
// sigaction
#include
// close
#include
// rlimit
#include
#include
// USR1.
// Close all sockets and eventually ABRT. This mimics behavior during KCrash
// handling. Closing all sockets will effectively disconnect us from the bus
// and result in the daemon reclaiming all our service names and allowing
// other processes to register them instead.
void usr1_handler(int signum)
{
qDebug() << "usr1" << signum << SIGSEGV;
// Close all remaining file descriptors so we drop off of the bus.
struct rlimit rlp;
getrlimit(RLIMIT_NOFILE, &rlp);
for (int i = 3; i < (int)rlp.rlim_cur; i++) {
close(i);
}
// Sleep a bit for good measure. We could actually loop ad infinitum here
// as after USR1 we are expected to get killed. In the interest of sane
// behavior we'll simply exit on our own as well though.
sleep(4);
abort();
}
// Simple application under test.
// Closes all sockets on USR1 and aborts to simulate a kcrash shutdown behavior
// which can result in a service registration race.
int main(int argc, char *argv[])
{
qDebug() << "hello there!";
struct sigaction action;
action.sa_handler = usr1_handler;
sigemptyset(&action.sa_mask);
sigaddset(&action.sa_mask, SIGUSR1);
action.sa_flags = SA_RESTART;
if (sigaction(SIGUSR1, &action, nullptr) < 0) {
qDebug() << "failed to register segv handler";
return 1;
}
QCoreApplication app(argc, argv);
QCoreApplication::setApplicationName("kdbussimpleservice");
QCoreApplication::setOrganizationDomain("kde.org");
KDBusService service(KDBusService::Unique);
if (!service.isRegistered()) {
qDebug() << "service not registered => exiting";
return 1;
}
qDebug() << "service registered";
int ret = app.exec();
qDebug() << "exiting deadservice";
return ret;
}
diff --git a/src/kdbusconnectionpool.cpp b/src/kdbusconnectionpool.cpp
index 26de9b3..72b2aad 100644
--- a/src/kdbusconnectionpool.cpp
+++ b/src/kdbusconnectionpool.cpp
@@ -1,75 +1,62 @@
/*
- * This file is part of the KDE Frameworks.
- * Copyright (C) 2010 Sebastian Trueg
- * Copyright (C) 2010 David Faure
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
+ This file is part of the KDE Frameworks.
+ SPDX-FileCopyrightText: 2010 Sebastian Trueg
+ SPDX-FileCopyrightText: 2010 David Faure
+
+ SPDX-License-Identifier: LGPL-2.0-or-later
+*/
#include "kdbusconnectionpool.h"
#include
#include
#include
namespace
{
QAtomicInt s_connectionCounter;
class KDBusConnectionPoolPrivate
{
public:
KDBusConnectionPoolPrivate()
: m_connection(QDBusConnection::connectToBus(
QDBusConnection::SessionBus,
QStringLiteral("KDBusConnectionPoolConnection%1").arg(newNumber())))
{
}
~KDBusConnectionPoolPrivate()
{
QDBusConnection::disconnectFromBus(m_connection.name());
}
QDBusConnection connection() const
{
return m_connection;
}
private:
static int newNumber()
{
return s_connectionCounter.fetchAndAddRelaxed(1);
}
QDBusConnection m_connection;
};
} // namespace
static QThreadStorage s_perThreadConnection;
QDBusConnection KDBusConnectionPool::threadConnection()
{
Q_ASSERT(QCoreApplication::instance() != nullptr);
if (QCoreApplication::instance()->thread() == QThread::currentThread()) {
return QDBusConnection::sessionBus();
}
if (!s_perThreadConnection.hasLocalData()) {
s_perThreadConnection.setLocalData(new KDBusConnectionPoolPrivate);
}
return s_perThreadConnection.localData()->connection();
}
diff --git a/src/kdbusconnectionpool.h b/src/kdbusconnectionpool.h
index d2e8e9c..be3ac73 100644
--- a/src/kdbusconnectionpool.h
+++ b/src/kdbusconnectionpool.h
@@ -1,62 +1,49 @@
/*
- * This file is part of the KDE Frameworks.
- * Copyright (C) 2010 Sebastian Trueg
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
+ This file is part of the KDE Frameworks.
+ SPDX-FileCopyrightText: 2010 Sebastian Trueg
+
+ SPDX-License-Identifier: LGPL-2.0-or-later
+*/
#ifndef KDBUSCONNECTIONPOOL_H
#define KDBUSCONNECTIONPOOL_H
#include
#include
/**
* @namespace KDBusConnectionPool
* Provides utility functions working around the problem
* of QDBusConnection not being thread-safe.
*/
namespace KDBusConnectionPool
{
/**
* The KDBusConnectionPool works around the problem
* of QDBusConnection not being thread-safe. As soon as that
* has been fixed (either directly in libdbus or with a work-
* around in Qt) this method can be dropped in favor of
* QDBusConnection::sessionBus().
*
* Note that this will create a thread-local QDBusConnection
* object, which means whichever thread this is called
* from must have both an event loop and be as long-lived as
* the object using it. If either condition is not met, the
* returned QDBusConnection will not send or receive D-Bus
* events (calls, return values, etc).
*
* Using this within libraries can create complexities for
* application developers working with threads as its use
* in the library may not be apparent to the application
* developer, and so functionality may appear to be broken
* simply due to the nature of the thread from which this
* ends up being called from. Library developers using
* this facility are strongly encouraged to note this
* caveat in the library's documentation.
*/
KDBUSADDONS_EXPORT QDBusConnection threadConnection();
}
#endif
diff --git a/src/kdbusinterprocesslock.cpp b/src/kdbusinterprocesslock.cpp
index 6e9391c..35ffd81 100644
--- a/src/kdbusinterprocesslock.cpp
+++ b/src/kdbusinterprocesslock.cpp
@@ -1,91 +1,78 @@
-/* This file is part of the KDE
-
- Copyright (C) 2009 Tobias Koenig (tokoe@kde.org)
- Copyright (C) 2011 Kevin Ottens (ervin@kde.org)
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) version 3, or any
- later version accepted by the membership of KDE e.V. (or its
- successor approved by the membership of KDE e.V.), which shall
- act as a proxy defined in Section 6 of version 3 of the license.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library. If not, see .
+/*
+ This file is part of the KDE
+
+ SPDX-FileCopyrightText: 2009 Tobias Koenig
+ SPDX-FileCopyrightText: 2011 Kevin Ottens
+
+ SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "kdbusinterprocesslock.h"
#include
#include
class KDBusInterProcessLockPrivate
{
public:
KDBusInterProcessLockPrivate(const QString &resource, KDBusInterProcessLock *parent)
: m_resource(resource), m_parent(parent)
{
m_serviceName = QStringLiteral("org.kde.private.lock-%1").arg(m_resource);
m_parent->connect(QDBusConnection::sessionBus().interface(), SIGNAL(serviceRegistered(QString)),
m_parent, SLOT(_k_serviceRegistered(QString)));
}
~KDBusInterProcessLockPrivate()
{
}
void _k_serviceRegistered(const QString &service)
{
if (service == m_serviceName) {
emit m_parent->lockGranted(m_parent);
}
}
QString m_resource;
QString m_serviceName;
KDBusInterProcessLock *m_parent;
};
KDBusInterProcessLock::KDBusInterProcessLock(const QString &resource)
: d(new KDBusInterProcessLockPrivate(resource, this))
{
}
KDBusInterProcessLock::~KDBusInterProcessLock()
{
delete d;
}
QString KDBusInterProcessLock::resource() const
{
return d->m_resource;
}
void KDBusInterProcessLock::lock()
{
QDBusConnection::sessionBus().interface()->registerService(d->m_serviceName,
QDBusConnectionInterface::QueueService,
QDBusConnectionInterface::DontAllowReplacement);
}
void KDBusInterProcessLock::unlock()
{
QDBusConnection::sessionBus().interface()->unregisterService(d->m_serviceName);
}
void KDBusInterProcessLock::waitForLockGranted()
{
QEventLoop loop;
connect(this, &KDBusInterProcessLock::lockGranted, &loop, &QEventLoop::quit);
loop.exec();
}
#include "moc_kdbusinterprocesslock.cpp"
diff --git a/src/kdbusinterprocesslock.h b/src/kdbusinterprocesslock.h
index 034a62c..7700dc6 100644
--- a/src/kdbusinterprocesslock.h
+++ b/src/kdbusinterprocesslock.h
@@ -1,124 +1,111 @@
-/* This file is part of libkdbus
-
- Copyright (C) 2009 Tobias Koenig (tokoe@kde.org)
- Copyright (C) 2011 Kevin Ottens (ervin@kde.org)
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) version 3, or any
- later version accepted by the membership of KDE e.V. (or its
- successor approved by the membership of KDE e.V.), which shall
- act as a proxy defined in Section 6 of version 3 of the license.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library. If not, see .
+/*
+ This file is part of libkdbus
+
+ SPDX-FileCopyrightText: 2009 Tobias Koenig
+ SPDX-FileCopyrightText: 2011 Kevin Ottens
+
+ SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef KDBUSINTERPROCESSLOCK_H
#define KDBUSINTERPROCESSLOCK_H
#include
#include
class KDBusInterProcessLockPrivate;
/**
* @class KDBusInterProcessLock kdbusinterprocesslock.h
*
* @short A class for serializing access to a resource that is shared between multiple processes.
*
* This class can be used to serialize access to a resource between
* multiple processes. Instead of using lock files, which could
* become stale easily, the registration of dummy D-Bus services is used
* to allow only one process at a time to access the resource.
*
* Example:
*
* @code
*
* KDBusInterProcessLock *lock = new KDBusInterProcessLock("myresource");
* connect(lock, SIGNAL(lockGranted(KDBusInterProcessLock *)),
* this, SLOT(doCriticalTask(KDBusInterProcessLock *)));
* lock->lock();
*
* ...
*
* ... ::doCriticalTask(KDBusInterProcessLock *lock)
* {
* // change common resource
*
* lock->unlock();
* }
*
* @endcode
*
* @author Tobias Koenig
*/
class KDBUSADDONS_EXPORT KDBusInterProcessLock : public QObject
{
Q_OBJECT
public:
/**
* Creates a new inter process lock object.
*
* @param resource The identifier of the resource that shall be locked.
* This identifier can be any string, however it must be unique for
* the resource and every client that wants to access the resource must
* know it.
*/
KDBusInterProcessLock(const QString &resource);
/**
* Destroys the inter process lock object.
*/
~KDBusInterProcessLock();
/**
* Returns the identifier of the resource the lock is set on.
*/
QString resource() const;
/**
* Requests the lock.
*
* The lock is granted as soon as the lockGranted() signal is emitted.
*/
void lock();
/**
* Releases the lock.
*
* @note This method should be called as soon as the critical area is left
* in your code path and the lock is no longer needed.
*/
void unlock();
/**
* Waits for the granting of a lock by starting an internal event loop.
*/
void waitForLockGranted();
Q_SIGNALS:
/**
* This signal is emitted when the requested lock has been granted.
*
* @param lock The lock that has been granted.
*/
void lockGranted(KDBusInterProcessLock *lock);
private:
friend class KDBusInterProcessLockPrivate;
KDBusInterProcessLockPrivate *const d;
Q_PRIVATE_SLOT(d, void _k_serviceRegistered(const QString &))
};
#endif
diff --git a/src/kdbusservice.cpp b/src/kdbusservice.cpp
index db629bb..06f51bd 100644
--- a/src/kdbusservice.cpp
+++ b/src/kdbusservice.cpp
@@ -1,350 +1,337 @@
-/* This file is part of libkdbusaddons
-
- Copyright (c) 2011 David Faure
- Copyright (c) 2011 Kevin Ottens
- Copyright (c) 2019 Harald Sitter
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) version 3, or any
- later version accepted by the membership of KDE e.V. (or its
- successor approved by the membership of KDE e.V.), which shall
- act as a proxy defined in Section 6 of version 3 of the license.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library. If not, see .
+/*
+ This file is part of libkdbusaddons
+
+ SPDX-FileCopyrightText: 2011 David Faure
+ SPDX-FileCopyrightText: 2011 Kevin Ottens
+ SPDX-FileCopyrightText: 2019 Harald Sitter
+
+ SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "kdbusservice.h"
#include
#include
#include
#include
#include
#include "KDBusServiceIface.h"
#include "FreeDesktopApplpicationIface.h"
#include "config-kdbusaddons.h"
#if HAVE_X11
#include
#endif
#include "kdbusservice_adaptor.h"
#include "kdbusserviceextensions_adaptor.h"
class KDBusServicePrivate
{
public:
KDBusServicePrivate()
: registered(false),
exitValue(0)
{}
QString generateServiceName()
{
const QCoreApplication *app = QCoreApplication::instance();
const QString domain = app->organizationDomain();
const QStringList parts = domain.split(QLatin1Char('.'), QString::SkipEmptyParts);
QString reversedDomain;
if (parts.isEmpty()) {
reversedDomain = QStringLiteral("local.");
} else {
for (const QString &part : parts) {
reversedDomain.prepend(QLatin1Char('.'));
reversedDomain.prepend(part);
}
}
return reversedDomain + app->applicationName();
}
bool registered;
QString serviceName;
QString errorMessage;
int exitValue;
};
// Wraps a serviceName registration.
class Registration : public QObject {
Q_OBJECT
public:
enum class Register {
RegisterWitoutQueue,
RegisterWithQueue
};
Registration(KDBusService *s_, KDBusServicePrivate *d_, KDBusService::StartupOptions options_)
: s(s_)
, d(d_)
, options(options_)
{
if (!QDBusConnection::sessionBus().isConnected() || !(bus = QDBusConnection::sessionBus().interface())) {
d->errorMessage = QLatin1String("Session bus not found\n"
"To circumvent this problem try the following command (with Linux and bash)\n"
"export $(dbus-launch)");
} else {
generateServiceName();
}
}
void run() {
if (bus) {
registerOnBus();
}
if (!d->registered && ((options & KDBusService::NoExitOnFailure) == 0)) {
qCritical() << d->errorMessage;
exit(1);
}
}
private:
void generateServiceName()
{
d->serviceName = d->generateServiceName();
objectPath = QLatin1Char('/') + d->serviceName;
objectPath.replace(QLatin1Char('.'), QLatin1Char('/'));
objectPath.replace(QLatin1Char('-'), QLatin1Char('_')); // see spec change at https://bugs.freedesktop.org/show_bug.cgi?id=95129
if (options & KDBusService::Multiple) {
const bool inSandbox = QFileInfo::exists(QStringLiteral("/flatpak-info"));
if (inSandbox) {
d->serviceName += QStringLiteral(".kdbus-") + QDBusConnection::sessionBus().baseService().replace(QRegularExpression(QStringLiteral("[\\.:]")), QStringLiteral("_"));
} else {
d->serviceName += QLatin1Char('-') + QString::number(QCoreApplication::applicationPid());
}
}
}
void registerOnBus()
{
auto bus = QDBusConnection::sessionBus();
bool objectRegistered = false;
objectRegistered = bus.registerObject(QStringLiteral("/MainApplication"),
QCoreApplication::instance(),
QDBusConnection::ExportAllSlots |
QDBusConnection::ExportScriptableProperties |
QDBusConnection::ExportAdaptors);
if (!objectRegistered) {
qWarning() << "Failed to register /MainApplication on DBus";
return;
}
objectRegistered = bus.registerObject(objectPath, s, QDBusConnection::ExportAdaptors);
if (!objectRegistered) {
qWarning() << "Failed to register" << objectPath << "on DBus";
return;
}
attemptRegistration();
if (d->registered) {
if (QCoreApplication *app = QCoreApplication::instance()) {
connect(app, &QCoreApplication::aboutToQuit,
s, &KDBusService::unregister);
}
}
}
void attemptRegistration()
{
Q_ASSERT(!d->registered);
auto queueOption = QDBusConnectionInterface::DontQueueService;
if (options & KDBusService::Unique) {
// When a process crashes and gets auto-restarted by KCrash we may
// be in this code path "too early". There is a bit of a delay
// between the restart and the previous process dropping off of the
// bus and thus releasing its registered names. As a result there
// is a good chance that if we wait a bit the name will shortly
// become registered.
queueOption = QDBusConnectionInterface::QueueService;
connect(bus, &QDBusConnectionInterface::serviceRegistered,
this, [this](const QString &service) {
if (service != d->serviceName) {
return;
}
d->registered = true;
registrationLoop.quit();
});
}
d->registered =
(bus->registerService(d->serviceName, queueOption) == QDBusConnectionInterface::ServiceRegistered);
if (d->registered) {
return;
}
if (options & KDBusService::Replace) {
auto message = QDBusMessage::createMethodCall(d->serviceName,
QStringLiteral("/MainApplication"),
QStringLiteral("org.qtproject.Qt.QCoreApplication"),
QStringLiteral("quit"));
QDBusConnection::sessionBus().asyncCall(message);
waitForRegistration();
} else if (options & KDBusService::Unique) {
// Already running so it's ok!
QVariantMap platform_data;
platform_data.insert(QStringLiteral("desktop-startup-id"), QString::fromUtf8(qgetenv("DESKTOP_STARTUP_ID")));
if (QCoreApplication::arguments().count() > 1) {
OrgKdeKDBusServiceInterface iface(d->serviceName, objectPath, QDBusConnection::sessionBus());
iface.setTimeout(5 * 60 * 1000); // Application can take time to answer
QDBusReply reply = iface.CommandLine(QCoreApplication::arguments(), QDir::currentPath(), platform_data);
if (reply.isValid()) {
exit(reply.value());
} else {
d->errorMessage = reply.error().message();
}
} else {
OrgFreedesktopApplicationInterface iface(d->serviceName, objectPath, QDBusConnection::sessionBus());
iface.setTimeout(5 * 60 * 1000); // Application can take time to answer
QDBusReply reply = iface.Activate(platform_data);
if (reply.isValid()) {
exit(0);
} else {
d->errorMessage = reply.error().message();
}
}
// service did not respond in a valid way....
// let's wait to see if our queued registration finishes perhaps.
waitForRegistration();
}
if (!d->registered) { // either multi service or failed to reclaim name
d->errorMessage = QLatin1String("Couldn't register name '")
+ d->serviceName
+ QLatin1String("' with DBUS - another process owns it already!");
}
}
void waitForRegistration()
{
QTimer quitTimer;
// Wait a bit longer when we know this instance was restarted. There's
// a very good chance we'll eventually get the name once the defunct
// process closes its sockets.
quitTimer.start(qEnvironmentVariableIsSet("KCRASH_AUTO_RESTARTED") ? 8000 : 2000);
connect(&quitTimer, &QTimer::timeout, ®istrationLoop, &QEventLoop::quit);
registrationLoop.exec();
}
QDBusConnectionInterface *bus = nullptr;
KDBusService *s = nullptr;
KDBusServicePrivate *d = nullptr;
KDBusService::StartupOptions options;
QEventLoop registrationLoop;
QString objectPath;
};
KDBusService::KDBusService(StartupOptions options, QObject *parent)
: QObject(parent), d(new KDBusServicePrivate)
{
new KDBusServiceAdaptor(this);
new KDBusServiceExtensionsAdaptor(this);
Registration registration(this, d, options);
registration.run();
}
KDBusService::~KDBusService()
{
delete d;
}
bool KDBusService::isRegistered() const
{
return d->registered;
}
QString KDBusService::errorMessage() const
{
return d->errorMessage;
}
void KDBusService::setExitValue(int value)
{
d->exitValue = value;
}
QString KDBusService::serviceName() const
{
return d->serviceName;
}
void KDBusService::unregister()
{
QDBusConnectionInterface *bus = nullptr;
if (!d->registered || !QDBusConnection::sessionBus().isConnected() || !(bus = QDBusConnection::sessionBus().interface())) {
return;
}
bus->unregisterService(d->serviceName);
}
void KDBusService::Activate(const QVariantMap &platform_data)
{
Q_UNUSED(platform_data);
#if HAVE_X11
if (QX11Info::isPlatformX11()) {
QX11Info::setAppTime(QX11Info::getTimestamp());
}
#endif
// TODO QX11Info::setNextStartupId(platform_data.value("desktop-startup-id"))
emit activateRequested(QStringList(), QString());
// TODO (via hook) KStartupInfo::appStarted(platform_data.value("desktop-startup-id"))
// ^^ same discussion as below
}
void KDBusService::Open(const QStringList &uris, const QVariantMap &platform_data)
{
Q_UNUSED(platform_data);
// TODO QX11Info::setNextStartupId(platform_data.value("desktop-startup-id"))
emit openRequested(QUrl::fromStringList(uris));
// TODO (via hook) KStartupInfo::appStarted(platform_data.value("desktop-startup-id"))
// ^^ not needed if the app actually opened a new window.
// Solution 1: do it all the time anyway (needs API in QX11Info)
// Solution 2: pass the id to the app and let it use KStartupInfo::appStarted if reusing a window
}
void KDBusService::ActivateAction(const QString &action_name, const QVariantList &maybeParameter, const QVariantMap &platform_data)
{
Q_UNUSED(platform_data);
// This is a workaround for D-Bus not supporting null variants.
const QVariant param = maybeParameter.count() == 1 ? maybeParameter.first() : QVariant();
emit activateActionRequested(action_name, param);
// TODO (via hook) KStartupInfo::appStarted(platform_data.value("desktop-startup-id"))
// if desktop-startup-id is set, the action is supposed to show a window (since it could be
// called when the app is not running)
}
int KDBusService::CommandLine(const QStringList &arguments, const QString &workingDirectory, const QVariantMap &platform_data)
{
Q_UNUSED(platform_data);
d->exitValue = 0;
// The TODOs here only make sense if this method can be called from the GUI.
// If it's for pure "usage in the terminal" then no startup notification got started.
// But maybe one day the workspace wants to call this for the Exec key of a .desktop file?
// TODO QX11Info::setNextStartupId(platform_data.value("desktop-startup-id"))
emit activateRequested(arguments, workingDirectory);
// TODO (via hook) KStartupInfo::appStarted(platform_data.value("desktop-startup-id"))
return d->exitValue;
}
#include "kdbusservice.moc"
diff --git a/src/kdbusservice.h b/src/kdbusservice.h
index 4458cea..4e460ad 100644
--- a/src/kdbusservice.h
+++ b/src/kdbusservice.h
@@ -1,282 +1,269 @@
-/* This file is part of libkdbusaddons
+/*
+ This file is part of libkdbusaddons
- Copyright (c) 2011 David Faure
- Copyright (c) 2011 Kevin Ottens
+ SPDX-FileCopyrightText: 2011 David Faure
+ SPDX-FileCopyrightText: 2011 Kevin Ottens
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) version 3, or any
- later version accepted by the membership of KDE e.V. (or its
- successor approved by the membership of KDE e.V.), which shall
- act as a proxy defined in Section 6 of version 3 of the license.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library. If not, see .
+ SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef KDBUSSERVICE_H
#define KDBUSSERVICE_H
#include
#include
#include
class KDBusServicePrivate;
/**
* @class KDBusService kdbusservice.h
*
* KDBusService takes care of registering the current process with D-Bus.
*
* This registers the application at a predictable location on D-Bus, registers
* the QCoreApplication (or subclass) object at /MainApplication, and
* assists in implementing the application side of D-Bus activation from
* the Desktop
* Entry Specification.
*
* An application can either work in Multiple mode or Unique mode.
*
* In Multiple mode, the application can be launched many times. The service
* name in the D-Bus registration will contain the PID to distinguish the
* various instances; for example: org.kde.konqueror-12345.
*
* In Unique mode, only one instance of this application can ever run.
* The first instance of the application registers with D-Bus without the PID,
* and any attempt to run the application again will cause the
* activateRequested() signal to be emitted in the already-running instance; the
* duplicate instance will then quit. The exit value can be set by the already
* running instance with setExitValue(), the default value is @c 0.
*
* Unique-mode applications should usually delay parsing command-line arguments
* until after creating a KDBusService object; that way they know they are the
* original instance of the application.
*
* Applications that set the D-Bus activation entries in their desktop files
* should use Unique mode and connect to the signals emitted by this class.
* Note that the D-Bus interface is exported for Multiple-mode applications as
* well, so it also makes sense for such applications to connect to the signals
* emitted by this class.
*
* @note In order to avoid a race, the application should export its objects to
* D-Bus before allowing the event loop to run (for example, by calling
* QCoreApplication::exec()). Otherwise, the application will appear on the bus
* before its objects are accessible via D-Bus, which could be a problem for
* other applications or scripts which start the application in order to talk
* D-Bus to it immediately.
*
* Example usage:
*
* @code
QApplication app(argc, argv);
app.setApplicationName("kuiserver");
app.setOrganizationDomain("kde.org");
// Create your D-Bus objects here
// ...
KDBusService service(KDBusService::Unique);
// If this point is reached, this is the only running instance
// i.e. org.kde.kuiserver has been registered
return app.exec();
* @endcode
*
* @since 5.0
*/
class KDBUSADDONS_EXPORT KDBusService : public QObject
{
Q_OBJECT
public:
/** Options to control the behaviour of KDBusService */
enum StartupOption {
/**
* Indicates that only one instance of this application should ever exist.
*
* Cannot be combined with @c Multiple.
*/
Unique = 1,
/**
* Indicates that multiple instances of the application may exist.
*
* Cannot be combined with @c Unique. This is the default.
*/
Multiple = 2,
/** Indicates that the application should not exit if it failed to
* register with D-Bus.
*
* If not set, KDBusService will quit the application if it failed to
* register the service with D-Bus or a @c Unique instance can not be
* activated. A @c Multiple instance will exit with error code @c 1.
* The exit value of a @c Unique instance can be set from the running
* instance with setExitValue(), the default value is @c 0.
*/
NoExitOnFailure = 4,
/**
* Indicates that if there's already a unique service running, to be quit and replaced
* with our own.
*
* If exported, it will try first quitting the service calling @c org.qtproject.Qt.QCoreApplication.quit,
* which is exported by KDBusService by default.
*
* @since 5.65
*/
Replace = 8
};
Q_ENUM(StartupOption)
Q_DECLARE_FLAGS(StartupOptions, StartupOption)
Q_FLAG(StartupOptions)
/**
* Tries to register the current process to D-Bus at an address based on the
* application name and organization domain.
*
* The D-Bus service name is the reversed organization domain, followed by
* the application name. If @p options includes the @c Multiple flag, the
* application PID will be appended. For example,
* @code
* app.setApplicationName("kuiserver");
* app.setOrganizationDomain("kde.org");
* @endcode
* will make KDBusService register as @c org.kde.kuiserver in @c Unique
* mode, and @c org.kde.kuiserver-1234 (if the process has PID @c 1234) in
* @c Multiple mode.
*/
explicit KDBusService(StartupOptions options = Multiple, QObject *parent = nullptr);
/**
* Destroys this object (but does not unregister the application).
*
* Deleting this object before unregister() is called (either manually or
* because QCoreApplication::aboutToQuit() was emitted) could confuse
* clients, who will see the service on the bus but will be unable to use
* the activation methods.
*/
~KDBusService();
/**
* Returns true if the D-Bus registration succeeded.
*
* Note that this is only useful when specifying the option NoExitOnFailure.
* Otherwise, the simple fact that this process is still running indicates
* that the registration succeeded.
*/
bool isRegistered() const;
/**
* Returns the name of the D-Bus service registered by this class.
* Mostly useful when using the option Multiple.
* @since 5.33
*/
QString serviceName() const;
/**
* Returns the error message from the D-Bus registration if it failed.
*
* Note that this is only useful when specifying the option NoExitOnFailure.
* Otherwise the process has quit by the time you can get a chance to call this.
*/
QString errorMessage() const;
/**
* Sets the exit value to be used for a duplicate instance.
*
* If this is a @c Unique application, a slot connected to
* activateRequested() can use this to specify a non-zero exit value for the
* duplicate instance. This would typically be done if invalid command-line
* arguments are passed.
*
* Note that this will only work if the signal-slot connection type is
* Qt::DirectConnection.
*
* @param value The exit value for the duplicate instance.
*/
void setExitValue(int value);
Q_SIGNALS:
/**
* Signals that the application is to be activated.
*
* If this is a @c Unique application, when KDBusService is constructed in
* subsequent instances of the application (ie: when the executable is run
* when an instance is already running), it will cause this signal to be
* emitted in the already-running instance (with the arguments passed to the
* duplicate instance), and the duplicate instance will then exit.
*
* If this application's desktop file indicates that it supports D-Bus
* activation (DBusActivatable=true), a command launcher may also call the Activate()
* D-Bus method to trigger this signal. In this case, @p args will be empty.
*
* In single-window applications, the connected signal should typically
* raise the window.
*
* @param arguments The arguments the executable was called with, starting with the executable file name.
* See QCoreApplication::arguments().
* This can also be empty.
*
* A typical implementation of the slot would be
* @code
* if (!arguments.isEmpty()) {
* commandLineParser->parse(arguments); // same QCommandLineParser instance as the one used in main()
* handleCmdLine(workingDirectory); // shared method with main(), which uses commandLineParser to handle options and positional arguments
* }
* // and for GUI applications, also terminate startup notification and activate the mainwindow:
* KStartupInfo::setNewStartupId(mainWindow, KStartupInfo::startupId());
* KWindowSystem::forceActiveWindow(mainWindow->winId());
* @endcode
*
* If you're using the builtin handling of @c --help and @c --version in QCommandLineParser,
* you should call parser.process(arguments) before creating the KDBusService instance,
* since parse() doesn't handle those (and exiting the already-running instance would be wrong anyway).
*
* @see setExitValue()
*/
void activateRequested(const QStringList &arguments, const QString &workingDirectory);
/**
* Signals that one or more files should be opened in the application.
*
* @param uris The URLs of the files to open.
*/
void openRequested(const QList &uris);
/**
* Signals that an application action should be triggered.
*
* See the desktop entry specification for more information.
*/
void activateActionRequested(const QString &actionName, const QVariant ¶meter);
public Q_SLOTS:
/**
* Unregister from D-Bus.
*
* This is called automatically when the application is about to quit, to
* make sure it doesn't keep receiving calls to its D-Bus interface while it
* is doing final cleanups.
*/
void unregister();
private:
// fdo.Application spec
void Activate(const QVariantMap &platform_data);
void Open(const QStringList &uris, const QVariantMap &platform_data);
void ActivateAction(const QString &action_name, const QVariantList &maybeParameter, const QVariantMap &platform_data);
friend class KDBusServiceAdaptor;
// org.kde.KDBusService
int CommandLine(const QStringList &arguments, const QString &workingDirectory, const QVariantMap &platform_data);
friend class KDBusServiceExtensionsAdaptor;
private:
KDBusServicePrivate *const d;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(KDBusService::StartupOptions)
#endif /* KDBUSSERVICE_H */
diff --git a/src/kdedmodule.cpp b/src/kdedmodule.cpp
index 0ea790b..d2cada8 100644
--- a/src/kdedmodule.cpp
+++ b/src/kdedmodule.cpp
@@ -1,116 +1,102 @@
/*
- This file is part of the KDE libraries
+ This file is part of the KDE libraries
- Copyright (c) 2001 Waldo Bastian
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
+ SPDX-FileCopyrightText: 2001 Waldo Bastian
+ SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "kdedmodule.h"
#include "kdbusaddons_debug.h"
#include
#include
#include
class KDEDModulePrivate
{
public:
QString moduleName;
};
KDEDModule::KDEDModule(QObject *parent)
: QObject(parent), d(new KDEDModulePrivate)
{
}
KDEDModule::~KDEDModule()
{
emit moduleDeleted(this);
delete d;
}
void KDEDModule::setModuleName(const QString &name)
{
d->moduleName = name;
QDBusObjectPath realPath(QLatin1String("/modules/") + d->moduleName);
if (realPath.path().isEmpty()) {
qCWarning(KDBUSADDONS_LOG) << "The kded module name" << name << "is invalid!";
return;
}
QDBusConnection::RegisterOptions regOptions;
if (this->metaObject()->indexOfClassInfo("D-Bus Interface") != -1) {
// 1. There are kded modules that don't have a D-Bus interface.
// 2. qt 4.4.3 crashes when trying to emit signals on class without
// Q_CLASSINFO("D-Bus Interface", "") but
// ExportSignal set.
// We try to solve that for now with just registering Properties and
// Adaptors. But we should investigate where the sense is in registering
// the module at all. Just for autoload? Is there a better solution?
regOptions = QDBusConnection::ExportScriptableContents | QDBusConnection::ExportAdaptors;
} else {
// Full functional module. Register everything.
regOptions = QDBusConnection::ExportScriptableSlots
| QDBusConnection::ExportScriptableProperties
| QDBusConnection::ExportAdaptors;
qCDebug(KDBUSADDONS_LOG) << "Registration of kded module" << d->moduleName << "without D-Bus interface.";
}
if (!QDBusConnection::sessionBus().registerObject(realPath.path(), this, regOptions)) {
// Happens for khotkeys but the module works. Need some time to investigate.
qCDebug(KDBUSADDONS_LOG) << "registerObject() returned false for" << d->moduleName;
} else {
//qCDebug(KDBUSADDONS_LOG) << "registerObject() successful for" << d->moduleName;
// Fix deadlock with Qt 5.6: this has to be delayed until the dbus thread is unlocked
QMetaObject::invokeMethod(this, "moduleRegistered", Qt::QueuedConnection, Q_ARG(QDBusObjectPath, realPath));
}
}
QString KDEDModule::moduleName() const
{
return d->moduleName;
}
static const char s_modules_path[] = "/modules/";
QString KDEDModule::moduleForMessage(const QDBusMessage &message)
{
if (message.type() != QDBusMessage::MethodCallMessage) {
return QString();
}
QString obj = message.path();
if (!obj.startsWith(QLatin1String(s_modules_path))) {
return QString();
}
// Remove the part
obj = obj.mid(strlen(s_modules_path));
// Remove the part after the modules name
const int index = obj.indexOf(QLatin1Char('/'));
if (index != -1) {
obj = obj.left(index);
}
return obj;
}
diff --git a/src/kdedmodule.h b/src/kdedmodule.h
index a033415..9cbcc69 100644
--- a/src/kdedmodule.h
+++ b/src/kdedmodule.h
@@ -1,106 +1,93 @@
/*
- This file is part of the KDE libraries
+ This file is part of the KDE libraries
- Copyright (c) 2001 Waldo Bastian
+ SPDX-FileCopyrightText: 2001 Waldo Bastian
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
+ SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef __KDEDMODULE_H__
#define __KDEDMODULE_H__
#include
#include
class KDEDModulePrivate;
class Kded;
class QDBusObjectPath;
class QDBusMessage;
/**
* \class KDEDModule kdedmodule.h
*
* The base class for KDED modules.
*
* KDED modules are realized as shared
* libraries that are loaded on-demand into kded at runtime.
*
* See kdelibs/kded/HOWTO for documentation about writing kded modules.
*
* @author Waldo Bastian
*/
class KDBUSADDONS_EXPORT KDEDModule: public QObject
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.KDEDModule")
friend class Kded;
public:
/**
* Constructor
*/
explicit KDEDModule(QObject *parent = nullptr);
virtual ~KDEDModule();
/**
* Sets the name of the module, and uses it to register the module to D-Bus.
*
* For modules loaded as plugins by a daemon, this is called automatically
* by the daemon after loading the module. Module authors should NOT call this.
*/
void setModuleName(const QString &name);
QString moduleName() const;
/**
* Returns the module being called by this D-Bus message.
* Useful for autoloading modules in kded and similar daemons.
* @since 5.7
*/
static QString moduleForMessage(const QDBusMessage &message);
Q_SIGNALS:
/**
* Emitted when the module is being deleted.
*/
void moduleDeleted(KDEDModule *);
/**
* Emitted when a mainwindow registers itself.
*/
void windowRegistered(qlonglong windowId);
/**
* Emitted when a mainwindow unregisters itself.
*/
void windowUnregistered(qlonglong windowId);
/**
* Emitted after the module is registered successfully with D-Bus
*
* @since 4.2
*/
void moduleRegistered(const QDBusObjectPath &path);
private:
KDEDModulePrivate *const d;
};
#endif
diff --git a/src/kdeinitinterface.cpp b/src/kdeinitinterface.cpp
index cd56f15..0c593dd 100644
--- a/src/kdeinitinterface.cpp
+++ b/src/kdeinitinterface.cpp
@@ -1,78 +1,65 @@
-/* This file is part of libkdbusaddons
+/*
+ This file is part of libkdbusaddons
- Copyright (c) 2013 David Faure
+ SPDX-FileCopyrightText: 2013 David Faure
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) version 3, or any
- later version accepted by the membership of KDE e.V. (or its
- successor approved by the membership of KDE e.V.), which shall
- act as a proxy defined in Section 6 of version 3 of the license.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library. If not, see .
+ SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "kdeinitinterface.h"
#include "kdbusconnectionpool.h"
#include "kdbusaddons_debug.h"
#include
#include
#include
#include
#include
#include
#include
void KDEInitInterface::ensureKdeinitRunning()
{
QDBusConnectionInterface *dbusDaemon = KDBusConnectionPool::threadConnection().interface();
if (dbusDaemon->isServiceRegistered(QStringLiteral("org.kde.klauncher5"))) {
return;
}
qCDebug(KDBUSADDONS_LOG) << "klauncher not running... launching kdeinit";
QLockFile lock(QDir::tempPath() + QLatin1Char('/') + QLatin1String("startkdeinitlock"));
// If we can't get the lock, then someone else is already in the process of starting kdeinit.
if (!lock.tryLock()) {
// Wait for that to happen, by locking again 30 seconds max.
if (!lock.tryLock(30000))
{
qCWarning(KDBUSADDONS_LOG) << "'kdeinit5' is taking more than 30 seconds to start.";
return;
}
// Check that the DBus name is up, i.e. the other process did manage to do it successfully.
if (dbusDaemon->isServiceRegistered(QStringLiteral("org.kde.klauncher5"))) {
return;
}
}
// Try to launch kdeinit.
QString srv = QStandardPaths::findExecutable(QStringLiteral("kdeinit5"));
// If not found in system paths, search other paths
if (srv.isEmpty()) {
const QStringList searchPaths = QStringList()
<< QCoreApplication::applicationDirPath() // then look where our application binary is located
<< QLibraryInfo::location(QLibraryInfo::BinariesPath); // look where exec path is (can be set in qt.conf)
srv = QStandardPaths::findExecutable(QStringLiteral("kdeinit5"), searchPaths);
if (srv.isEmpty()) {
qCWarning(KDBUSADDONS_LOG) << "Can not find 'kdeinit5' executable at " << qgetenv("PATH") << searchPaths.join(QStringLiteral(", "));
return;
}
}
QStringList args;
#ifndef Q_OS_WIN
args += QStringLiteral("--suicide");
#endif
// NOTE: kdeinit5 is supposed to finish quickly, certainly in less than 30 seconds.
QProcess::execute(srv, args);
}
diff --git a/src/kdeinitinterface.h b/src/kdeinitinterface.h
index 61ecb6f..da5f133 100644
--- a/src/kdeinitinterface.h
+++ b/src/kdeinitinterface.h
@@ -1,43 +1,30 @@
-/* This file is part of libkdbusaddons
+/*
+ This file is part of libkdbusaddons
- Copyright (c) 2013 David Faure
+ SPDX-FileCopyrightText: 2013 David Faure
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) version 3, or any
- later version accepted by the membership of KDE e.V. (or its
- successor approved by the membership of KDE e.V.), which shall
- act as a proxy defined in Section 6 of version 3 of the license.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library. If not, see .
+ SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef KDEINIT_IFACE_H
#define KDEINIT_IFACE_H
#include
/**
* The KDEInitInterface namespace contains:
*
*
* - A function to ensure kdeinit and klauncher are running.
* This is necessary before making D-Bus calls to org.kde.klauncher5.
*
*
* @since 5.0
*/
namespace KDEInitInterface
{
KDBUSADDONS_EXPORT void ensureKdeinitRunning();
}
#endif
diff --git a/src/tools/kquitapp/kquitapp.cpp b/src/tools/kquitapp/kquitapp.cpp
index 718ebbb..62c54af 100644
--- a/src/tools/kquitapp/kquitapp.cpp
+++ b/src/tools/kquitapp/kquitapp.cpp
@@ -1,68 +1,56 @@
/*
- * Copyright (C) 2006 Aaron Seigo
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License version 2 as
- * published by the Free Software Foundation
- *
- * 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 Library General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
+ SPDX-FileCopyrightText: 2006 Aaron Seigo
+
+ SPDX-License-Identifier: LGPL-2.0-only
+*/
#include
#include
#include
#include
int main(int argc, char* argv[])
{
QCoreApplication app(argc, argv);
app.setApplicationName(QStringLiteral("kquitapp"));
app.setApplicationVersion(QStringLiteral("2.0"));
QCommandLineParser parser;
parser.setApplicationDescription(QCoreApplication::translate("main", "Quit a D-Bus enabled application easily"));
parser.addOption(QCommandLineOption(QStringLiteral("service"), QCoreApplication::translate("main", "Full service name, overrides application name provided"), QStringLiteral("service")));
parser.addOption(QCommandLineOption(QStringLiteral("path"), QCoreApplication::translate("main", "Path in the D-Bus interface to use"), QStringLiteral("path"), QStringLiteral("/MainApplication")));
parser.addPositionalArgument(QStringLiteral("[application]"), QCoreApplication::translate("main", "The name of the application to quit"));
parser.addHelpOption();
parser.addVersionOption();
parser.process(app);
QString service;
if (parser.isSet(QStringLiteral("service")))
{
service = parser.value(QStringLiteral("service"));
}
else if(!parser.positionalArguments().isEmpty())
{
service = QStringLiteral("org.kde.%1").arg(parser.positionalArguments().at(0));
}
else
{
parser.showHelp(1);
}
QString path(parser.value(QStringLiteral("path")));
QDBusInterface interface(service, path);
if (!interface.isValid()) {
qWarning() << QCoreApplication::translate("main", "Application %1 could not be found using service %2 and path %3.").arg(parser.positionalArguments().at(0), service, path);
return 1;
}
interface.call(QStringLiteral("quit"));
QDBusError error = interface.lastError();
if (error.type() != QDBusError::NoError) {
qWarning() << QCoreApplication::translate("main", "Quitting application %1 failed. Error reported was:\n\n %2 : %3").arg(parser.positionalArguments().join(QStringLiteral(" ")), error.name(), error.message());
return 1;
}
return 0;
}