From 4b63f8dca24b392374eaf57290b24e7459dab021 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Thu, 15 Dec 2016 08:29:14 +0100 Subject: [PATCH] Remove unused bubblewrap source --- README.md | 5 +- external/CMakeLists.txt | 1 - external/bubblewrap/.dir-locals.el | 1 - external/bubblewrap/.editorconfig | 6 - external/bubblewrap/.travis.yml | 25 - external/bubblewrap/CMakeLists.txt | 14 - external/bubblewrap/COPYING | 481 ----- external/bubblewrap/LICENSE | 1 - external/bubblewrap/Makefile-bwrap.am | 13 - external/bubblewrap/Makefile-docs.am | 17 - external/bubblewrap/Makefile.am | 31 - external/bubblewrap/README.md | 191 -- external/bubblewrap/autogen.sh | 19 - external/bubblewrap/bind-mount.c | 285 --- external/bubblewrap/bind-mount.h | 30 - external/bubblewrap/bubblewrap.c | 1593 ----------------- external/bubblewrap/bubblewrap.jpg | Bin 40239 -> 0 bytes external/bubblewrap/bwrap.xml | 266 --- external/bubblewrap/completions/bash/bwrap | 52 - external/bubblewrap/config.h | 5 - external/bubblewrap/configure.ac | 103 -- external/bubblewrap/demos/bubblewrap-shell.sh | 21 - external/bubblewrap/demos/xdg-app-run.sh | 65 - external/bubblewrap/demos/xdg-app.bpf | Bin 744 -> 0 bytes external/bubblewrap/git.mk | 348 ---- external/bubblewrap/network.c | 200 --- external/bubblewrap/network.h | 21 - external/bubblewrap/packaging/bubblewrap.spec | 49 - external/bubblewrap/tests/test-basic.sh | 35 - external/bubblewrap/uncrustify.cfg | 136 -- external/bubblewrap/uncrustify.sh | 2 - external/bubblewrap/utils.c | 676 ------- external/bubblewrap/utils.h | 164 -- external/jni/JNIHelp.h | 206 --- external/jni/README.md | 1 - external/jni/jni.h | 1141 ------------ 36 files changed, 2 insertions(+), 6202 deletions(-) delete mode 100644 external/bubblewrap/.dir-locals.el delete mode 100644 external/bubblewrap/.editorconfig delete mode 100644 external/bubblewrap/.travis.yml delete mode 100644 external/bubblewrap/CMakeLists.txt delete mode 100644 external/bubblewrap/COPYING delete mode 120000 external/bubblewrap/LICENSE delete mode 100644 external/bubblewrap/Makefile-bwrap.am delete mode 100644 external/bubblewrap/Makefile-docs.am delete mode 100644 external/bubblewrap/Makefile.am delete mode 100644 external/bubblewrap/README.md delete mode 100755 external/bubblewrap/autogen.sh delete mode 100644 external/bubblewrap/bind-mount.c delete mode 100644 external/bubblewrap/bind-mount.h delete mode 100644 external/bubblewrap/bubblewrap.c delete mode 100644 external/bubblewrap/bubblewrap.jpg delete mode 100644 external/bubblewrap/bwrap.xml delete mode 100644 external/bubblewrap/completions/bash/bwrap delete mode 100644 external/bubblewrap/config.h delete mode 100644 external/bubblewrap/configure.ac delete mode 100755 external/bubblewrap/demos/bubblewrap-shell.sh delete mode 100755 external/bubblewrap/demos/xdg-app-run.sh delete mode 100644 external/bubblewrap/demos/xdg-app.bpf delete mode 100644 external/bubblewrap/git.mk delete mode 100644 external/bubblewrap/network.c delete mode 100644 external/bubblewrap/network.h delete mode 100644 external/bubblewrap/packaging/bubblewrap.spec delete mode 100755 external/bubblewrap/tests/test-basic.sh delete mode 100644 external/bubblewrap/uncrustify.cfg delete mode 100755 external/bubblewrap/uncrustify.sh delete mode 100644 external/bubblewrap/utils.c delete mode 100644 external/bubblewrap/utils.h delete mode 100644 external/jni/JNIHelp.h delete mode 100644 external/jni/README.md delete mode 100644 external/jni/jni.h diff --git a/README.md b/README.md index 4c585a2..654ae92 100644 --- a/README.md +++ b/README.md @@ -76,9 +76,8 @@ will install the necessary bits into your system. ## Copyright and Licensing -Anbox reuses code from other projects like the Android Qemu emulator -or bubblewrap (https://github.com/projectatomic/bubblewrap). These -projects are available in the external/ subdirectory with the +Anbox reuses code from other projects like the Android Qemu emulator. +These projects are available in the external/ subdirectory with the licensing terms included. The anbox source itself (in src/) is licensed under the terms of diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 24ebcab..179e7f3 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -1,4 +1,3 @@ -add_subdirectory(bubblewrap) add_subdirectory(process-cpp-minimal) add_subdirectory(android-emugl) add_subdirectory(xdg) diff --git a/external/bubblewrap/.dir-locals.el b/external/bubblewrap/.dir-locals.el deleted file mode 100644 index 3514040..0000000 --- a/external/bubblewrap/.dir-locals.el +++ /dev/null @@ -1 +0,0 @@ -((c-mode . ((indent-tabs-mode . nil) (c-file-style . "gnu")))) diff --git a/external/bubblewrap/.editorconfig b/external/bubblewrap/.editorconfig deleted file mode 100644 index d062d2c..0000000 --- a/external/bubblewrap/.editorconfig +++ /dev/null @@ -1,6 +0,0 @@ -[*.[ch]] -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -indent_brace_style = gnu - diff --git a/external/bubblewrap/.travis.yml b/external/bubblewrap/.travis.yml deleted file mode 100644 index dbba64b..0000000 --- a/external/bubblewrap/.travis.yml +++ /dev/null @@ -1,25 +0,0 @@ -language: c -dist: trusty -addons: - apt: - packages: - - automake - - autotools-dev - - libcap-dev -script: - - env NOCONFIGURE=1 ./autogen.sh - - mkdir build - - cd build && ../configure - - make -j 2 - - make check - -notifications: - # This is Colin's instance of Homu, in the future - # we'll move this to a production cluster. - webhooks: http://escher.verbum.org:54856/travis - email: false - -branches: - only: - - auto - diff --git a/external/bubblewrap/CMakeLists.txt b/external/bubblewrap/CMakeLists.txt deleted file mode 100644 index e7677a2..0000000 --- a/external/bubblewrap/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -# Don't treat any warnings as error as we take the source directly from -# upstream and just compile it. -set(CMAKE_C_FLAGS "-Wall") - -set(SOURCES - bind-mount.c - bubblewrap.c - network.c - utils.c) - -set(HEADERS - config.h) - -add_library(bwrap ${SOURCES} ${HEADERS}) diff --git a/external/bubblewrap/COPYING b/external/bubblewrap/COPYING deleted file mode 100644 index 5bc8fb2..0000000 --- a/external/bubblewrap/COPYING +++ /dev/null @@ -1,481 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 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 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. - - GNU LIBRARY GENERAL PUBLIC LICENSE - 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. - - - Copyright (C) - - 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 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. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/external/bubblewrap/LICENSE b/external/bubblewrap/LICENSE deleted file mode 120000 index d24842f..0000000 --- a/external/bubblewrap/LICENSE +++ /dev/null @@ -1 +0,0 @@ -COPYING \ No newline at end of file diff --git a/external/bubblewrap/Makefile-bwrap.am b/external/bubblewrap/Makefile-bwrap.am deleted file mode 100644 index f4c2a35..0000000 --- a/external/bubblewrap/Makefile-bwrap.am +++ /dev/null @@ -1,13 +0,0 @@ - -bwrap_SOURCES = \ - $(bwrap_srcpath)/bubblewrap.c \ - $(bwrap_srcpath)/bind-mount.h \ - $(bwrap_srcpath)/bind-mount.c \ - $(bwrap_srcpath)/network.h \ - $(bwrap_srcpath)/network.c \ - $(bwrap_srcpath)/utils.h \ - $(bwrap_srcpath)/utils.c \ - $(NULL) - -bwrap_CFLAGS = $(AM_CFLAGS) -bwrap_LDFLAGS = $(SELINUX_LIBS) diff --git a/external/bubblewrap/Makefile-docs.am b/external/bubblewrap/Makefile-docs.am deleted file mode 100644 index c70fa62..0000000 --- a/external/bubblewrap/Makefile-docs.am +++ /dev/null @@ -1,17 +0,0 @@ -XSLTPROC = xsltproc - -XSLTPROC_FLAGS = \ - --nonet \ - --stringparam man.output.quietly 1 \ - --stringparam funcsynopsis.style ansi \ - --stringparam man.th.extra1.suppress 1 \ - --stringparam man.authors.section.enabled 0 \ - --stringparam man.copyright.section.enabled 0 - -.xml.1: - $(XSLTPROC) $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< - -if ENABLE_MAN -man_MANS = bwrap.1 -CLEANFILES += $(man_MANS) -endif diff --git a/external/bubblewrap/Makefile.am b/external/bubblewrap/Makefile.am deleted file mode 100644 index 6e47b5f..0000000 --- a/external/bubblewrap/Makefile.am +++ /dev/null @@ -1,31 +0,0 @@ -AM_CFLAGS = $(WARN_CFLAGS) -CLEANFILES = - -GITIGNOREFILES = build-aux/ gtk-doc.make config.h.in aclocal.m4 - -bin_PROGRAMS = bwrap - -bwrap_srcpath := $(srcdir) -include Makefile-bwrap.am - -install-exec-hook: -if PRIV_MODE_SETUID - $(SUDO_BIN) chown root $(DESTDIR)$(bindir)/bwrap - $(SUDO_BIN) chmod u+s $(DESTDIR)$(bindir)/bwrap -else -if PRIV_MODE_FILECAPS - $(SUDO_BIN) setcap cap_sys_admin,cap_net_admin,cap_sys_chroot,cap_setuid,cap_setgid+ep $(DESTDIR)$(bindir)/bwrap -endif -endif - -include Makefile-docs.am - -TESTS = tests/test-basic.sh -TESTS_ENVIRONMENT = PATH=$$(cd $(top_builddir) && pwd):$${PATH} - -if ENABLE_BASH_COMPLETION -bashcompletiondir = $(BASH_COMPLETION_DIR) -dist_bashcompletion_DATA = completions/bash/bwrap -endif - --include $(top_srcdir)/git.mk diff --git a/external/bubblewrap/README.md b/external/bubblewrap/README.md deleted file mode 100644 index 2dd65bc..0000000 --- a/external/bubblewrap/README.md +++ /dev/null @@ -1,191 +0,0 @@ -Bubblewrap -========== - -Many container runtime tools like `systemd-nspawn`, `docker`, -etc. focus on providing infrastructure for system administrators and -orchestration tools (e.g. Kubernetes) to run containers. - -These tools are not suitable to give to unprivileged users, because it -is trivial to turn such access into to a fully privileged root shell -on the host. - -User namespaces ---------------- - -There is an effort in the Linux kernel called -[user namespaces](https://www.google.com/search?q=user+namespaces+site%3Ahttps%3A%2F%2Flwn.net) -which attempts to allow unprivileged users to use container features. -While significant progress has been made, there are -[still concerns](https://lwn.net/Articles/673597/) about it, and -it is not available to unprivileged users in several production distributions -such as CentOS/Red Hat Enterprise Linux 7, Debian Jessie, etc. - -See for example -[CVE-2016-3135](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3135) -which is a local root vulnerability introduced by userns. -[This March 2016 post](https://lkml.org/lkml/2016/3/9/555) has some -more discussion. - -Bubblewrap could be viewed as setuid implementation of a *subset* of -user namespaces. Emphasis on subset - specifically relevant to the -above CVE, bubblewrap does not allow control over iptables. - -The original bubblewrap code existed before user namespaces - it inherits code from -[xdg-app helper](https://cgit.freedesktop.org/xdg-app/xdg-app/tree/common/xdg-app-helper.c) -which in turn distantly derives from -[linux-user-chroot](https://git.gnome.org/browse/linux-user-chroot). - -Security --------- - -The maintainers of this tool believe that it does not, even when used -in combination with typical software installed on that distribution, -allow privilege escalation. It may increase the ability of a logged -in user to perform denial of service attacks, however. - -In particular, bubblewrap uses `PR_SET_NO_NEW_PRIVS` to turn off -setuid binaries, which is the [traditional way](https://en.wikipedia.org/wiki/Chroot#Limitations) to get out of things -like chroots. - -Users ------ - -This program can be shared by all container tools which perform -non-root operation, such as: - - - [xdg-app](https://cgit.freedesktop.org/xdg-app/xdg-app) - - [rpm-ostree unprivileged](https://github.com/projectatomic/rpm-ostree/pull/209) - -We would also like to see this be available in Kubernetes/OpenShift -clusters. Having the ability for unprivileged users to use container -features would make it significantly easier to do interactive -debugging scenarios and the like. - -Usage ------ - -bubblewrap works by creating a new, completely empty, mount -namespace where the root is on a tmpfs that is invisible from the -host, and will be automatically cleaned up when the last process -exists. You can then use commandline options to construct the root -filesystem and process environment and command to run in the -namespace. - -A simple example is -``` -bwrap --ro-bind / / bash -``` -This will create a read-only bind mount of the host root at the -sandbox root, and then start a bash. - -Another simple example would be a read-write chroot operation: -``` -bwrap --bind /some/chroot/dir / bash -``` - -A more complex example is to run a with a custom (readonly) /usr, -but your own (tmpfs) data, running in a PID and network namespace: - -``` -bwrap --ro-bind /usr /usr \ - --tmpfs /tmp \ - --proc /proc \ - --dev /dev \ - --ro-bind /etc/resolv.conf /etc/resolv.conf \ - --symlink usr/lib /lib \ - --symlink usr/lib64 /lib64 \ - --symlink usr/bin /bin \ - --symlink usr/sbin /sbin \ - --chdir / \ - --unshare-pid \ - --unshare-net \ - --dir /run/user/$(id -u) \ - --setenv XDG_RUNTIME_DIR "/run/user/`id -u`" \ - /bin/sh -``` - -Sandboxing ----------- - -The goal of bubblewrap is to run an application in a sandbox, where it -has restricted access to parts of the operating system or user data -such as the home directory. - -bubblewrap always creates a new mount namespace, and the user can specify -exactly what parts of the filesystem should be visible in the sandbox. -Any such directories you specify mounted `nodev` by default, and can be made readonly. - -Additionally you can use these kernel features: - -User namespaces ([CLONE_NEWUSER](http://linux.die.net/man/2/clone)): This hides all but the current uid and gid from the -sandbox. You can also change what the value of uid/gid should be in the sandbox. - -IPC namespaces ([CLONE_NEWIPC](http://linux.die.net/man/2/clone)): The sandbox will get its own copy of all the -different forms of IPCs, like SysV shared memory and semaphores. - -PID namespaces ([CLONE_NEWPID](http://linux.die.net/man/2/clone)): The sandbox will not see any processes outside the sandbox. Additionally, bubblewrap will run a trivial pid1 inside your container to handle the requirements of reaping children in the sandbox. .This avoids what is known now as the [Docker pid 1 problem](https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/). - - -Network namespaces ([CLONE_NEWNET](http://linux.die.net/man/2/clone)): The sandbox will not see the network. Instead it will have its own network namespace with only a loopback device. - -UTS namespace ([CLONE_NEWUTS](http://linux.die.net/man/2/clone)): The sandbox will have its own hostname. - -Seccomp filters: You can pass in seccomp filters that limit which syscalls can be done in the sandbox. For more information, see [Seccomp](https://en.wikipedia.org/wiki/Seccomp). - -Related project comparison: Firejail ------------------------------------- - -[Firejail](https://github.com/netblue30/firejail/tree/master/src/firejail) is -similar to xdg-app before bubblewrap was split out in that it combines -a setuid tool with a lot of desktop-specific sandboxing features. For -example, Firejail knows about Pulseaudio, whereas bubblewrap does not. - -The bubblewrap authors believe it's much easier to audit a small -setuid program, and keep features such as Pulseaudio filtering as an -unprivileged process, as now occurs in xdg-app. - -Also, @cgwalters thinks trying to -[whitelist file paths](https://github.com/netblue30/firejail/blob/37a5a3545ef6d8d03dad8bbd888f53e13274c9e5/src/firejail/fs_whitelist.c#L176) -is a bad idea given the myriad ways users have to manipulate paths, -and the myriad ways in which system administrators may configure a -system. The bubblewrap approach is to only retain a few specific -Linux capabilities such as `CAP_SYS_ADMIN`, but to always access the -filesystem as the invoking uid. This entirely closes -[TOCTOCU attacks](https://cwe.mitre.org/data/definitions/367.html) and -such. - -Related project comparison: Sandstorm.io ----------------------------------------- - -[Sandstorm.io](https://sandstorm.io/) also has a setuid helper -process. @cgwalters believes their setuid code is fairly good, but it -could still make sense to unify on bubblewrap as a setuid core. That -hasn't been ruled out, but neither is it being actively pursued today. - -Related project comparison: runc/binctr ----------------------------------------- - -[runc](https://github.com/opencontainers/runc) is similar to -[systemd nspawn](https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html) -in that it is tooling intended to be invoked by root. There is an -effort to have runc optionally use -[user namespaces](https://github.com/opencontainers/runc/issues/38), -but no plans for any setuid support. - -The bubblewrap authors believe that runc and systemd-nspawn are not -designed to be made setuid and are distant from supporting such a -mode. - -[binctr](https://github.com/jfrazelle/binctr) is just a wrapper for -runc, so inherits all of its design tradeoffs. - -Whats with the name ?! ----------------------- - -The name bubblewrap was chosen to convey that this -tool runs as the parent of the application (so wraps it in some sense) and creates -a protective layer (the sandbox) around it. - -![](bubblewrap.jpg) - -(Bubblewrap cat by [dancing_stupidity](https://www.flickr.com/photos/27549668@N03/)) diff --git a/external/bubblewrap/autogen.sh b/external/bubblewrap/autogen.sh deleted file mode 100755 index 4674ca8..0000000 --- a/external/bubblewrap/autogen.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -test -n "$srcdir" || srcdir=`dirname "$0"` -test -n "$srcdir" || srcdir=. - -olddir=`pwd` -cd $srcdir - -if ! (autoreconf --version >/dev/null 2>&1); then - echo "*** No autoreconf found, please install it ***" - exit 1 -fi - -mkdir -p m4 - -autoreconf --force --install --verbose - -cd $olddir -test -n "$NOCONFIGURE" || "$srcdir/configure" "$@" diff --git a/external/bubblewrap/bind-mount.c b/external/bubblewrap/bind-mount.c deleted file mode 100644 index 72fd3c5..0000000 --- a/external/bubblewrap/bind-mount.c +++ /dev/null @@ -1,285 +0,0 @@ -/* bubblewrap - * Copyright (C) 2016 Alexander Larsson - * - * This program 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 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, see . - * - */ - -#include "config.h" - -#include - -#include "utils.h" -#include "bind-mount.h" - -static char * -skip_line (char *line) -{ - while (*line != 0 && *line != '\n') - line++; - - if (*line == '\n') - line++; - - return line; -} - -static char * -skip_token (char *line, bool eat_whitespace) -{ - while (*line != ' ' && *line != '\n') - line++; - - if (eat_whitespace && *line == ' ') - line++; - - return line; -} - -static char * -unescape_mountpoint (const char *escaped, ssize_t len) -{ - char *unescaped, *res; - const char *end; - - if (len < 0) - len = strlen (escaped); - end = escaped + len; - - unescaped = res = xmalloc (len + 1); - while (escaped < end) - { - if (*escaped == '\\') - { - *unescaped++ = - ((escaped[1] - '0') << 6) | - ((escaped[2] - '0') << 3) | - ((escaped[3] - '0') << 0); - escaped += 4; - } - else - { - *unescaped++ = *escaped++; - } - } - *unescaped = 0; - return res; -} - -static char * -get_mountinfo (int proc_fd, - const char *mountpoint) -{ - char *line_mountpoint, *line_mountpoint_end; - cleanup_free char *mountinfo = NULL; - cleanup_free char *free_me = NULL; - char *line, *line_start; - char *res = NULL; - int i; - - if (mountpoint[0] != '/') - { - cleanup_free char *cwd = getcwd (NULL, 0); - if (cwd == NULL) - die_oom (); - - mountpoint = free_me = strconcat3 (cwd, "/", mountpoint); - } - - mountinfo = load_file_at (proc_fd, "self/mountinfo"); - if (mountinfo == NULL) - return NULL; - - line = mountinfo; - - while (*line != 0) - { - cleanup_free char *unescaped = NULL; - - line_start = line; - for (i = 0; i < 4; i++) - line = skip_token (line, TRUE); - line_mountpoint = line; - line = skip_token (line, FALSE); - line_mountpoint_end = line; - line = skip_line (line); - - unescaped = unescape_mountpoint (line_mountpoint, line_mountpoint_end - line_mountpoint); - if (strcmp (mountpoint, unescaped) == 0) - { - res = line_start; - line[-1] = 0; - /* Keep going, because we want to return the *last* match */ - } - } - - if (res) - return xstrdup (res); - return NULL; -} - -static unsigned long -get_mountflags (int proc_fd, - const char *mountpoint) -{ - cleanup_free char *line = NULL; - char *token, *end_token; - int i; - unsigned long flags = 0; - static const struct { int flag; - char *name; - } flags_data[] = { - { 0, "rw" }, - { MS_RDONLY, "ro" }, - { MS_NOSUID, "nosuid" }, - { MS_NODEV, "nodev" }, - { MS_NOEXEC, "noexec" }, - { MS_NOATIME, "noatime" }, - { MS_NODIRATIME, "nodiratime" }, - { MS_RELATIME, "relatime" }, - { 0, NULL } - }; - - line = get_mountinfo (proc_fd, mountpoint); - if (line == NULL) - return 0; - - token = line; - for (i = 0; i < 5; i++) - token = skip_token (token, TRUE); - - end_token = skip_token (token, FALSE); - *end_token = 0; - - do - { - end_token = strchr (token, ','); - if (end_token != NULL) - *end_token = 0; - - for (i = 0; flags_data[i].name != NULL; i++) - if (strcmp (token, flags_data[i].name) == 0) - flags |= flags_data[i].flag; - - if (end_token) - token = end_token + 1; - else - token = NULL; - } - while (token != NULL); - - return flags; -} - - -static char ** -get_submounts (int proc_fd, - const char *parent_mount) -{ - char *mountpoint, *mountpoint_end; - char **submounts; - int i, n_submounts, submounts_size; - cleanup_free char *mountinfo = NULL; - char *line; - - mountinfo = load_file_at (proc_fd, "self/mountinfo"); - if (mountinfo == NULL) - return NULL; - - submounts_size = 8; - n_submounts = 0; - submounts = xmalloc (sizeof (char *) * submounts_size); - - line = mountinfo; - - while (*line != 0) - { - cleanup_free char *unescaped = NULL; - for (i = 0; i < 4; i++) - line = skip_token (line, TRUE); - mountpoint = line; - line = skip_token (line, FALSE); - mountpoint_end = line; - line = skip_line (line); - *mountpoint_end = 0; - - unescaped = unescape_mountpoint (mountpoint, -1); - - if (has_path_prefix (unescaped, parent_mount)) - { - if (n_submounts + 1 >= submounts_size) - { - submounts_size *= 2; - submounts = xrealloc (submounts, sizeof (char *) * submounts_size); - } - submounts[n_submounts++] = xstrdup (unescaped); - } - } - - submounts[n_submounts] = NULL; - - return submounts; -} - -int -bind_mount (int proc_fd, - const char *src, - const char *dest, - bind_option_t options) -{ - bool readonly = (options & BIND_READONLY) != 0; - bool devices = (options & BIND_DEVICES) != 0; - bool recursive = (options & BIND_RECURSIVE) != 0; - unsigned long current_flags, new_flags; - int i; - - if (mount (src, dest, NULL, MS_MGC_VAL | MS_BIND | (recursive ? MS_REC : 0), NULL) != 0) - return 1; - - current_flags = get_mountflags (proc_fd, dest); - - new_flags = current_flags | (devices ? 0 : MS_NODEV) | MS_NOSUID | (readonly ? MS_RDONLY : 0); - if (new_flags != current_flags && - mount ("none", dest, - NULL, MS_MGC_VAL | MS_BIND | MS_REMOUNT | new_flags, NULL) != 0) - return 3; - - /* We need to work around the fact that a bind mount does not apply the flags, so we need to manually - * apply the flags to all submounts in the recursive case. - * Note: This does not apply the flags to mounts which are later propagated into this namespace. - */ - if (recursive) - { - cleanup_strv char **submounts = get_submounts (proc_fd, dest); - if (submounts == NULL) - return 4; - - for (i = 0; submounts[i] != NULL; i++) - { - current_flags = get_mountflags (proc_fd, submounts[i]); - new_flags = current_flags | (devices ? 0 : MS_NODEV) | MS_NOSUID | (readonly ? MS_RDONLY : 0); - if (new_flags != current_flags && - mount ("none", submounts[i], - NULL, MS_MGC_VAL | MS_BIND | MS_REMOUNT | new_flags, NULL) != 0) - { - /* If we can't read the mountpoint we can't remount it, but that should - be safe to ignore because its not something the user can access. */ - if (errno != EACCES) - return 5; - } - } - } - - return 0; -} diff --git a/external/bubblewrap/bind-mount.h b/external/bubblewrap/bind-mount.h deleted file mode 100644 index c763763..0000000 --- a/external/bubblewrap/bind-mount.h +++ /dev/null @@ -1,30 +0,0 @@ -/* bubblewrap - * Copyright (C) 2016 Alexander Larsson - * - * This program 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 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, see . - * - */ - -#pragma once - -typedef enum { - BIND_READONLY = (1 << 0), - BIND_DEVICES = (1 << 2), - BIND_RECURSIVE = (1 << 3), -} bind_option_t; - -int bind_mount (int proc_fd, - const char *src, - const char *dest, - bind_option_t options); diff --git a/external/bubblewrap/bubblewrap.c b/external/bubblewrap/bubblewrap.c deleted file mode 100644 index 1c0feee..0000000 --- a/external/bubblewrap/bubblewrap.c +++ /dev/null @@ -1,1593 +0,0 @@ -/* bubblewrap - * Copyright (C) 2016 Alexander Larsson - * - * This program 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 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, see . - * - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "utils.h" -#include "network.h" -#include "bind-mount.h" - -#ifndef CLONE_NEWCGROUP -#define CLONE_NEWCGROUP 0x02000000 /* New cgroup namespace */ -#endif - -/* Globals to avoid having to use getuid(), since the uid/gid changes during runtime */ -static uid_t uid; -static gid_t gid; -static bool is_privileged; -static const char *argv0; -static const char *host_tty_dev; -static int proc_fd = -1; -static char *opt_exec_label = NULL; -static char *opt_file_label = NULL; - -typedef enum { - SETUP_BIND_MOUNT, - SETUP_RO_BIND_MOUNT, - SETUP_DEV_BIND_MOUNT, - SETUP_MOUNT_PROC, - SETUP_MOUNT_DEV, - SETUP_MOUNT_TMPFS, - SETUP_MOUNT_MQUEUE, - SETUP_MAKE_DIR, - SETUP_MAKE_FILE, - SETUP_MAKE_BIND_FILE, - SETUP_MAKE_SYMLINK, -} SetupOpType; - -typedef struct _SetupOp SetupOp; - -struct _SetupOp -{ - SetupOpType type; - const char *source; - const char *dest; - int fd; - SetupOp *next; -}; - -typedef struct _LockFile LockFile; - -struct _LockFile -{ - const char *path; - LockFile *next; -}; - -static SetupOp *ops = NULL; -static SetupOp *last_op = NULL; -static LockFile *lock_files = NULL; -static LockFile *last_lock_file = NULL; - -enum { - PRIV_SEP_OP_DONE, - PRIV_SEP_OP_BIND_MOUNT, - PRIV_SEP_OP_PROC_MOUNT, - PRIV_SEP_OP_TMPFS_MOUNT, - PRIV_SEP_OP_DEVPTS_MOUNT, - PRIV_SEP_OP_MQUEUE_MOUNT, -}; - -typedef struct -{ - uint32_t op; - uint32_t flags; - uint32_t arg1_offset; - uint32_t arg2_offset; -} PrivSepOp; - -static SetupOp * -setup_op_new (SetupOpType type) -{ - SetupOp *op = xcalloc (sizeof (SetupOp)); - - op->type = type; - op->fd = -1; - if (last_op != NULL) - last_op->next = op; - else - ops = op; - - last_op = op; - return op; -} - -static LockFile * -lock_file_new (const char *path) -{ - LockFile *lock = xcalloc (sizeof (LockFile)); - - lock->path = path; - if (last_lock_file != NULL) - last_lock_file->next = lock; - else - lock_files = lock; - - last_lock_file = lock; - return lock; -} - - -static void -usage (int ecode, FILE *out) -{ - fprintf (out, "usage: %s [OPTIONS...] COMMAND [ARGS...]\n\n", argv0); - - fprintf (out, - " --help Print this help\n" - " --version Print version\n" - " --args FD Parse nul-separated args from FD\n" - " --unshare-user Create new user namespace (may be automatically implied if not setuid)\n" - " --unshare-ipc Create new ipc namespace\n" - " --unshare-pid Create new pid namespace\n" - " --unshare-net Create new network namespace\n" - " --unshare-uts Create new uts namespace\n" - " --unshare-cgroup Create new cgroup namespace\n" - " --unshare-cgroup-try Create new cgroup namespace if possible else continue by skipping it\n" - " --uid UID Custom uid in the sandbox (requires --unshare-user)\n" - " --gid GID Custon gid in the sandbox (requires --unshare-user)\n" - " --chdir DIR Change directory to DIR\n" - " --setenv VAR VALUE Set an environment variable\n" - " --unsetenv VAR Unset an environment variable\n" - " --lock-file DEST Take a lock on DEST while sandbox is running\n" - " --sync-fd FD Keep this fd open while sandbox is running\n" - " --bind SRC DEST Bind mount the host path SRC on DEST\n" - " --dev-bind SRC DEST Bind mount the host path SRC on DEST, allowing device access\n" - " --ro-bind SRC DEST Bind mount the host path SRC readonly on DEST\n" - " --exec-label LABEL Exec Label for the sandbox\n" - " --file-label LABEL File label for temporary sandbox content\n" - " --proc DEST Mount procfs on DEST\n" - " --dev DEST Mount new dev on DEST\n" - " --tmpfs DEST Mount new tmpfs on DEST\n" - " --mqueue DEST Mount new mqueue on DEST\n" - " --dir DEST Create dir at DEST\n" - " --file FD DEST Copy from FD to dest DEST\n" - " --bind-data FD DEST Copy from FD to file which is bind-mounted on DEST\n" - " --symlink SRC DEST Create symlink at DEST with target SRC\n" - " --seccomp FD Load and use seccomp rules from FD\n" - " --pid-file DEST Store container execute process PID in file DEST\n" - ); - exit (ecode); -} - -static void -block_sigchild (void) -{ - sigset_t mask; - - sigemptyset (&mask); - sigaddset (&mask, SIGCHLD); - - if (sigprocmask (SIG_BLOCK, &mask, NULL) == -1) - die_with_error ("sigprocmask"); -} - -static void -unblock_sigchild (void) -{ - sigset_t mask; - - sigemptyset (&mask); - sigaddset (&mask, SIGCHLD); - - if (sigprocmask (SIG_UNBLOCK, &mask, NULL) == -1) - die_with_error ("sigprocmask"); -} - -/* Closes all fd:s except 0,1,2 and the passed in array of extra fds */ -static int -close_extra_fds (void *data, int fd) -{ - int *extra_fds = (int *) data; - int i; - - for (i = 0; extra_fds[i] != -1; i++) - if (fd == extra_fds[i]) - return 0; - - if (fd <= 2) - return 0; - - close (fd); - return 0; -} - -/* This stays around for as long as the initial process in the app does - * and when that exits it exits, propagating the exit status. We do this - * by having pid 1 in the sandbox detect this exit and tell the monitor - * the exit status via a eventfd. We also track the exit of the sandbox - * pid 1 via a signalfd for SIGCHLD, and exit with an error in this case. - * This is to catch e.g. problems during setup. */ -static void -monitor_child (int event_fd) -{ - int res; - uint64_t val; - ssize_t s; - int signal_fd; - sigset_t mask; - struct pollfd fds[2]; - int num_fds; - struct signalfd_siginfo fdsi; - int dont_close[] = { event_fd, -1 }; - - /* Close all extra fds in the monitoring process. - Any passed in fds have been passed on to the child anyway. */ - fdwalk (proc_fd, close_extra_fds, dont_close); - - sigemptyset (&mask); - sigaddset (&mask, SIGCHLD); - - signal_fd = signalfd (-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK); - if (signal_fd == -1) - die_with_error ("Can't create signalfd"); - - num_fds = 1; - fds[0].fd = signal_fd; - fds[0].events = POLLIN; - if (event_fd != -1) - { - fds[1].fd = event_fd; - fds[1].events = POLLIN; - num_fds++; - } - - while (1) - { - fds[0].revents = fds[1].revents = 0; - res = poll (fds, num_fds, -1); - if (res == -1 && errno != EINTR) - die_with_error ("poll"); - - /* Always read from the eventfd first, if pid 2 died then pid 1 often - * dies too, and we could race, reporting that first and we'd lose - * the real exit status. */ - if (event_fd != -1) - { - s = read (event_fd, &val, 8); - if (s == -1 && errno != EINTR && errno != EAGAIN) - die_with_error ("read eventfd"); - else if (s == 8) - exit ((int) val - 1); - } - - s = read (signal_fd, &fdsi, sizeof (struct signalfd_siginfo)); - if (s == -1 && errno != EINTR && errno != EAGAIN) - { - die_with_error ("read signalfd"); - } - else if (s == sizeof (struct signalfd_siginfo)) - { - if (fdsi.ssi_signo != SIGCHLD) - die ("Read unexpected signal\n"); - exit (fdsi.ssi_status); - } - } -} - -/* This is pid 1 in the app sandbox. It is needed because we're using - * pid namespaces, and someone has to reap zombies in it. We also detect - * when the initial process (pid 2) dies and report its exit status to - * the monitor so that it can return it to the original spawner. - * - * When there are no other processes in the sandbox the wait will return - * ECHILD, and we then exit pid 1 to clean up the sandbox. */ -static int -do_init (int event_fd, pid_t initial_pid) -{ - int initial_exit_status = 1; - LockFile *lock; - - for (lock = lock_files; lock != NULL; lock = lock->next) - { - int fd = open (lock->path, O_RDONLY | O_CLOEXEC); - if (fd == -1) - die_with_error ("Unable to open lock file %s", lock->path); - - struct flock l = { - .l_type = F_RDLCK, - .l_whence = SEEK_SET, - .l_start = 0, - .l_len = 0 - }; - - if (fcntl (fd, F_SETLK, &l) < 0) - die_with_error ("Unable to lock file %s", lock->path); - - /* Keep fd open to hang on to lock */ - } - - while (TRUE) - { - pid_t child; - int status; - - child = wait (&status); - if (child == initial_pid && event_fd != -1) - { - uint64_t val; - int res UNUSED; - - if (WIFEXITED (status)) - initial_exit_status = WEXITSTATUS (status); - - val = initial_exit_status + 1; - res = write (event_fd, &val, 8); - /* Ignore res, if e.g. the parent died and closed event_fd - we don't want to error out here */ - } - - if (child == -1 && errno != EINTR) - { - if (errno != ECHILD) - die_with_error ("init wait()"); - break; - } - } - - return initial_exit_status; -} - -/* low 32bit caps needed */ -#define REQUIRED_CAPS_0 (CAP_TO_MASK (CAP_SYS_ADMIN) | CAP_TO_MASK (CAP_SYS_CHROOT) | CAP_TO_MASK (CAP_NET_ADMIN) | CAP_TO_MASK (CAP_SETUID) | CAP_TO_MASK (CAP_SETGID)) -/* high 32bit caps needed */ -#define REQUIRED_CAPS_1 0 - -static void -acquire_caps (void) -{ - struct __user_cap_header_struct hdr = { _LINUX_CAPABILITY_VERSION_3, 0 }; - struct __user_cap_data_struct data[2] = { { 0 } }; - - if (capget (&hdr, data) < 0) - die_with_error ("capget failed"); - - if (((data[0].effective & REQUIRED_CAPS_0) == REQUIRED_CAPS_0) && - ((data[0].permitted & REQUIRED_CAPS_0) == REQUIRED_CAPS_0) && - ((data[1].effective & REQUIRED_CAPS_1) == REQUIRED_CAPS_1) && - ((data[1].permitted & REQUIRED_CAPS_1) == REQUIRED_CAPS_1)) - is_privileged = TRUE; - - if (getuid () != geteuid ()) - { - /* Tell kernel not clear capabilities when dropping root */ - if (prctl (PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) - die_with_error ("prctl(PR_SET_KEEPCAPS) failed"); - - /* Drop root uid, but retain the required permitted caps */ - if (setuid (getuid ()) < 0) - die_with_error ("unable to drop privs"); - } - - if (is_privileged) - { - /* Drop all non-require capabilities */ - data[0].effective = REQUIRED_CAPS_0; - data[0].permitted = REQUIRED_CAPS_0; - data[0].inheritable = 0; - data[1].effective = REQUIRED_CAPS_1; - data[1].permitted = REQUIRED_CAPS_1; - data[1].inheritable = 0; - if (capset (&hdr, data) < 0) - die_with_error ("capset failed"); - } - /* Else, we try unprivileged user namespaces */ - - /* We need the process to be dumpable, or we can't access /proc/self/uid_map */ - if (prctl (PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) - die_with_error ("prctl(PR_SET_DUMPABLE) failed"); -} - -static void -drop_caps (void) -{ - struct __user_cap_header_struct hdr = { _LINUX_CAPABILITY_VERSION_3, 0 }; - struct __user_cap_data_struct data[2] = { { 0 } }; - - if (!is_privileged) - return; - - if (capset (&hdr, data) < 0) - die_with_error ("capset failed"); -} - -static char * -get_newroot_path (const char *path) -{ - while (*path == '/') - path++; - return strconcat ("/newroot/", path); -} - -static char * -get_oldroot_path (const char *path) -{ - while (*path == '/') - path++; - return strconcat ("/oldroot/", path); -} - -static void -write_uid_gid_map (uid_t sandbox_uid, - uid_t parent_uid, - uid_t sandbox_gid, - uid_t parent_gid, - pid_t pid, - bool deny_groups, - bool map_root) -{ - cleanup_free char *uid_map = NULL; - cleanup_free char *gid_map = NULL; - cleanup_free char *dir = NULL; - cleanup_fd int dir_fd = -1; - - if (pid == -1) - dir = xstrdup ("self"); - else - dir = xasprintf ("%d", pid); - - dir_fd = openat (proc_fd, dir, O_RDONLY | O_PATH); - if (dir_fd < 0) - die_with_error ("open /proc/%s failed", dir); - - if (map_root && parent_uid != 0 && sandbox_uid != 0) - uid_map = xasprintf ("0 0 1\n" - "%d %d 1\n", sandbox_uid, parent_uid); - else - uid_map = xasprintf ("%d %d 1\n", sandbox_uid, parent_uid); - - if (write_file_at (dir_fd, "uid_map", uid_map) != 0) - die_with_error ("setting up uid map"); - - if (deny_groups && - write_file_at (dir_fd, "setgroups", "deny\n") != 0) - die_with_error ("error writing to setgroups"); - - if (map_root && parent_gid != 0 && sandbox_gid != 0) - gid_map = xasprintf ("0 0 1\n" - "%d %d 1\n", sandbox_gid, parent_gid); - else - gid_map = xasprintf ("%d %d 1\n", sandbox_gid, parent_gid); - - if (write_file_at (dir_fd, "gid_map", gid_map) != 0) - die_with_error ("setting up gid map"); -} - -static void -privileged_op (int privileged_op_socket, - uint32_t op, - uint32_t flags, - const char *arg1, - const char *arg2) -{ - if (privileged_op_socket != -1) - { - uint32_t buffer[2048]; /* 8k, but is int32 to guarantee nice alignment */ - PrivSepOp *op_buffer = (PrivSepOp *) buffer; - size_t buffer_size = sizeof (PrivSepOp); - uint32_t arg1_offset = 0, arg2_offset = 0; - if (arg1 != NULL) - { - arg1_offset = buffer_size; - buffer_size += strlen (arg1) + 1; - } - if (arg2 != NULL) - { - arg2_offset = buffer_size; - buffer_size += strlen (arg2) + 1; - } - - if (buffer_size >= sizeof (buffer)) - die ("privilege separation operation to large"); - - op_buffer->op = op; - op_buffer->flags = flags; - op_buffer->arg1_offset = arg1_offset; - op_buffer->arg2_offset = arg2_offset; - if (arg1 != NULL) - strcpy ((char *) buffer + arg1_offset, arg1); - if (arg2 != NULL) - strcpy ((char *) buffer + arg2_offset, arg2); - - if (write (privileged_op_socket, buffer, buffer_size) != buffer_size) - die ("Can't write to privileged_op_socket"); - - if (read (privileged_op_socket, buffer, 1) != 1) - die ("Can't read from privileged_op_socket"); - - return; - } - - switch (op) - { - case PRIV_SEP_OP_DONE: - break; - - case PRIV_SEP_OP_BIND_MOUNT: - /* We always bind directories recursively, otherwise this would let us - access files that are otherwise covered on the host */ - if (bind_mount (proc_fd, arg1, arg2, BIND_RECURSIVE | flags) != 0) - die_with_error ("Can't bind mount %s on %s", arg1, arg2); - break; - - case PRIV_SEP_OP_PROC_MOUNT: - if (mount ("proc", arg1, "proc", MS_MGC_VAL | MS_NOSUID | MS_NOEXEC | MS_NODEV, NULL) != 0) - die_with_error ("Can't mount proc on %s", arg1); - break; - - case PRIV_SEP_OP_TMPFS_MOUNT: - { - cleanup_free char *opt = label_mount ("mode=0755", opt_file_label); - if (mount ("tmpfs", arg1, "tmpfs", MS_MGC_VAL | MS_NOSUID | MS_NODEV, opt) != 0) - die_with_error ("Can't mount tmpfs on %s", arg1); - break; - } - - case PRIV_SEP_OP_DEVPTS_MOUNT: - if (mount ("devpts", arg1, "devpts", MS_MGC_VAL | MS_NOSUID | MS_NOEXEC, - "newinstance,ptmxmode=0666,mode=620") != 0) - die_with_error ("Can't mount devpts on %s", arg1); - break; - - case PRIV_SEP_OP_MQUEUE_MOUNT: - if (mount ("mqueue", arg1, "mqueue", 0, NULL) != 0) - die_with_error ("Can't mount mqueue on %s", arg1); - break; - - default: - die ("Unexpected privileged op %d", op); - } -} - -static void -setup_newroot (bool unshare_pid, - int privileged_op_socket) -{ - SetupOp *op; - - for (op = ops; op != NULL; op = op->next) - { - cleanup_free char *source = NULL; - cleanup_free char *dest = NULL; - int source_mode = 0; - int i; - - if (op->source && - op->type != SETUP_MAKE_SYMLINK) - { - source = get_oldroot_path (op->source); - source_mode = get_file_mode (source); - if (source_mode < 0) - die_with_error ("Can't get type of source %s", op->source); - } - - if (op->dest) - { - dest = get_newroot_path (op->dest); - if (mkdir_with_parents (dest, 0755, FALSE) != 0) - die_with_error ("Can't mkdir parents for %s", op->dest); - } - - switch (op->type) - { - case SETUP_RO_BIND_MOUNT: - case SETUP_DEV_BIND_MOUNT: - case SETUP_BIND_MOUNT: - if (source_mode == S_IFDIR) - { - if (mkdir (dest, 0755) != 0 && errno != EEXIST) - die_with_error ("Can't mkdir %s", op->dest); - } - else if (ensure_file (dest, 0666) != 0) - die_with_error ("Can't create file at %s", op->dest); - - privileged_op (privileged_op_socket, - PRIV_SEP_OP_BIND_MOUNT, - (op->type == SETUP_RO_BIND_MOUNT ? BIND_READONLY : 0) | - (op->type == SETUP_DEV_BIND_MOUNT ? BIND_DEVICES : 0), - source, dest); - break; - - case SETUP_MOUNT_PROC: - if (mkdir (dest, 0755) != 0 && errno != EEXIST) - die_with_error ("Can't mkdir %s", op->dest); - - if (unshare_pid) - { - /* Our own procfs */ - privileged_op (privileged_op_socket, - PRIV_SEP_OP_PROC_MOUNT, 0, - dest, NULL); - } - else - { - /* Use system procfs, as we share pid namespace anyway */ - privileged_op (privileged_op_socket, - PRIV_SEP_OP_BIND_MOUNT, 0, - "oldroot/proc", dest); - } - - /* There are a bunch of weird old subdirs of /proc that could potentially be - problematic (for instance /proc/sysrq-trigger lets you shut down the machine - if you have write access). We should not have access to these as a non-privileged - user, but lets cover them anyway just to make sure */ - const char *cover_proc_dirs[] = { "sys", "sysrq-trigger", "irq", "bus" }; - for (i = 0; i < N_ELEMENTS (cover_proc_dirs); i++) - { - cleanup_free char *subdir = strconcat3 (dest, "/", cover_proc_dirs[i]); - privileged_op (privileged_op_socket, - PRIV_SEP_OP_BIND_MOUNT, BIND_READONLY, - subdir, subdir); - } - - break; - - case SETUP_MOUNT_DEV: - if (mkdir (dest, 0755) != 0 && errno != EEXIST) - die_with_error ("Can't mkdir %s", op->dest); - - privileged_op (privileged_op_socket, - PRIV_SEP_OP_TMPFS_MOUNT, 0, - dest, NULL); - - static const char *const devnodes[] = { "null", "zero", "full", "random", "urandom", "tty" }; - for (i = 0; i < N_ELEMENTS (devnodes); i++) - { - cleanup_free char *node_dest = strconcat3 (dest, "/", devnodes[i]); - cleanup_free char *node_src = strconcat ("/oldroot/dev/", devnodes[i]); - if (create_file (node_dest, 0666, NULL) != 0) - die_with_error ("Can't create file %s/%s", op->dest, devnodes[i]); - privileged_op (privileged_op_socket, - PRIV_SEP_OP_BIND_MOUNT, BIND_DEVICES, - node_src, node_dest); - } - - static const char *const stdionodes[] = { "stdin", "stdout", "stderr" }; - for (i = 0; i < N_ELEMENTS (stdionodes); i++) - { - cleanup_free char *target = xasprintf ("/proc/self/fd/%d", i); - cleanup_free char *node_dest = strconcat3 (dest, "/", stdionodes[i]); - if (symlink (target, node_dest) < 0) - die_with_error ("Can't create symlink %s/%s", op->dest, stdionodes[i]); - } - - { - cleanup_free char *pts = strconcat (dest, "/pts"); - cleanup_free char *ptmx = strconcat (dest, "/ptmx"); - cleanup_free char *shm = strconcat (dest, "/shm"); - - if (mkdir (shm, 0755) == -1) - die_with_error ("Can't create %s/shm", op->dest); - - if (mkdir (pts, 0755) == -1) - die_with_error ("Can't create %s/devpts", op->dest); - privileged_op (privileged_op_socket, - PRIV_SEP_OP_DEVPTS_MOUNT, BIND_DEVICES, - pts, NULL); - - if (symlink ("pts/ptmx", ptmx) != 0) - die_with_error ("Can't make symlink at %s/ptmx", op->dest); - } - - /* If stdout is a tty, that means the sandbox can write to the - outside-sandbox tty. In that case we also create a /dev/console - that points to this tty device. This should not cause any more - access than we already have, and it makes ttyname() work in the - sandbox. */ - if (host_tty_dev != NULL && *host_tty_dev != 0) - { - cleanup_free char *src_tty_dev = strconcat ("/oldroot", host_tty_dev); - cleanup_free char *dest_console = strconcat (dest, "/console"); - - if (create_file (dest_console, 0666, NULL) != 0) - die_with_error ("creating %s/console", op->dest); - - privileged_op (privileged_op_socket, - PRIV_SEP_OP_BIND_MOUNT, BIND_DEVICES, - src_tty_dev, dest_console); - } - - break; - - case SETUP_MOUNT_TMPFS: - if (mkdir (dest, 0755) != 0 && errno != EEXIST) - die_with_error ("Can't mkdir %s", op->dest); - - privileged_op (privileged_op_socket, - PRIV_SEP_OP_TMPFS_MOUNT, 0, - dest, NULL); - break; - - case SETUP_MOUNT_MQUEUE: - if (mkdir (dest, 0755) != 0 && errno != EEXIST) - die_with_error ("Can't mkdir %s", op->dest); - - privileged_op (privileged_op_socket, - PRIV_SEP_OP_MQUEUE_MOUNT, 0, - dest, NULL); - break; - - case SETUP_MAKE_DIR: - if (mkdir (dest, 0755) != 0 && errno != EEXIST) - die_with_error ("Can't mkdir %s", op->dest); - - break; - - case SETUP_MAKE_FILE: - { - cleanup_fd int dest_fd = -1; - - dest_fd = creat (dest, 0666); - if (dest_fd == -1) - die_with_error ("Can't create file %s", op->dest); - - if (copy_file_data (op->fd, dest_fd) != 0) - die_with_error ("Can't write data to file %s", op->dest); - - close (op->fd); - } - break; - - case SETUP_MAKE_BIND_FILE: - { - cleanup_fd int dest_fd = -1; - char tempfile[] = "/bindfileXXXXXX"; - - dest_fd = mkstemp (tempfile); - if (dest_fd == -1) - die_with_error ("Can't create tmpfile for %s", op->dest); - - if (copy_file_data (op->fd, dest_fd) != 0) - die_with_error ("Can't write data to file %s", op->dest); - - close (op->fd); - - if (ensure_file (dest, 0666) != 0) - die_with_error ("Can't create file at %s", op->dest); - - privileged_op (privileged_op_socket, - PRIV_SEP_OP_BIND_MOUNT, - 0, tempfile, dest); - } - break; - - case SETUP_MAKE_SYMLINK: - if (symlink (op->source, dest) != 0) - die_with_error ("Can't make symlink at %s", op->dest); - break; - - default: - die ("Unexpected type %d", op->type); - } - } - privileged_op (privileged_op_socket, - PRIV_SEP_OP_DONE, 0, NULL, NULL); -} - -static const char * -resolve_string_offset (void *buffer, - size_t buffer_size, - uint32_t offset) -{ - if (offset == 0) - return NULL; - - if (offset > buffer_size) - die ("Invalid string offset %d (buffer size %zd)", offset, buffer_size); - - return (const char *) buffer + offset; -} - -static uint32_t -read_priv_sec_op (int read_socket, - void *buffer, - size_t buffer_size, - uint32_t *flags, - const char **arg1, - const char **arg2) -{ - const PrivSepOp *op = (const PrivSepOp *) buffer; - ssize_t rec_len; - - do - rec_len = read (read_socket, buffer, buffer_size - 1); - while (rec_len == -1 && errno == EINTR); - - if (rec_len < 0) - die_with_error ("Can't read from unprivileged helper"); - - if (rec_len < sizeof (PrivSepOp)) - die ("Invalid size %zd from unprivileged helper", rec_len); - - /* Guarantee zero termination of any strings */ - ((char *) buffer)[rec_len] = 0; - - *flags = op->flags; - *arg1 = resolve_string_offset (buffer, rec_len, op->arg1_offset); - *arg2 = resolve_string_offset (buffer, rec_len, op->arg2_offset); - - return op->op; -} - -char *opt_chdir_path = NULL; -bool opt_unshare_user = FALSE; -bool opt_unshare_pid = FALSE; -bool opt_unshare_ipc = FALSE; -bool opt_unshare_net = FALSE; -bool opt_unshare_uts = FALSE; -bool opt_unshare_cgroup = FALSE; -bool opt_unshare_cgroup_try = FALSE; -bool opt_needs_devpts = FALSE; -uid_t opt_sandbox_uid = -1; -gid_t opt_sandbox_gid = -1; -int opt_sync_fd = -1; -int opt_seccomp_fd = -1; -char *opt_pid_file = NULL; - - -static void -parse_args_recurse (int *argcp, - char ***argvp, - bool in_file, - int *total_parsed_argc_p) -{ - SetupOp *op; - int argc = *argcp; - char **argv = *argvp; - /* I can't imagine a case where someone wants more than this. - * If you do...you should be able to pass multiple files - * via a single tmpfs and linking them there, etc. - * - * We're adding this hardening due to precedent from - * http://googleprojectzero.blogspot.com/2014/08/the-poisoned-nul-byte-2014-edition.html - * - * I picked 9000 because the Internet told me to and it was hard to - * resist. - */ - static const uint32_t MAX_ARGS = 9000; - - if (*total_parsed_argc_p > MAX_ARGS) - die ("Exceeded maximum number of arguments %u", MAX_ARGS); - - while (argc > 0) - { - const char *arg = argv[0]; - - if (strcmp (arg, "--help") == 0) - { - usage (EXIT_SUCCESS, stdout); - } - else if (strcmp (arg, "--version") == 0) - { - printf ("%s\n", PACKAGE_STRING); - exit (0); - } - else if (strcmp (arg, "--args") == 0) - { - int the_fd; - char *endptr; - char *data, *p; - char *data_end; - size_t data_len; - cleanup_free char **data_argv = NULL; - char **data_argv_copy; - int data_argc; - int i; - - if (in_file) - die ("--args not supported in arguments file"); - - if (argc < 2) - die ("--args takes an argument"); - - the_fd = strtol (argv[1], &endptr, 10); - if (argv[1][0] == 0 || endptr[0] != 0 || the_fd < 0) - die ("Invalid fd: %s", argv[1]); - - data = load_file_data (the_fd, &data_len); - if (data == NULL) - die_with_error ("Can't read --args data"); - - data_end = data + data_len; - data_argc = 0; - - p = data; - while (p != NULL && p < data_end) - { - data_argc++; - (*total_parsed_argc_p)++; - if (*total_parsed_argc_p > MAX_ARGS) - die ("Exceeded maximum number of arguments %u", MAX_ARGS); - p = memchr (p, 0, data_end - p); - if (p != NULL) - p++; - } - - data_argv = xcalloc (sizeof (char *) * (data_argc + 1)); - - i = 0; - p = data; - while (p != NULL && p < data_end) - { - /* Note: load_file_data always adds a nul terminator, so this is safe - * even for the last string. */ - data_argv[i++] = p; - p = memchr (p, 0, data_end - p); - if (p != NULL) - p++; - } - - data_argv_copy = data_argv; /* Don't change data_argv, we need to free it */ - parse_args_recurse (&data_argc, &data_argv_copy, TRUE, total_parsed_argc_p); - - argv += 1; - argc -= 1; - } - else if (strcmp (arg, "--unshare-user") == 0) - { - opt_unshare_user = TRUE; - } - else if (strcmp (arg, "--unshare-ipc") == 0) - { - opt_unshare_ipc = TRUE; - } - else if (strcmp (arg, "--unshare-pid") == 0) - { - opt_unshare_pid = TRUE; - } - else if (strcmp (arg, "--unshare-net") == 0) - { - opt_unshare_net = TRUE; - } - else if (strcmp (arg, "--unshare-uts") == 0) - { - opt_unshare_uts = TRUE; - } - else if (strcmp (arg, "--unshare-cgroup") == 0) - { - opt_unshare_cgroup = TRUE; - } - else if (strcmp (arg, "--unshare-cgroup-try") == 0) - { - opt_unshare_cgroup_try = TRUE; - } - else if (strcmp (arg, "--chdir") == 0) - { - if (argc < 2) - die ("--chdir takes one argument"); - - opt_chdir_path = argv[1]; - argv++; - argc--; - } - else if (strcmp (arg, "--bind") == 0) - { - if (argc < 3) - die ("--bind takes two arguments"); - - op = setup_op_new (SETUP_BIND_MOUNT); - op->source = canonicalize_file_name (argv[1]); - if (op->source == NULL) - die_with_error ("Can't find source path %s", argv[1]); - op->dest = argv[2]; - - argv += 2; - argc -= 2; - } - else if (strcmp (arg, "--ro-bind") == 0) - { - if (argc < 3) - die ("--ro-bind takes two arguments"); - - op = setup_op_new (SETUP_RO_BIND_MOUNT); - op->source = canonicalize_file_name (argv[1]); - if (op->source == NULL) - die_with_error ("Can't find source path %s", argv[1]); - op->dest = argv[2]; - - argv += 2; - argc -= 2; - } - else if (strcmp (arg, "--dev-bind") == 0) - { - if (argc < 3) - die ("--dev-bind takes two arguments"); - - op = setup_op_new (SETUP_DEV_BIND_MOUNT); - op->source = canonicalize_file_name (argv[1]); - if (op->source == NULL) - die_with_error ("Can't find source path %s", argv[1]); - op->dest = argv[2]; - - argv += 2; - argc -= 2; - } - else if (strcmp (arg, "--proc") == 0) - { - if (argc < 2) - die ("--proc takes an argument"); - - op = setup_op_new (SETUP_MOUNT_PROC); - op->dest = argv[1]; - - argv += 1; - argc -= 1; - } - else if (strcmp (arg, "--exec-label") == 0) - { - if (argc < 2) - die ("--exec-label takes an argument"); - opt_exec_label = argv[1]; - die_unless_label_valid (opt_exec_label); - - argv += 1; - argc -= 1; - } - else if (strcmp (arg, "--file-label") == 0) - { - if (argc < 2) - die ("--file-label takes an argument"); - opt_file_label = argv[1]; - die_unless_label_valid (opt_file_label); - if (label_create_file (opt_file_label)) - die_with_error ("--file-label setup failed"); - - argv += 1; - argc -= 1; - } - else if (strcmp (arg, "--dev") == 0) - { - if (argc < 2) - die ("--dev takes an argument"); - - op = setup_op_new (SETUP_MOUNT_DEV); - op->dest = argv[1]; - opt_needs_devpts = TRUE; - - argv += 1; - argc -= 1; - } - else if (strcmp (arg, "--tmpfs") == 0) - { - if (argc < 2) - die ("--tmpfs takes an argument"); - - op = setup_op_new (SETUP_MOUNT_TMPFS); - op->dest = argv[1]; - - argv += 1; - argc -= 1; - } - else if (strcmp (arg, "--mqueue") == 0) - { - if (argc < 2) - die ("--mqueue takes an argument"); - - op = setup_op_new (SETUP_MOUNT_MQUEUE); - op->dest = argv[1]; - - argv += 1; - argc -= 1; - } - else if (strcmp (arg, "--dir") == 0) - { - if (argc < 2) - die ("--dir takes an argument"); - - op = setup_op_new (SETUP_MAKE_DIR); - op->dest = argv[1]; - - argv += 1; - argc -= 1; - } - else if (strcmp (arg, "--file") == 0) - { - int file_fd; - char *endptr; - - if (argc < 3) - die ("--file takes two arguments"); - - file_fd = strtol (argv[1], &endptr, 10); - if (argv[1][0] == 0 || endptr[0] != 0 || file_fd < 0) - die ("Invalid fd: %s", argv[1]); - - op = setup_op_new (SETUP_MAKE_FILE); - op->fd = file_fd; - op->dest = argv[2]; - - argv += 2; - argc -= 2; - } - else if (strcmp (arg, "--bind-data") == 0) - { - int file_fd; - char *endptr; - - if (argc < 3) - die ("--bind-data takes two arguments"); - - file_fd = strtol (argv[1], &endptr, 10); - if (argv[1][0] == 0 || endptr[0] != 0 || file_fd < 0) - die ("Invalid fd: %s", argv[1]); - - op = setup_op_new (SETUP_MAKE_BIND_FILE); - op->fd = file_fd; - op->dest = argv[2]; - - argv += 2; - argc -= 2; - } - else if (strcmp (arg, "--symlink") == 0) - { - if (argc < 3) - die ("--symlink takes two arguments"); - - op = setup_op_new (SETUP_MAKE_SYMLINK); - op->source = argv[1]; - op->dest = argv[2]; - - argv += 2; - argc -= 2; - } - else if (strcmp (arg, "--lock-file") == 0) - { - if (argc < 2) - die ("--lock-file takes an argument"); - - (void) lock_file_new (argv[1]); - - argv += 1; - argc -= 1; - } - else if (strcmp (arg, "--sync-fd") == 0) - { - int the_fd; - char *endptr; - - if (argc < 2) - die ("--sync-fd takes an argument"); - - the_fd = strtol (argv[1], &endptr, 10); - if (argv[1][0] == 0 || endptr[0] != 0 || the_fd < 0) - die ("Invalid fd: %s", argv[1]); - - opt_sync_fd = the_fd; - - argv += 1; - argc -= 1; - } - else if (strcmp (arg, "--seccomp") == 0) - { - int the_fd; - char *endptr; - - if (argc < 2) - die ("--seccomp takes an argument"); - - the_fd = strtol (argv[1], &endptr, 10); - if (argv[1][0] == 0 || endptr[0] != 0 || the_fd < 0) - die ("Invalid fd: %s", argv[1]); - - opt_seccomp_fd = the_fd; - - argv += 1; - argc -= 1; - } - else if (strcmp (arg, "--setenv") == 0) - { - if (argc < 3) - die ("--setenv takes two arguments"); - - xsetenv (argv[1], argv[2], 1); - - argv += 2; - argc -= 2; - } - else if (strcmp (arg, "--unsetenv") == 0) - { - if (argc < 2) - die ("--unsetenv takes an argument"); - - xunsetenv (argv[1]); - - argv += 1; - argc -= 1; - } - else if (strcmp (arg, "--uid") == 0) - { - int the_uid; - char *endptr; - - if (argc < 2) - die ("--uid takes an argument"); - - the_uid = strtol (argv[1], &endptr, 10); - if (argv[1][0] == 0 || endptr[0] != 0 || the_uid < 0) - die ("Invalid uid: %s", argv[1]); - - opt_sandbox_uid = the_uid; - - argv += 1; - argc -= 1; - } - else if (strcmp (arg, "--gid") == 0) - { - int the_gid; - char *endptr; - - if (argc < 2) - die ("--gid takes an argument"); - - the_gid = strtol (argv[1], &endptr, 10); - if (argv[1][0] == 0 || endptr[0] != 0 || the_gid < 0) - die ("Invalid gid: %s", argv[1]); - - opt_sandbox_gid = the_gid; - - argv += 1; - argc -= 1; - } - else if (strcmp (arg, "--pid-file") == 0) - { - if (argc < 2) - die ("--pid-file takes an argument"); - - opt_pid_file = argv[1]; - - argv += 1; - argc -= 1; - } - else if (*arg == '-') - { - die ("Unknown option %s", arg); - } - else - { - break; - } - - argv++; - argc--; - } - - *argcp = argc; - *argvp = argv; -} - -static void -parse_args (int *argcp, - char ***argvp) -{ - int total_parsed_argc = *argcp; - - parse_args_recurse (argcp, argvp, FALSE, &total_parsed_argc); -} - -int -bwrap_main (int argc, - char **argv) -{ - mode_t old_umask; - cleanup_free char *base_path = NULL; - int clone_flags; - char *old_cwd = NULL; - pid_t pid; - int event_fd = -1; - int child_wait_fd = -1; - const char *new_cwd; - uid_t ns_uid; - gid_t ns_gid; - struct stat sbuf; - uint64_t val; - int res UNUSED; - - /* Get the (optional) capabilities we need, drop root */ - acquire_caps (); - - /* The initial code is run with high permissions - (i.e. CAP_SYS_ADMIN), so take lots of care. */ - - argv0 = argv[0]; - - if (isatty (1)) - host_tty_dev = ttyname (1); - - argv++; - argc--; - - if (argc == 0) - usage (EXIT_FAILURE, stderr); - - parse_args (&argc, &argv); - - /* We have to do this if we weren't installed setuid, so let's just DWIM */ - if (!is_privileged) - opt_unshare_user = TRUE; - - if (argc == 0) - usage (EXIT_FAILURE, stderr); - - __debug__ (("Creating root mount point\n")); - - uid = getuid (); - if (opt_sandbox_uid == -1) - opt_sandbox_uid = uid; - gid = getgid (); - if (opt_sandbox_gid == -1) - opt_sandbox_gid = gid; - - if (!opt_unshare_user && opt_sandbox_uid != uid) - die ("Specifying --uid requires --unshare-user"); - - if (!opt_unshare_user && opt_sandbox_gid != gid) - die ("Specifying --gid requires --unshare-user"); - - /* We need to read stuff from proc during the pivot_root dance, etc. - Lets keep a fd to it open */ - proc_fd = open ("/proc", O_RDONLY | O_PATH); - if (proc_fd == -1) - die_with_error ("Can't open /proc"); - - /* We need *some* mountpoint where we can mount the root tmpfs. - We first try in /run, and if that fails, try in /tmp. */ - base_path = xasprintf ("/run/user/%d/.bubblewrap", uid); - if (mkdir (base_path, 0755) && errno != EEXIST) - { - free (base_path); - base_path = xasprintf ("/tmp/.bubblewrap-%d", uid); - if (mkdir (base_path, 0755) && errno != EEXIST) - die_with_error ("Creating root mountpoint failed"); - } - - __debug__ (("creating new namespace\n")); - - if (opt_unshare_pid) - { - event_fd = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK); - if (event_fd == -1) - die_with_error ("eventfd()"); - } - - /* We block sigchild here so that we can use signalfd in the monitor. */ - block_sigchild (); - - clone_flags = SIGCHLD; - if (opt_unshare_pid) - clone_flags |= CLONE_NEWPID; - if (opt_unshare_net) - clone_flags |= CLONE_NEWNET; - if (opt_unshare_ipc) - clone_flags |= CLONE_NEWIPC; - if (opt_unshare_uts) - clone_flags |= CLONE_NEWUTS; - if (opt_unshare_cgroup) - { - if (stat ("/proc/self/ns/cgroup", &sbuf)) - { - if (errno == ENOENT) - die ("Cannot create new cgroup namespace because the kernel does not support it"); - else - die_with_error ("stat on /proc/self/ns/cgroup failed"); - } - clone_flags |= CLONE_NEWCGROUP; - } - if (opt_unshare_cgroup_try) - if (!stat ("/proc/self/ns/cgroup", &sbuf)) - clone_flags |= CLONE_NEWCGROUP; - - child_wait_fd = eventfd (0, EFD_CLOEXEC); - if (child_wait_fd == -1) - die_with_error ("eventfd()"); - - pid = raw_clone (clone_flags, NULL); - if (pid == -1) - { - die_with_error ("Creating new namespace failed"); - } - - ns_uid = opt_sandbox_uid; - ns_gid = opt_sandbox_gid; - - if (pid != 0) - { - /* Initial launched process, wait for exec:ed command to exit */ - - if (opt_pid_file) { - /* drop old left over pid file */ - remove(opt_pid_file); - - int pid_file_fd = open(opt_pid_file, O_CREAT | O_WRONLY, 0644); - char pid_str[20]; - snprintf(pid_str, 20, "%i", pid); - write(pid_file_fd, pid_str, strlen(pid_str)); - close(pid_file_fd); - } - - /* Let child run */ - val = 1; - res = write (child_wait_fd, &val, 8); - /* Ignore res, if e.g. the child died and closed child_wait_fd we don't want to error out here */ - close (child_wait_fd); - - monitor_child (event_fd); - exit (0); /* Should not be reached, but better safe... */ - } - - /* Wait for the parent to init uid/gid maps and drop caps */ - res = read (child_wait_fd, &val, 8); - close (child_wait_fd); - - if (opt_unshare_net && loopback_setup () != 0) - die ("Can't create loopback device"); - - ns_uid = opt_sandbox_uid; - ns_gid = opt_sandbox_gid; - - old_umask = umask (0); - - /* Mark everything as slave, so that we still - * receive mounts from the real root, but don't - * propagate mounts to the real root. */ - if (mount (NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) - die_with_error ("Failed to make / slave"); - - /* Create a tmpfs which we will use as / in the namespace */ - if (mount ("", base_path, "tmpfs", MS_NODEV | MS_NOSUID, NULL) != 0) - die_with_error ("Failed to mount tmpfs"); - - old_cwd = get_current_dir_name (); - - /* Chdir to the new root tmpfs mount. This will be the CWD during - the entire setup. Access old or new root via "oldroot" and "newroot". */ - if (chdir (base_path) != 0) - die_with_error ("chdir base_path"); - - /* We create a subdir "$base_path/newroot" for the new root, that - * way we can pivot_root to base_path, and put the old root at - * "$base_path/oldroot". This avoids problems accessing the oldroot - * dir if the user requested to bind mount something over / */ - - if (mkdir ("newroot", 0755)) - die_with_error ("Creating newroot failed"); - - if (mkdir ("oldroot", 0755)) - die_with_error ("Creating oldroot failed"); - - if (pivot_root (base_path, "oldroot")) - die_with_error ("pivot_root"); - - if (chdir ("/") != 0) - die_with_error ("chdir / (base path)"); - - setup_newroot (opt_unshare_pid, -1); - - /* The old root better be rprivate or we will send unmount events to the parent namespace */ - if (mount ("oldroot", "oldroot", NULL, MS_REC | MS_PRIVATE, NULL) != 0) - die_with_error ("Failed to make old root rprivate"); - - if (umount2 ("oldroot", MNT_DETACH)) - die_with_error ("unmount old root"); - - /* Now make /newroot the real root */ - if (chdir ("/newroot") != 0) - die_with_error ("chdir newroot"); - if (chroot ("/newroot") != 0) - die_with_error ("chroot /newroot"); - if (chdir ("/") != 0) - die_with_error ("chdir /"); - - umask (old_umask); - - new_cwd = "/"; - if (opt_chdir_path) - { - if (chdir (opt_chdir_path)) - die_with_error ("Can't chdir to %s", opt_chdir_path); - new_cwd = opt_chdir_path; - } - else if (chdir (old_cwd) == 0) - { - /* If the old cwd is mapped in the sandbox, go there */ - new_cwd = old_cwd; - } - else - { - /* If the old cwd is not mapped, go to home */ - const char *home = getenv ("HOME"); - if (home != NULL && - chdir (home) == 0) - new_cwd = home; - } - xsetenv ("PWD", new_cwd, 1); - free (old_cwd); - - __debug__ (("forking for child\n")); - - if (opt_unshare_pid || lock_files != NULL || opt_sync_fd != -1) - { - /* We have to have a pid 1 in the pid namespace, because - * otherwise we'll get a bunch of zombies as nothing reaps - * them. Alternatively if we're using sync_fd or lock_files we - * need some process to own these. - */ - - pid = fork (); - if (pid == -1) - die_with_error ("Can't fork for pid 1"); - - if (pid != 0) - { - /* Close fds in pid 1, except stdio and optionally event_fd - (for syncing pid 2 lifetime with monitor_child) and - opt_sync_fd (for syncing sandbox lifetime with outside - process). - Any other fds will been passed on to the child though. */ - { - int dont_close[3]; - int j = 0; - if (event_fd != -1) - dont_close[j++] = event_fd; - if (opt_sync_fd != -1) - dont_close[j++] = opt_sync_fd; - dont_close[j++] = -1; - fdwalk (proc_fd, close_extra_fds, dont_close); - } - - return do_init (event_fd, pid); - } - } - - __debug__ (("launch executable %s\n", argv[0])); - - if (proc_fd != -1) - close (proc_fd); - - if (opt_sync_fd != -1) - close (opt_sync_fd); - - /* We want sigchild in the child */ - unblock_sigchild (); - - if (label_exec (opt_exec_label) == -1) - die_with_error ("label_exec %s", argv[0]); - - if (execvp (argv[0], argv) == -1) - die_with_error ("execvp %s", argv[0]); - - return 0; -} diff --git a/external/bubblewrap/bubblewrap.jpg b/external/bubblewrap/bubblewrap.jpg deleted file mode 100644 index d3c243dface42da83cdec1be9bd93f5475120a9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40239 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 diff --git a/external/bubblewrap/bwrap.xml b/external/bubblewrap/bwrap.xml deleted file mode 100644 index 0d5e236..0000000 --- a/external/bubblewrap/bwrap.xml +++ /dev/null @@ -1,266 +0,0 @@ - - - - - - bwrap - Project Atomic - - - Developer - Alexander - Larsson - - - Developer - Colin - Walters - - - - - - bwrap - 1 - User Commands - - - - bwrap - container setup utility - - - - -bwrap -OPTION -COMMAND - - - -Description - - bwrap is a privileged helper for container setup. You - are unlikely to use it directly from the commandline, although that is possible. - - - It works by creating a new, completely empty, filesystem namespace where the root - is on a tmpfs that is invisible from the host, and which will be automatically - cleaned up when the last process exists. You can then use commandline options to - construct the root filesystem and process environment for the command to run in - the namespace. - - - By default, bwrap creates a new user namespace for the sandbox. - Optionally it also sets up new ipc, pid, network and uts namespaces. The application - in the sandbox can be made to run with a different UID and GID. - - - If needed (e.g. when using a PID namespace) bwrap - is running a minimal pid 1 process in the sandbox that is - responsible for reaping zombies. It also detects when the initial - application process (pid 2) dies and reports its exit status back to - the original spawner. The pid 1 process exits to clean up the - sandbox when there are no other processes in the sandbox left. - - - -Options - - When options are used multiple times, the last option wins, unless otherwise - specified. - - General options: - - - - Print help and exit - - - - Print version - - - - - Parse nul-separated arguments from the given file descriptor. - This option can be used multiple times to parse options from - multiple sources. - - - - Options related to kernel namespaces: - - - - Don't create a new user namespace - - - - Create a new ipc namespace - - - - Create a new pid namespace - - - - Create a new network namespace - - - - Create a new uts namespace - - - - Create a new cgroup namespace - - - - Create a new cgroup namespace if possible else skip it - - - - Use a custom user id in the sandbox (incompatible with ) - - - - Use a custom group id in the sandbox (incompatible with ) - - - Options about environment setup: - - - - Change directory to DIR - - - - Set an environment variable - - - - Unset an environment variable - - - Options for monitoring the sandbox from the outside: - - - - - Take a lock on DEST while the sandbox is running. - This option can be used multiple times to take locks on multiple files. - - - - - Keep this file descriptor open while the sandbox is running - - - - Filesystem related options. These are all operations that modify the filesystem directly, or - mounts stuff in the filesystem. These are applied in the order they are given as arguments. - Any missing parent directories that are required to create a specified destination are - automatically created as needed. - - - - - Bind mount the host path SRC on DEST - - - - Bind mount the host path SRC on DEST, allowing device access - - - - Bind mount the host path SRC readonly on DEST - - - - Mount procfs on DEST - - - - Mount new devtmpfs on DEST - - - - Mount new tmpfs on DEST - - - - Mount new mqueue on DEST - - - - Create a directory at DEST - - - - Copy from the file descriptor FD to DEST - - - - Copy from the file descriptor FD to a file which is bind-mounted on DEST - - - - Create a symlink at DEST with target SRC - - - Lockdown options: - - - - - Load and use seccomp rules from FD. - The rules need to be in the form of a compiled eBPF program, - as generated by seccomp_export_bpf. - - - - - - Exec Label from the sandbox. On an SELinux system you can specify the SELinux - context for the sandbox process(s). - - - - - - File label for temporary sandbox content. On an SELinux system you can specify - the SELinux context for the sandbox content. - - - - - - - Environment - - - - HOME - - Used as the cwd in the sandbox if has not been - explicitly specified and the current cwd is not present inside the sandbox. - The option can be used to override the value - that is used here. - - - - - - - Exit status - - - The bwrap command returns the exit status of the - initial application process (pid 2 in the sandbox). - - - - diff --git a/external/bubblewrap/completions/bash/bwrap b/external/bubblewrap/completions/bash/bwrap deleted file mode 100644 index ba312fd..0000000 --- a/external/bubblewrap/completions/bash/bwrap +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash -# -# bash completion file for bubblewrap commands -# - -_bwrap() { - local cur prev words cword - _init_completion || return - - local boolean_options=" - --help - --share-user - --unshare-ipc - --unshare-net - --unshare-pid - --unshare-uts - --version - " - - local options_with_args=" - $boolean_optons - --args - --bind - --bind-data - --chdir - --dev - --dev-bind - --dir - --exec-label - --file - --file-label - --gid - --lock-file - --proc - --ro-bind - --seccomp - --setenv - --symlink - --sync-fd - --uid - --unsetenv - --seccomp - --symlink - " - - if [[ "$cur" == -* ]]; then - COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) - fi - - return 0 -} -complete -F _bwrap bwrap diff --git a/external/bubblewrap/config.h b/external/bubblewrap/config.h deleted file mode 100644 index 383e36f..0000000 --- a/external/bubblewrap/config.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif - -#define PACKAGE_STRING "bubblewrap 0.1" diff --git a/external/bubblewrap/configure.ac b/external/bubblewrap/configure.ac deleted file mode 100644 index d22bd31..0000000 --- a/external/bubblewrap/configure.ac +++ /dev/null @@ -1,103 +0,0 @@ -AC_PREREQ([2.63]) -AC_INIT([bubblewrap], [0.1], [alexl@redhat.com]) -AC_CONFIG_HEADER([config.h]) -AC_CONFIG_MACRO_DIR([m4]) -AC_CONFIG_AUX_DIR([build-aux]) - -AC_USE_SYSTEM_EXTENSIONS - -AM_INIT_AUTOMAKE([1.11 -Wno-portability foreign no-define tar-ustar no-dist-gzip dist-xz]) -AM_MAINTAINER_MODE([enable]) -AM_SILENT_RULES([yes]) - -AC_SYS_LARGEFILE - -AC_PROG_CC -AM_PROG_CC_C_O - -AC_CHECK_HEADERS([sys/capability.h], [], [AC_MSG_ERROR([*** POSIX caps headers not found])]) - -AC_ARG_ENABLE(man, - [AS_HELP_STRING([--enable-man], - [generate man pages [default=auto]])],, - enable_man=maybe) - -AS_IF([test "$enable_man" != no], [ - AC_PATH_PROG([XSLTPROC], [xsltproc], []) - AS_IF([test -z "$XSLTPROC"], [ - AS_IF([test "$enable_man" = yes], [ - AC_MSG_ERROR([xsltproc is required for --enable-man]) - ]) - enable_man=no - ], [ - enable_man=yes - ]) -]) -AM_CONDITIONAL(ENABLE_MAN, test "$enable_man" != no) - -AC_ARG_WITH([bash-completion-dir], - AS_HELP_STRING([--with-bash-completion-dir[=PATH]], - [Install the bash auto-completion script in this directory. @<:@default=yes@:>@]), - [], - [with_bash_completion_dir=yes]) - -if test "x$with_bash_completion_dir" = "xyes"; then - PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0], - [BASH_COMPLETION_DIR="`pkg-config --variable=completionsdir bash-completion`"], - [BASH_COMPLETION_DIR="$datadir/bash-completion/completions"]) -else - BASH_COMPLETION_DIR="$with_bash_completion_dir" -fi - -AC_SUBST([BASH_COMPLETION_DIR]) -AM_CONDITIONAL([ENABLE_BASH_COMPLETION],[test "x$with_bash_completion_dir" != "xno"]) -# ------------------------------------------------------------------------------ -have_selinux=no -AC_ARG_ENABLE(selinux, AS_HELP_STRING([--disable-selinux], [Disable optional SELINUX support])) -if test "x$enable_selinux" != "xno"; then - PKG_CHECK_MODULES([SELINUX], [libselinux >= 2.1.9], - [AC_DEFINE(HAVE_SELINUX, 1, [Define if SELinux is available]) - have_selinux=yes - M4_DEFINES="$M4_DEFINES -DHAVE_SELINUX"], - [have_selinux=no]) - if test "x$have_selinux" = xno -a "x$enable_selinux" = xyes; then - AC_MSG_ERROR([*** SELinux support requested but libraries not found]) - fi -fi -AM_CONDITIONAL(HAVE_SELINUX, [test "$have_selinux" = "yes"]) - -changequote(,)dnl -if test "x$GCC" = "xyes"; then - WARN_CFLAGS="-Wall -Werror=missing-prototypes" -fi -changequote([,])dnl -AC_SUBST(WARN_CFLAGS) - -AC_ARG_WITH(priv-mode, - AS_HELP_STRING([--with-priv-mode=setuid/caps/none], - [How to set privilege-raising during make install)]), - [], - [with_priv_mode="none"]) - -AM_CONDITIONAL(PRIV_MODE_FILECAPS, test "x$with_priv_mode" = "xcaps") -AM_CONDITIONAL(PRIV_MODE_SETUID, test "x$with_priv_mode" = "xsetuid") - -AC_ARG_ENABLE(sudo, - AS_HELP_STRING([--enable-sudo],[Use sudo to set privileged mode on binaries during install (only needed if --with-priv-mode used)]), - [SUDO_BIN="sudo"], [SUDO_BIN=""]) -AC_SUBST([SUDO_BIN]) - -AC_CONFIG_FILES([ -Makefile -]) -AC_OUTPUT - -echo " - bubblewrap $VERSION - =================== - - man pages (xsltproc): $enable_man - SELinux: $have_selinux - setuid mode on make install: $with_priv_mode - mysteriously satisfying to pop: yes" -echo "" diff --git a/external/bubblewrap/demos/bubblewrap-shell.sh b/external/bubblewrap/demos/bubblewrap-shell.sh deleted file mode 100755 index da06d49..0000000 --- a/external/bubblewrap/demos/bubblewrap-shell.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -# Use bubblewrap to run /bin/sh in the host's rootfs. -set -euo pipefail -(exec bwrap --ro-bind /usr /usr \ - --dir /tmp \ - --proc /proc \ - --dev /dev \ - --ro-bind /etc/resolv.conf /etc/resolv.conf \ - --symlink usr/lib /lib \ - --symlink usr/lib64 /lib64 \ - --symlink usr/bin /bin \ - --symlink usr/sbin /sbin \ - --chdir / \ - --unshare-pid \ - --dir /run/user/$(id -u) \ - --setenv XDG_RUNTIME_DIR "/run/user/`id -u`" \ - --file 11 /etc/passwd \ - --file 12 /etc/group \ - /bin/sh) \ - 11< <(getent passwd $UID 65534) \ - 12< <(getent group $(id -g) 65534) diff --git a/external/bubblewrap/demos/xdg-app-run.sh b/external/bubblewrap/demos/xdg-app-run.sh deleted file mode 100755 index 02295cd..0000000 --- a/external/bubblewrap/demos/xdg-app-run.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash -# For this to work you first have to run these commands: -# curl -O http://sdk.gnome.org/nightly/keys/nightly.gpg -# xdg-app --user remote-add --gpg-key=nightly.gpg gnome-nightly http://sdk.gnome.org/nightly/repo/ -# xdg-app --user install gnome-nightly org.gnome.Platform -# xdg-app --user install gnome-nightly org.gnome.Weather - -mkdir -p ~/.var/app/org.gnome.Weather/cache ~/.var/app/org.gnome.Weather/config ~/.var/app/org.gnome.Weather/data - -( - exec bwrap \ - --ro-bind ~/.local/share/xdg-app/runtime/org.gnome.Platform/x86_64/master/active/files /usr \ - --lock-file /usr/.ref \ - --ro-bind ~/.local/share/xdg-app/app/org.gnome.Weather/x86_64/master/active/files/ /app \ - --lock-file /app/.ref \ - --dev /dev \ - --proc /proc \ - --dir /tmp \ - --symlink /tmp /var/tmp \ - --symlink /run /var/run \ - --symlink usr/lib /lib \ - --symlink usr/lib64 /lib64 \ - --symlink usr/bin /bin \ - --symlink usr/sbin /sbin \ - --symlink usr/etc /etc \ - --dir /run/user/`id -u` \ - --ro-bind /etc/machine-id /usr/etc/machine-id \ - --ro-bind /etc/resolv.conf /run/host/monitor/resolv.conf \ - --ro-bind /sys/block /sys/block \ - --ro-bind /sys/bus /sys/bus \ - --ro-bind /sys/class /sys/class \ - --ro-bind /sys/dev /sys/dev \ - --ro-bind /sys/devices /sys/devices \ - --dev-bind /dev/dri /dev/dri \ - --bind /tmp/.X11-unix/X0 /tmp/.X11-unix/X99 \ - --bind ~/.var/app/org.gnome.Weather ~/.var/app/org.gnome.Weather \ - --bind ~/.config/dconf ~/.config/dconf \ - --bind /run/user/`id -u`/dconf /run/user/`id -u`/dconf \ - --unshare-pid \ - --setenv XDG_RUNTIME_DIR "/run/user/`id -u`" \ - --setenv DISPLAY :99 \ - --setenv GI_TYPELIB_PATH /app/lib/girepository-1.0 \ - --setenv GST_PLUGIN_PATH /app/lib/gstreamer-1.0 \ - --setenv LD_LIBRARY_PATH /app/lib:/usr/lib/GL \ - --setenv DCONF_USER_CONFIG_DIR .config/dconf \ - --setenv PATH /app/bin:/usr/bin \ - --setenv XDG_CONFIG_DIRS /app/etc/xdg:/etc/xdg \ - --setenv XDG_DATA_DIRS /app/share:/usr/share \ - --setenv SHELL /bin/sh \ - --setenv XDG_CACHE_HOME ~/.var/app/org.gnome.Weather/cache \ - --setenv XDG_CONFIG_HOME ~/.var/app/org.gnome.Weather/config \ - --setenv XDG_DATA_HOME ~/.var/app/org.gnome.Weather/data \ - --file 10 /run/user/`id -u`/xdg-app-info \ - --bind-data 11 /usr/etc/passwd \ - --bind-data 12 /usr/etc/group \ - --seccomp 13 \ - /bin/sh) \ - 11< <(getent passwd $UID 65534 ) \ - 12< <(getent group $(id -g) 65534) \ - 13< `dirname $0`/xdg-app.bpf \ - 10<h*Q_+j7k z)4t=_ZgFDY^4o6m&u(yL-*9f%p%gi<$?Yo|_9bomB653)=aDC$MV?%XJh>Wq@@eGB zCy^(6ktZKVp6o`R>_nb?6nXMt)bOv}VVWy*3#^B4PUNx4w#q$wg^sPTWywBkf1!%^qkAdqw4Y&DPoO^AS6`@N We)v7|M64o@XNCT^u%z{a9{vNd1~

/dev/null; then \ - echo "$$x already includes git.mk"; \ - else \ - failed=; \ - echo "Updating $$x"; \ - { cat $$x; \ - echo ''; \ - echo '-include $$(top_srcdir)/git.mk'; \ - } > $$x.tmp || failed=1; \ - if test x$$failed = x; then \ - mv $$x.tmp $$x || failed=1; \ - fi; \ - if test x$$failed = x; then : else \ - echo "Failed updating $$x"; >&2 \ - any_failed=1; \ - fi; \ - fi; done; test -z "$$any_failed" - -git-mk-update: - wget $(GIT_MK_URL) -O $(top_srcdir)/git.mk - -.PHONY: git-all git-mk-install git-mk-update - - - -############################################################################### -# Actual .gitignore generation: -############################################################################### - -$(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk - @echo "git.mk: Generating $@" - @{ \ - if test "x$(DOC_MODULE)" = x -o "x$(DOC_MAIN_SGML_FILE)" = x; then :; else \ - for x in \ - $(DOC_MODULE)-decl-list.txt \ - $(DOC_MODULE)-decl.txt \ - tmpl/$(DOC_MODULE)-unused.sgml \ - "tmpl/*.bak" \ - $(REPORT_FILES) \ - $(DOC_MODULE).pdf \ - xml html \ - ; do echo "/$$x"; done; \ - FLAVOR=$$(cd $(top_srcdir); $(AUTOCONF) --trace 'GTK_DOC_CHECK:$$2' ./configure.ac); \ - case $$FLAVOR in *no-tmpl*) echo /tmpl;; esac; \ - if echo "$(SCAN_OPTIONS)" | grep -q "\-\-rebuild-types"; then \ - echo "/$(DOC_MODULE).types"; \ - fi; \ - if echo "$(SCAN_OPTIONS)" | grep -q "\-\-rebuild-sections"; then \ - echo "/$(DOC_MODULE)-sections.txt"; \ - fi; \ - if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ - for x in \ - $(SETUP_FILES) \ - $(DOC_MODULE).types \ - ; do echo "/$$x"; done; \ - fi; \ - fi; \ - if test "x$(DOC_MODULE)$(DOC_ID)" = x -o "x$(DOC_LINGUAS)" = x; then :; else \ - for lc in $(DOC_LINGUAS); do \ - for x in \ - $(if $(DOC_MODULE),$(DOC_MODULE).xml) \ - $(DOC_PAGES) \ - $(DOC_INCLUDES) \ - ; do echo "/$$lc/$$x"; done; \ - done; \ - for x in \ - $(_DOC_OMF_ALL) \ - $(_DOC_DSK_ALL) \ - $(_DOC_HTML_ALL) \ - $(_DOC_MOFILES) \ - $(DOC_H_FILE) \ - "*/.xml2po.mo" \ - "*/*.omf.out" \ - ; do echo /$$x; done; \ - fi; \ - if test "x$(HELP_ID)" = x -o "x$(HELP_LINGUAS)" = x; then :; else \ - for lc in $(HELP_LINGUAS); do \ - for x in \ - $(HELP_FILES) \ - "$$lc.stamp" \ - "$$lc.mo" \ - ; do echo "/$$lc/$$x"; done; \ - done; \ - fi; \ - if test "x$(gsettings_SCHEMAS)" = x; then :; else \ - for x in \ - $(gsettings_SCHEMAS:.xml=.valid) \ - $(gsettings__enum_file) \ - ; do echo "/$$x"; done; \ - fi; \ - if test "x$(appdata_XML)" = x; then :; else \ - for x in \ - $(appdata_XML:.xml=.valid) \ - ; do echo "/$$x"; done; \ - fi; \ - if test "x$(appstream_XML)" = x; then :; else \ - for x in \ - $(appstream_XML:.xml=.valid) \ - ; do echo "/$$x"; done; \ - fi; \ - if test -f $(srcdir)/po/Makefile.in.in; then \ - for x in \ - po/Makefile.in.in \ - po/Makefile.in.in~ \ - po/Makefile.in \ - po/Makefile \ - po/Makevars.template \ - po/POTFILES \ - po/Rules-quot \ - po/stamp-it \ - po/stamp-po \ - po/.intltool-merge-cache \ - "po/*.gmo" \ - "po/*.header" \ - "po/*.mo" \ - "po/*.sed" \ - "po/*.sin" \ - po/$(GETTEXT_PACKAGE).pot \ - intltool-extract.in \ - intltool-merge.in \ - intltool-update.in \ - ; do echo "/$$x"; done; \ - fi; \ - if test -f $(srcdir)/configure; then \ - for x in \ - autom4te.cache \ - configure \ - config.h \ - stamp-h1 \ - libtool \ - config.lt \ - ; do echo "/$$x"; done; \ - fi; \ - if test "x$(DEJATOOL)" = x; then :; else \ - for x in \ - $(DEJATOOL) \ - ; do echo "/$$x.sum"; echo "/$$x.log"; done; \ - echo /site.exp; \ - fi; \ - if test "x$(am__dirstamp)" = x; then :; else \ - echo "$(am__dirstamp)"; \ - fi; \ - if test "x$(LTCOMPILE)" = x -a "x$(LTCXXCOMPILE)" = x -a "x$(GTKDOC_RUN)" = x; then :; else \ - for x in \ - "*.lo" \ - ".libs" "_libs" \ - ; do echo "$$x"; done; \ - fi; \ - for x in \ - .gitignore \ - $(GITIGNOREFILES) \ - $(CLEANFILES) \ - $(PROGRAMS) $(check_PROGRAMS) $(EXTRA_PROGRAMS) \ - $(LIBRARIES) $(check_LIBRARIES) $(EXTRA_LIBRARIES) \ - $(LTLIBRARIES) $(check_LTLIBRARIES) $(EXTRA_LTLIBRARIES) \ - so_locations \ - $(MOSTLYCLEANFILES) \ - $(TEST_LOGS) \ - $(TEST_LOGS:.log=.trs) \ - $(TEST_SUITE_LOG) \ - $(TESTS:=.test) \ - "*.gcda" \ - "*.gcno" \ - $(DISTCLEANFILES) \ - $(am__CONFIG_DISTCLEAN_FILES) \ - $(CONFIG_CLEAN_FILES) \ - TAGS ID GTAGS GRTAGS GSYMS GPATH tags \ - "*.tab.c" \ - $(MAINTAINERCLEANFILES) \ - $(BUILT_SOURCES) \ - $(patsubst %.vala,%.c,$(filter %.vala,$(SOURCES))) \ - $(filter %_vala.stamp,$(DIST_COMMON)) \ - $(filter %.vapi,$(DIST_COMMON)) \ - $(filter $(addprefix %,$(notdir $(patsubst %.vapi,%.h,$(filter %.vapi,$(DIST_COMMON))))),$(DIST_COMMON)) \ - Makefile \ - Makefile.in \ - "*.orig" \ - "*.rej" \ - "*.bak" \ - "*~" \ - ".*.sw[nop]" \ - ".dirstamp" \ - ; do echo "/$$x"; done; \ - for x in \ - "*.$(OBJEXT)" \ - $(DEPDIR) \ - ; do echo "$$x"; done; \ - } | \ - sed "s@^/`echo "$(srcdir)" | sed 's/\(.\)/[\1]/g'`/@/@" | \ - sed 's@/[.]/@/@g' | \ - LC_ALL=C sort | uniq > $@.tmp && \ - mv $@.tmp $@; - -all: $(srcdir)/.gitignore gitignore-recurse-maybe -gitignore: $(srcdir)/.gitignore gitignore-recurse - -gitignore-recurse-maybe: - @for subdir in $(DIST_SUBDIRS); do \ - case " $(SUBDIRS) " in \ - *" $$subdir "*) :;; \ - *) test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir");; \ - esac; \ - done -gitignore-recurse: - @for subdir in $(DIST_SUBDIRS); do \ - test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir"); \ - done - -maintainer-clean: gitignore-clean -gitignore-clean: - -rm -f $(srcdir)/.gitignore - -.PHONY: gitignore-clean gitignore gitignore-recurse gitignore-recurse-maybe diff --git a/external/bubblewrap/network.c b/external/bubblewrap/network.c deleted file mode 100644 index f5d131d..0000000 --- a/external/bubblewrap/network.c +++ /dev/null @@ -1,200 +0,0 @@ -/* bubblewrap - * Copyright (C) 2016 Alexander Larsson - * - * This program 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 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, see . - * - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include - -#include "utils.h" -#include "network.h" - -static void * -add_rta (struct nlmsghdr *header, - int type, - size_t size) -{ - struct rtattr *rta; - size_t rta_size = RTA_LENGTH (size); - - rta = (struct rtattr *) ((char *) header + NLMSG_ALIGN (header->nlmsg_len)); - rta->rta_type = type; - rta->rta_len = rta_size; - - header->nlmsg_len = NLMSG_ALIGN (header->nlmsg_len) + rta_size; - - return RTA_DATA (rta); -} - -static int -rtnl_send_request (int rtnl_fd, - struct nlmsghdr *header) -{ - struct sockaddr_nl dst_addr = { AF_NETLINK, 0 }; - ssize_t sent; - - sent = sendto (rtnl_fd, (void *) header, header->nlmsg_len, 0, - (struct sockaddr *) &dst_addr, sizeof (dst_addr)); - if (sent < 0) - return -1; - - return 0; -} - -static int -rtnl_read_reply (int rtnl_fd, - int seq_nr) -{ - char buffer[1024]; - ssize_t received; - struct nlmsghdr *rheader; - - while (1) - { - received = recv (rtnl_fd, buffer, sizeof (buffer), 0); - if (received < 0) - return -1; - - rheader = (struct nlmsghdr *) buffer; - while (received >= NLMSG_HDRLEN) - { - if (rheader->nlmsg_seq != seq_nr) - return -1; - if (rheader->nlmsg_pid != getpid ()) - return -1; - if (rheader->nlmsg_type == NLMSG_ERROR) - { - uint32_t *err = NLMSG_DATA (rheader); - if (*err == 0) - return 0; - - return -1; - } - if (rheader->nlmsg_type == NLMSG_DONE) - return 0; - - rheader = NLMSG_NEXT (rheader, received); - } - } -} - -static int -rtnl_do_request (int rtnl_fd, - struct nlmsghdr *header) -{ - if (rtnl_send_request (rtnl_fd, header) != 0) - return -1; - - if (rtnl_read_reply (rtnl_fd, header->nlmsg_seq) != 0) - return -1; - - return 0; -} - -static struct nlmsghdr * -rtnl_setup_request (char *buffer, - int type, - int flags, - size_t size) -{ - struct nlmsghdr *header; - size_t len = NLMSG_LENGTH (size); - static uint32_t counter = 0; - - memset (buffer, 0, len); - - header = (struct nlmsghdr *) buffer; - header->nlmsg_len = len; - header->nlmsg_type = type; - header->nlmsg_flags = flags | NLM_F_REQUEST; - header->nlmsg_seq = counter++; - header->nlmsg_pid = getpid (); - - return (struct nlmsghdr *) header; -} - -int -loopback_setup (void) -{ - int r, if_loopback; - cleanup_fd int rtnl_fd = -1; - char buffer[1024]; - struct sockaddr_nl src_addr = { AF_NETLINK, 0 }; - struct nlmsghdr *header; - struct ifaddrmsg *addmsg; - struct ifinfomsg *infomsg; - struct in_addr *ip_addr; - - src_addr.nl_pid = getpid (); - - if_loopback = (int) if_nametoindex ("lo"); - if (if_loopback <= 0) - return -1; - - rtnl_fd = socket (PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); - if (rtnl_fd < 0) - return -1; - - r = bind (rtnl_fd, (struct sockaddr *) &src_addr, sizeof (src_addr)); - if (r < 0) - return -1; - - header = rtnl_setup_request (buffer, RTM_NEWADDR, - NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK, - sizeof (struct ifaddrmsg)); - addmsg = NLMSG_DATA (header); - - addmsg->ifa_family = AF_INET; - addmsg->ifa_prefixlen = 8; - addmsg->ifa_flags = IFA_F_PERMANENT; - addmsg->ifa_scope = RT_SCOPE_HOST; - addmsg->ifa_index = if_loopback; - - ip_addr = add_rta (header, IFA_LOCAL, sizeof (*ip_addr)); - ip_addr->s_addr = htonl (INADDR_LOOPBACK); - - ip_addr = add_rta (header, IFA_ADDRESS, sizeof (*ip_addr)); - ip_addr->s_addr = htonl (INADDR_LOOPBACK); - - assert (header->nlmsg_len < sizeof (buffer)); - - if (rtnl_do_request (rtnl_fd, header) != 0) - return -1; - - header = rtnl_setup_request (buffer, RTM_NEWLINK, - NLM_F_ACK, - sizeof (struct ifinfomsg)); - infomsg = NLMSG_DATA (header); - - infomsg->ifi_family = AF_UNSPEC; - infomsg->ifi_type = 0; - infomsg->ifi_index = if_loopback; - infomsg->ifi_flags = IFF_UP; - infomsg->ifi_change = IFF_UP; - - assert (header->nlmsg_len < sizeof (buffer)); - - if (rtnl_do_request (rtnl_fd, header) != 0) - return -1; - - return 0; -} diff --git a/external/bubblewrap/network.h b/external/bubblewrap/network.h deleted file mode 100644 index d712d91..0000000 --- a/external/bubblewrap/network.h +++ /dev/null @@ -1,21 +0,0 @@ -/* bubblewrap - * Copyright (C) 2016 Alexander Larsson - * - * This program 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 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, see . - * - */ - -#pragma once - -int loopback_setup (void); diff --git a/external/bubblewrap/packaging/bubblewrap.spec b/external/bubblewrap/packaging/bubblewrap.spec deleted file mode 100644 index 1c3bb4a..0000000 --- a/external/bubblewrap/packaging/bubblewrap.spec +++ /dev/null @@ -1,49 +0,0 @@ -%global commit0 66d12bb23b04e201c5846e325f0b10930ed802f8 -%global shortcommit0 %(c=%{commit0}; echo ${c:0:7}) - -Summary: Core execution tool for unprivileged containers -Name: bubblewrap -Version: 0 -Release: 1%{?dist} -#VCS: git:https://github.com/projectatomic/bubblewrap -Source0: https://github.com/projectatomic/%{name}/archive/%{commit0}.tar.gz#/%{name}-%{shortcommit0}.tar.gz -License: LGPLv2+ -URL: https://github.com/projectatomic/bubblewrap - -BuildRequires: git -# We always run autogen.sh -BuildRequires: autoconf automake libtool -BuildRequires: libcap-devel -BuildRequires: pkgconfig(libselinux) -BuildRequires: libxslt -BuildRequires: docbook-style-xsl - -%description -Bubblewrap (/usr/bin/bwrap) is a core execution engine for unprivileged -containers that works as a setuid binary on kernels without -user namespaces. - -%prep -%autosetup -Sgit -n %{name}-%{version} - -%build -env NOCONFIGURE=1 ./autogen.sh -%configure --disable-silent-rules --with-priv-mode=none - -make %{?_smp_mflags} - -%install -make install DESTDIR=$RPM_BUILD_ROOT INSTALL="install -p -c" -find $RPM_BUILD_ROOT -name '*.la' -delete - -%files -%license COPYING -%doc README.md -%{_datadir}/bash-completion/completions/bwrap -%if (0%{?rhel} != 0 && 0%{?rhel} <= 7) -%attr(0755,root,root) %caps(cap_sys_admin,cap_net_admin,cap_sys_chroot=ep) %{_bindir}/bwrap -%else -%{_bindir}/bwrap -%endif -%{_mandir}/man1/* - diff --git a/external/bubblewrap/tests/test-basic.sh b/external/bubblewrap/tests/test-basic.sh deleted file mode 100755 index 7513933..0000000 --- a/external/bubblewrap/tests/test-basic.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -set -xeuo pipefail - -srcd=$(cd $(dirname $0) && pwd) -bn=$(basename $0) -tempdir=$(mktemp -d /var/tmp/tap-test.XXXXXX) -touch ${tempdir}/.testtmp -function cleanup () { - if test -n "${TEST_SKIP_CLEANUP:-}"; then - echo "Skipping cleanup of ${test_tmpdir}" - else if test -f ${tempdir}/.test; then - rm "${tempdir}" -rf - fi - fi -} -trap cleanup EXIT -cd ${tempdir} - -assert_not_reached () { - echo $@ 1>&2; exit 1 -} - -assert_file_has_content () { - if ! grep -q -e "$2" "$1"; then - echo 1>&2 "File '$1' doesn't match regexp '$2'"; exit 1 - fi -} - -# At the moment we're testing in Travis' container infrastructure -# which also uses PR_SET_NO_NEW_PRIVS...but let's at least -# verify --help works! -bwrap --help >out.txt 2>&1 -assert_file_has_content out.txt "--lock-file" - diff --git a/external/bubblewrap/uncrustify.cfg b/external/bubblewrap/uncrustify.cfg deleted file mode 100644 index 6d3ad56..0000000 --- a/external/bubblewrap/uncrustify.cfg +++ /dev/null @@ -1,136 +0,0 @@ -newlines lf - -input_tab_size 8 -output_tab_size 8 - -string_escape_char 92 -string_escape_char2 0 - -# indenting -indent_columns 2 -indent_with_tabs 0 -indent_align_string True -indent_brace 2 -indent_braces false -indent_braces_no_func True -indent_func_call_param false -indent_func_def_param false -indent_func_proto_param false -indent_switch_case 0 -indent_case_brace 2 -indent_paren_close 1 - -# spacing -sp_arith Add -sp_assign Add -sp_enum_assign Add -sp_bool Add -sp_compare Add -sp_inside_paren Remove -sp_inside_fparens Remove -sp_func_def_paren Force -sp_func_proto_paren Force -sp_paren_paren Remove -sp_balance_nested_parens False -sp_paren_brace Remove -sp_before_square Remove -sp_before_squares Remove -sp_inside_square Remove -sp_before_ptr_star Add -sp_between_ptr_star Remove -sp_after_comma Add -sp_before_comma Remove -sp_after_cast Add -sp_sizeof_paren Add -sp_not Remove -sp_inv Remove -sp_addr Remove -sp_member Remove -sp_deref Remove -sp_sign Remove -sp_incdec Remove -sp_attribute_paren remove -sp_macro Force -sp_func_call_paren Force -sp_func_call_user_paren Remove -set func_call_user _ N_ C_ g_autoptr g_auto -sp_brace_typedef add -sp_cond_colon add -sp_cond_question add -sp_defined_paren remove - -# alignment -align_keep_tabs False -align_with_tabs False -align_on_tabstop False -align_number_left True -align_func_params True -align_var_def_span 0 -align_var_def_amp_style 1 -align_var_def_colon true -align_enum_equ_span 0 -align_var_struct_span 2 -align_var_def_star_style 2 -align_var_def_amp_style 2 -align_typedef_span 2 -align_typedef_func 0 -align_typedef_star_style 2 -align_typedef_amp_style 2 - -# newlines -nl_assign_leave_one_liners True -nl_enum_leave_one_liners False -nl_func_leave_one_liners False -nl_if_leave_one_liners False -nl_end_of_file Add -nl_assign_brace Remove -nl_func_var_def_blk 1 -nl_fcall_brace Add -nl_enum_brace Remove -nl_struct_brace Force -nl_union_brace Force -nl_if_brace Force -nl_brace_else Force -nl_elseif_brace Force -nl_else_brace Add -nl_for_brace Force -nl_while_brace Force -nl_do_brace Force -nl_brace_while Force -nl_switch_brace Force -nl_before_case True -nl_after_case False -nl_func_type_name Force -nl_func_proto_type_name Remove -nl_func_paren Remove -nl_func_decl_start Remove -nl_func_decl_args Force -nl_func_decl_end Remove -nl_fdef_brace Force -nl_after_return False -nl_define_macro False -nl_create_if_one_liner False -nl_create_for_one_liner False -nl_create_while_one_liner False -nl_after_semicolon True -nl_multi_line_cond true - -# mod -# I'd like these to be remove, but that removes brackets in if { if { foo } }, which i dislike -# Not clear what to do about that... -mod_full_brace_for Remove -mod_full_brace_if Remove -mod_full_brace_if_chain True -mod_full_brace_while Remove -mod_full_brace_do Remove -mod_full_brace_nl 3 -mod_paren_on_return Remove - -# line splitting -#code_width = 78 -ls_for_split_full True -ls_func_split_full True - -# positioning -pos_bool Trail -pos_conditional Trail diff --git a/external/bubblewrap/uncrustify.sh b/external/bubblewrap/uncrustify.sh deleted file mode 100755 index 7c9080b..0000000 --- a/external/bubblewrap/uncrustify.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -uncrustify -c uncrustify.cfg --no-backup `git ls-tree --name-only -r HEAD | grep \\\.[ch]$` diff --git a/external/bubblewrap/utils.c b/external/bubblewrap/utils.c deleted file mode 100644 index acedfe8..0000000 --- a/external/bubblewrap/utils.c +++ /dev/null @@ -1,676 +0,0 @@ -/* bubblewrap - * Copyright (C) 2016 Alexander Larsson - * - * This program 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 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, see . - * - */ -#include "config.h" - -#include "utils.h" -#include -#ifdef HAVE_SELINUX -#include -#endif - -void -die_with_error (const char *format, ...) -{ - va_list args; - int errsv; - - errsv = errno; - - va_start (args, format); - vfprintf (stderr, format, args); - va_end (args); - - fprintf (stderr, ": %s\n", strerror (errsv)); - - exit (1); -} - -void -die (const char *format, ...) -{ - va_list args; - - va_start (args, format); - vfprintf (stderr, format, args); - va_end (args); - - fprintf (stderr, "\n"); - - exit (1); -} - -void -die_unless_label_valid (const char *label) -{ -#ifdef HAVE_SELINUX - if (is_selinux_enabled () == 1) - { - if (security_check_context ((security_context_t) label) < 0) - die_with_error ("invalid label %s", label); - return; - } -#endif - die ("labeling not supported on this system"); -} - -void -die_oom (void) -{ - puts ("Out of memory"); - exit (1); -} - -void * -xmalloc (size_t size) -{ - void *res = malloc (size); - - if (res == NULL) - die_oom (); - return res; -} - -void * -xcalloc (size_t size) -{ - void *res = calloc (1, size); - - if (res == NULL) - die_oom (); - return res; -} - -void * -xrealloc (void *ptr, size_t size) -{ - void *res = realloc (ptr, size); - - if (size != 0 && res == NULL) - die_oom (); - return res; -} - -char * -xstrdup (const char *str) -{ - char *res; - - assert (str != NULL); - - res = strdup (str); - if (res == NULL) - die_oom (); - - return res; -} - -void -strfreev (char **str_array) -{ - if (str_array) - { - int i; - - for (i = 0; str_array[i] != NULL; i++) - free (str_array[i]); - - free (str_array); - } -} - -/* Compares if str has a specific path prefix. This differs - from a regular prefix in two ways. First of all there may - be multiple slashes separating the path elements, and - secondly, if a prefix is matched that has to be en entire - path element. For instance /a/prefix matches /a/prefix/foo/bar, - but not /a/prefixfoo/bar. */ -bool -has_path_prefix (const char *str, - const char *prefix) -{ - while (TRUE) - { - /* Skip consecutive slashes to reach next path - element */ - while (*str == '/') - str++; - while (*prefix == '/') - prefix++; - - /* No more prefix path elements? Done! */ - if (*prefix == 0) - return TRUE; - - /* Compare path element */ - while (*prefix != 0 && *prefix != '/') - { - if (*str != *prefix) - return FALSE; - str++; - prefix++; - } - - /* Matched prefix path element, - must be entire str path element */ - if (*str != '/' && *str != 0) - return FALSE; - } -} - -bool -has_prefix (const char *str, - const char *prefix) -{ - return strncmp (str, prefix, strlen (prefix)) == 0; -} - -void -xsetenv (const char *name, const char *value, int overwrite) -{ - if (setenv (name, value, overwrite)) - die ("setenv failed"); -} - -void -xunsetenv (const char *name) -{ - if (unsetenv (name)) - die ("unsetenv failed"); -} - -char * -strconcat (const char *s1, - const char *s2) -{ - size_t len = 0; - char *res; - - if (s1) - len += strlen (s1); - if (s2) - len += strlen (s2); - - res = xmalloc (len + 1); - *res = 0; - if (s1) - strcat (res, s1); - if (s2) - strcat (res, s2); - - return res; -} - -char * -strconcat3 (const char *s1, - const char *s2, - const char *s3) -{ - size_t len = 0; - char *res; - - if (s1) - len += strlen (s1); - if (s2) - len += strlen (s2); - if (s3) - len += strlen (s3); - - res = xmalloc (len + 1); - *res = 0; - if (s1) - strcat (res, s1); - if (s2) - strcat (res, s2); - if (s3) - strcat (res, s3); - - return res; -} - -char * -xasprintf (const char *format, - ...) -{ - char *buffer = NULL; - va_list args; - - va_start (args, format); - if (vasprintf (&buffer, format, args) == -1) - die_oom (); - va_end (args); - - return buffer; -} - -int -fdwalk (int proc_fd, int (*cb)(void *data, - int fd), void *data) -{ - int open_max; - int fd; - int dfd; - int res = 0; - DIR *d; - - dfd = openat (proc_fd, "self/fd", O_DIRECTORY | O_RDONLY | O_NONBLOCK | O_CLOEXEC | O_NOCTTY); - if (dfd == -1) - return res; - - if ((d = fdopendir (dfd))) - { - struct dirent *de; - - while ((de = readdir (d))) - { - long l; - char *e = NULL; - - if (de->d_name[0] == '.') - continue; - - errno = 0; - l = strtol (de->d_name, &e, 10); - if (errno != 0 || !e || *e) - continue; - - fd = (int) l; - - if ((long) fd != l) - continue; - - if (fd == dirfd (d)) - continue; - - if ((res = cb (data, fd)) != 0) - break; - } - - closedir (d); - return res; - } - - open_max = sysconf (_SC_OPEN_MAX); - - for (fd = 0; fd < open_max; fd++) - if ((res = cb (data, fd)) != 0) - break; - - return res; -} - -/* Sets errno on error (!= 0), ENOSPC on short write */ -int -write_to_fd (int fd, - const char *content, - ssize_t len) -{ - ssize_t res; - - while (len > 0) - { - res = write (fd, content, len); - if (res < 0 && errno == EINTR) - continue; - if (res <= 0) - { - if (res == 0) /* Unexpected short write, should not happen when writing to a file */ - errno = ENOSPC; - return -1; - } - len -= res; - content += res; - } - - return 0; -} - -/* Sets errno on error (!= 0), ENOSPC on short write */ -int -write_file_at (int dirfd, - const char *path, - const char *content) -{ - int fd; - bool res; - int errsv; - - fd = openat (dirfd, path, O_RDWR | O_CLOEXEC, 0); - if (fd == -1) - return -1; - - res = 0; - if (content) - res = write_to_fd (fd, content, strlen (content)); - - errsv = errno; - close (fd); - errno = errsv; - - return res; -} - -/* Sets errno on error (!= 0), ENOSPC on short write */ -int -create_file (const char *path, - mode_t mode, - const char *content) -{ - int fd; - int res; - int errsv; - - fd = creat (path, mode); - if (fd == -1) - return -1; - - res = 0; - if (content) - res = write_to_fd (fd, content, strlen (content)); - - errsv = errno; - close (fd); - errno = errsv; - - return res; -} - -int -ensure_file (const char *path, - mode_t mode) -{ - struct stat buf; - - /* We check this ahead of time, otherwise - the create file will fail in the read-only - case with EROFD instead of EEXIST */ - if (stat (path, &buf) == 0 && - S_ISREG (buf.st_mode)) - return 0; - - if (create_file (path, mode, NULL) != 0 && errno != EEXIST) - return -1; - - return 0; -} - - -#define BUFSIZE 8192 -/* Sets errno on error (!= 0), ENOSPC on short write */ -int -copy_file_data (int sfd, - int dfd) -{ - char buffer[BUFSIZE]; - ssize_t bytes_read; - - while (TRUE) - { - bytes_read = read (sfd, buffer, BUFSIZE); - if (bytes_read == -1) - { - if (errno == EINTR) - continue; - - return -1; - } - - if (bytes_read == 0) - break; - - if (write_to_fd (dfd, buffer, bytes_read) != 0) - return -1; - } - - return 0; -} - -/* Sets errno on error (!= 0), ENOSPC on short write */ -int -copy_file (const char *src_path, - const char *dst_path, - mode_t mode) -{ - int sfd; - int dfd; - int res; - int errsv; - - sfd = open (src_path, O_CLOEXEC | O_RDONLY); - if (sfd == -1) - return -1; - - dfd = creat (dst_path, mode); - if (dfd == -1) - { - errsv = errno; - close (sfd); - errno = errsv; - return -1; - } - - res = copy_file_data (sfd, dfd); - - errsv = errno; - close (sfd); - close (dfd); - errno = errsv; - - return res; -} - -/* Sets errno on error (== NULL), - * Always ensures terminating zero */ -char * -load_file_data (int fd, - size_t *size) -{ - cleanup_free char *data = NULL; - ssize_t data_read; - ssize_t data_len; - ssize_t res; - int errsv; - - data_read = 0; - data_len = 4080; - data = xmalloc (data_len); - - do - { - if (data_len == data_read + 1) - { - data_len *= 2; - data = xrealloc (data, data_len); - } - - do - res = read (fd, data + data_read, data_len - data_read - 1); - while (res < 0 && errno == EINTR); - - if (res < 0) - { - errsv = errno; - close (fd); - errno = errsv; - return NULL; - } - - data_read += res; - } - while (res > 0); - - data[data_read] = 0; - - if (size) - *size = (size_t) data_read; - - return steal_pointer (&data); -} - -/* Sets errno on error (== NULL), - * Always ensures terminating zero */ -char * -load_file_at (int dirfd, - const char *path) -{ - int fd; - char *data; - int errsv; - - fd = openat (dirfd, path, O_CLOEXEC | O_RDONLY); - if (fd == -1) - return NULL; - - data = load_file_data (fd, NULL); - - errsv = errno; - close (fd); - errno = errsv; - - return data; -} - -/* Sets errno on error (< 0) */ -int -get_file_mode (const char *pathname) -{ - struct stat buf; - - if (stat (pathname, &buf) != 0) - return -1; - - return buf.st_mode & S_IFMT; -} - -/* Sets errno on error (!= 0) */ -int -mkdir_with_parents (const char *pathname, - int mode, - bool create_last) -{ - cleanup_free char *fn = NULL; - char *p; - struct stat buf; - - if (pathname == NULL || *pathname == '\0') - { - errno = EINVAL; - return -1; - } - - fn = xstrdup (pathname); - - p = fn; - while (*p == '/') - p++; - - do - { - while (*p && *p != '/') - p++; - - if (!*p) - p = NULL; - else - *p = '\0'; - - if (!create_last && p == NULL) - break; - - if (stat (fn, &buf) != 0) - { - if (mkdir (fn, mode) == -1 && errno != EEXIST) - return -1; - } - else if (!S_ISDIR (buf.st_mode)) - { - errno = ENOTDIR; - return -1; - } - - if (p) - { - *p++ = '/'; - while (*p && *p == '/') - p++; - } - } - while (p); - - return 0; -} - -int -raw_clone (unsigned long flags, - void *child_stack) -{ -#if defined(__s390__) || defined(__CRIS__) - /* On s390 and cris the order of the first and second arguments - * of the raw clone() system call is reversed. */ - return (int) syscall (__NR_clone, child_stack, flags); -#else - return (int) syscall (__NR_clone, flags, child_stack); -#endif -} - -int -pivot_root (const char * new_root, const char * put_old) -{ -#ifdef __NR_pivot_root - return syscall (__NR_pivot_root, new_root, put_old); -#else - errno = ENOSYS; - return -1; -#endif -} - -char * -label_mount (const char *opt, const char *mount_label) -{ -#ifdef HAVE_SELINUX - if (mount_label) - { - if (opt) - return xasprintf ("%s,context=\"%s\"", opt, mount_label); - else - return xasprintf ("context=\"%s\"", mount_label); - } -#endif - if (opt) - return xstrdup (opt); - return NULL; -} - -int -label_create_file (const char *file_label) -{ -#ifdef HAVE_SELINUX - if (is_selinux_enabled () > 0 && file_label) - return setfscreatecon ((security_context_t) file_label); -#endif - return 0; -} - -int -label_exec (const char *exec_label) -{ -#ifdef HAVE_SELINUX - if (is_selinux_enabled () > 0 && exec_label) - return setexeccon ((security_context_t) exec_label); -#endif - return 0; -} diff --git a/external/bubblewrap/utils.h b/external/bubblewrap/utils.h deleted file mode 100644 index 8ec86bd..0000000 --- a/external/bubblewrap/utils.h +++ /dev/null @@ -1,164 +0,0 @@ -/* bubblewrap - * Copyright (C) 2016 Alexander Larsson - * - * This program 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 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, see . - * - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if 1 -#define __debug__(x) printf x -#else -#define __debug__(x) -#endif - -#define UNUSED __attribute__((__unused__)) - -#define N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0])) - -#define TRUE 1 -#define FALSE 0 -typedef int bool; - -#define PIPE_READ_END 0 -#define PIPE_WRITE_END 1 - -void die_with_error (const char *format, - ...) __attribute__((__noreturn__)) __attribute__((format (printf, 1, 2))); -void die (const char *format, - ...) __attribute__((__noreturn__)); -void die_oom (void) __attribute__((__noreturn__)); -void die_unless_label_valid (const char *label); - -void *xmalloc (size_t size); -void *xcalloc (size_t size); -void *xrealloc (void *ptr, - size_t size); -char *xstrdup (const char *str); -void strfreev (char **str_array); -void xsetenv (const char *name, - const char *value, - int overwrite); -void xunsetenv (const char *name); -char *strconcat (const char *s1, - const char *s2); -char *strconcat3 (const char *s1, - const char *s2, - const char *s3); -char * xasprintf (const char *format, - ...) __attribute__((format (printf, 1, 2))); -bool has_prefix (const char *str, - const char *prefix); -bool has_path_prefix (const char *str, - const char *prefix); -int fdwalk (int proc_fd, - int (*cb)(void *data, - int fd), - void *data); -char *load_file_data (int fd, - size_t *size); -char *load_file_at (int dirfd, - const char *path); -int write_file_at (int dirfd, - const char *path, - const char *content); -int write_to_fd (int fd, - const char *content, - ssize_t len); -int copy_file_data (int sfd, - int dfd); -int copy_file (const char *src_path, - const char *dst_path, - mode_t mode); -int create_file (const char *path, - mode_t mode, - const char *content); -int ensure_file (const char *path, - mode_t mode); -int get_file_mode (const char *pathname); -int mkdir_with_parents (const char *pathname, - int mode, - bool create_last); - -/* syscall wrappers */ -int raw_clone (unsigned long flags, - void *child_stack); -int pivot_root (const char *new_root, - const char *put_old); -char *label_mount (const char *opt, - const char *mount_label); -int label_exec (const char *exec_label); -int label_create_file (const char *file_label); - -static inline void -cleanup_freep (void *p) -{ - void **pp = (void **) p; - - if (*pp) - free (*pp); -} - -static inline void -cleanup_strvp (void *p) -{ - void **pp = (void **) p; - - strfreev (*pp); -} - -static inline void -cleanup_fdp (int *fdp) -{ - int fd; - - assert (fdp); - - fd = *fdp; - if (fd != -1) - (void) close (fd); -} - -#define cleanup_free __attribute__((cleanup (cleanup_freep))) -#define cleanup_fd __attribute__((cleanup (cleanup_fdp))) -#define cleanup_strv __attribute__((cleanup (cleanup_strvp))) - -static inline void * -steal_pointer (void *pp) -{ - void **ptr = (void **) pp; - void *ref; - - ref = *ptr; - *ptr = NULL; - - return ref; -} - -/* type safety */ -#define steal_pointer(pp) \ - (0 ? (*(pp)) : (steal_pointer) (pp)) diff --git a/external/jni/JNIHelp.h b/external/jni/JNIHelp.h deleted file mode 100644 index bf01986..0000000 --- a/external/jni/JNIHelp.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * JNI helper functions. - * - * This file may be included by C or C++ code, which is trouble because jni.h - * uses different typedefs for JNIEnv in each language. - * - * TODO: remove C support. - */ -#ifndef NATIVEHELPER_JNIHELP_H_ -#define NATIVEHELPER_JNIHELP_H_ - -#include "jni.h" -#include -#include - -#ifndef NELEM -# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Register one or more native methods with a particular class. - * "className" looks like "java/lang/String". Aborts on failure. - * TODO: fix all callers and change the return type to void. - */ -int jniRegisterNativeMethods(C_JNIEnv* env, const char* className, const JNINativeMethod* gMethods, int numMethods); - -/* - * Throw an exception with the specified class and an optional message. - * - * The "className" argument will be passed directly to FindClass, which - * takes strings with slashes (e.g. "java/lang/Object"). - * - * If an exception is currently pending, we log a warning message and - * clear it. - * - * Returns 0 on success, nonzero if something failed (e.g. the exception - * class couldn't be found, so *an* exception will still be pending). - * - * Currently aborts the VM if it can't throw the exception. - */ -int jniThrowException(C_JNIEnv* env, const char* className, const char* msg); - -/* - * Throw a java.lang.NullPointerException, with an optional message. - */ -int jniThrowNullPointerException(C_JNIEnv* env, const char* msg); - -/* - * Throw a java.lang.RuntimeException, with an optional message. - */ -int jniThrowRuntimeException(C_JNIEnv* env, const char* msg); - -/* - * Throw a java.io.IOException, generating the message from errno. - */ -int jniThrowIOException(C_JNIEnv* env, int errnum); - -/* - * Return a pointer to a locale-dependent error string explaining errno - * value 'errnum'. The returned pointer may or may not be equal to 'buf'. - * This function is thread-safe (unlike strerror) and portable (unlike - * strerror_r). - */ -const char* jniStrError(int errnum, char* buf, size_t buflen); - -/* - * Returns a new java.io.FileDescriptor for the given int fd. - */ -jobject jniCreateFileDescriptor(C_JNIEnv* env, int fd); - -/* - * Returns the int fd from a java.io.FileDescriptor. - */ -int jniGetFDFromFileDescriptor(C_JNIEnv* env, jobject fileDescriptor); - -/* - * Sets the int fd in a java.io.FileDescriptor. - */ -void jniSetFileDescriptorOfFD(C_JNIEnv* env, jobject fileDescriptor, int value); - -/* - * Returns the reference from a java.lang.ref.Reference. - */ -jobject jniGetReferent(C_JNIEnv* env, jobject ref); - -/* - * Log a message and an exception. - * If exception is NULL, logs the current exception in the JNI environment. - */ -void jniLogException(C_JNIEnv* env, int priority, const char* tag, jthrowable exception); - -#ifdef __cplusplus -} -#endif - - -/* - * For C++ code, we provide inlines that map to the C functions. g++ always - * inlines these, even on non-optimized builds. - */ -#if defined(__cplusplus) -inline int jniRegisterNativeMethods(JNIEnv* env, const char* className, const JNINativeMethod* gMethods, int numMethods) { - return jniRegisterNativeMethods(&env->functions, className, gMethods, numMethods); -} - -inline int jniThrowException(JNIEnv* env, const char* className, const char* msg) { - return jniThrowException(&env->functions, className, msg); -} - -extern "C" int jniThrowExceptionFmt(C_JNIEnv* env, const char* className, const char* fmt, va_list args); - -/* - * Equivalent to jniThrowException but with a printf-like format string and - * variable-length argument list. This is only available in C++. - */ -inline int jniThrowExceptionFmt(JNIEnv* env, const char* className, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - return jniThrowExceptionFmt(&env->functions, className, fmt, args); - va_end(args); -} - -inline int jniThrowNullPointerException(JNIEnv* env, const char* msg) { - return jniThrowNullPointerException(&env->functions, msg); -} - -inline int jniThrowRuntimeException(JNIEnv* env, const char* msg) { - return jniThrowRuntimeException(&env->functions, msg); -} - -inline int jniThrowIOException(JNIEnv* env, int errnum) { - return jniThrowIOException(&env->functions, errnum); -} - -inline jobject jniCreateFileDescriptor(JNIEnv* env, int fd) { - return jniCreateFileDescriptor(&env->functions, fd); -} - -inline int jniGetFDFromFileDescriptor(JNIEnv* env, jobject fileDescriptor) { - return jniGetFDFromFileDescriptor(&env->functions, fileDescriptor); -} - -inline void jniSetFileDescriptorOfFD(JNIEnv* env, jobject fileDescriptor, int value) { - jniSetFileDescriptorOfFD(&env->functions, fileDescriptor, value); -} - -inline jobject jniGetReferent(JNIEnv* env, jobject ref) { - return jniGetReferent(&env->functions, ref); -} - -inline void jniLogException(JNIEnv* env, int priority, const char* tag, jthrowable exception = NULL) { - jniLogException(&env->functions, priority, tag, exception); -} - -#if !defined(DISALLOW_COPY_AND_ASSIGN) -// DISALLOW_COPY_AND_ASSIGN disallows the copy and operator= functions. It goes in the private: -// declarations in a class. -#if __cplusplus >= 201103L -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&) = delete; \ - void operator=(const TypeName&) = delete -#else -#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) -#endif // __has_feature(cxx_deleted_functions) -#endif // !defined(DISALLOW_COPY_AND_ASSIGN) - -#endif - -/* - * TEMP_FAILURE_RETRY is defined by some, but not all, versions of - * . (Alas, it is not as standard as we'd hoped!) So, if it's - * not already defined, then define it here. - */ -#ifndef TEMP_FAILURE_RETRY -/* Used to retry syscalls that can return EINTR. */ -#define TEMP_FAILURE_RETRY(exp) ({ \ - typeof (exp) _rc; \ - do { \ - _rc = (exp); \ - } while (_rc == -1 && errno == EINTR); \ - _rc; }) -#endif - -#endif /* NATIVEHELPER_JNIHELP_H_ */ diff --git a/external/jni/README.md b/external/jni/README.md deleted file mode 100644 index e567b98..0000000 --- a/external/jni/README.md +++ /dev/null @@ -1 +0,0 @@ -Taken from https://android.googlesource.com/platform/libnativehelper/ diff --git a/external/jni/jni.h b/external/jni/jni.h deleted file mode 100644 index 1c2fb0c..0000000 --- a/external/jni/jni.h +++ /dev/null @@ -1,1141 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * JNI specification, as defined by Sun: - * http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html - * - * Everything here is expected to be VM-neutral. - */ - -#ifndef JNI_H_ -#define JNI_H_ - -#include -#include - -/* Primitive types that match up with Java equivalents. */ -typedef uint8_t jboolean; /* unsigned 8 bits */ -typedef int8_t jbyte; /* signed 8 bits */ -typedef uint16_t jchar; /* unsigned 16 bits */ -typedef int16_t jshort; /* signed 16 bits */ -typedef int32_t jint; /* signed 32 bits */ -typedef int64_t jlong; /* signed 64 bits */ -typedef float jfloat; /* 32-bit IEEE 754 */ -typedef double jdouble; /* 64-bit IEEE 754 */ - -/* "cardinal indices and sizes" */ -typedef jint jsize; - -#ifdef __cplusplus -/* - * Reference types, in C++ - */ -class _jobject {}; -class _jclass : public _jobject {}; -class _jstring : public _jobject {}; -class _jarray : public _jobject {}; -class _jobjectArray : public _jarray {}; -class _jbooleanArray : public _jarray {}; -class _jbyteArray : public _jarray {}; -class _jcharArray : public _jarray {}; -class _jshortArray : public _jarray {}; -class _jintArray : public _jarray {}; -class _jlongArray : public _jarray {}; -class _jfloatArray : public _jarray {}; -class _jdoubleArray : public _jarray {}; -class _jthrowable : public _jobject {}; - -typedef _jobject* jobject; -typedef _jclass* jclass; -typedef _jstring* jstring; -typedef _jarray* jarray; -typedef _jobjectArray* jobjectArray; -typedef _jbooleanArray* jbooleanArray; -typedef _jbyteArray* jbyteArray; -typedef _jcharArray* jcharArray; -typedef _jshortArray* jshortArray; -typedef _jintArray* jintArray; -typedef _jlongArray* jlongArray; -typedef _jfloatArray* jfloatArray; -typedef _jdoubleArray* jdoubleArray; -typedef _jthrowable* jthrowable; -typedef _jobject* jweak; - - -#else /* not __cplusplus */ - -/* - * Reference types, in C. - */ -typedef void* jobject; -typedef jobject jclass; -typedef jobject jstring; -typedef jobject jarray; -typedef jarray jobjectArray; -typedef jarray jbooleanArray; -typedef jarray jbyteArray; -typedef jarray jcharArray; -typedef jarray jshortArray; -typedef jarray jintArray; -typedef jarray jlongArray; -typedef jarray jfloatArray; -typedef jarray jdoubleArray; -typedef jobject jthrowable; -typedef jobject jweak; - -#endif /* not __cplusplus */ - -struct _jfieldID; /* opaque structure */ -typedef struct _jfieldID* jfieldID; /* field IDs */ - -struct _jmethodID; /* opaque structure */ -typedef struct _jmethodID* jmethodID; /* method IDs */ - -struct JNIInvokeInterface; - -typedef union jvalue { - jboolean z; - jbyte b; - jchar c; - jshort s; - jint i; - jlong j; - jfloat f; - jdouble d; - jobject l; -} jvalue; - -typedef enum jobjectRefType { - JNIInvalidRefType = 0, - JNILocalRefType = 1, - JNIGlobalRefType = 2, - JNIWeakGlobalRefType = 3 -} jobjectRefType; - -typedef struct { - const char* name; - const char* signature; - void* fnPtr; -} JNINativeMethod; - -struct _JNIEnv; -struct _JavaVM; -typedef const struct JNINativeInterface* C_JNIEnv; - -#if defined(__cplusplus) -typedef _JNIEnv JNIEnv; -typedef _JavaVM JavaVM; -#else -typedef const struct JNINativeInterface* JNIEnv; -typedef const struct JNIInvokeInterface* JavaVM; -#endif - -/* - * Table of interface function pointers. - */ -struct JNINativeInterface { - void* reserved0; - void* reserved1; - void* reserved2; - void* reserved3; - - jint (*GetVersion)(JNIEnv *); - - jclass (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*, - jsize); - jclass (*FindClass)(JNIEnv*, const char*); - - jmethodID (*FromReflectedMethod)(JNIEnv*, jobject); - jfieldID (*FromReflectedField)(JNIEnv*, jobject); - /* spec doesn't show jboolean parameter */ - jobject (*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean); - - jclass (*GetSuperclass)(JNIEnv*, jclass); - jboolean (*IsAssignableFrom)(JNIEnv*, jclass, jclass); - - /* spec doesn't show jboolean parameter */ - jobject (*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean); - - jint (*Throw)(JNIEnv*, jthrowable); - jint (*ThrowNew)(JNIEnv *, jclass, const char *); - jthrowable (*ExceptionOccurred)(JNIEnv*); - void (*ExceptionDescribe)(JNIEnv*); - void (*ExceptionClear)(JNIEnv*); - void (*FatalError)(JNIEnv*, const char*); - - jint (*PushLocalFrame)(JNIEnv*, jint); - jobject (*PopLocalFrame)(JNIEnv*, jobject); - - jobject (*NewGlobalRef)(JNIEnv*, jobject); - void (*DeleteGlobalRef)(JNIEnv*, jobject); - void (*DeleteLocalRef)(JNIEnv*, jobject); - jboolean (*IsSameObject)(JNIEnv*, jobject, jobject); - - jobject (*NewLocalRef)(JNIEnv*, jobject); - jint (*EnsureLocalCapacity)(JNIEnv*, jint); - - jobject (*AllocObject)(JNIEnv*, jclass); - jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...); - jobject (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list); - jobject (*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*); - - jclass (*GetObjectClass)(JNIEnv*, jobject); - jboolean (*IsInstanceOf)(JNIEnv*, jobject, jclass); - jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*); - - jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...); - jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list); - jobject (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); - jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...); - jboolean (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list); - jboolean (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); - jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...); - jbyte (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list); - jbyte (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); - jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...); - jchar (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list); - jchar (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); - jshort (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...); - jshort (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list); - jshort (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); - jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...); - jint (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list); - jint (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); - jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...); - jlong (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list); - jlong (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); - jfloat (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...); - jfloat (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list); - jfloat (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); - jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...); - jdouble (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list); - jdouble (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); - void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...); - void (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list); - void (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*); - - jobject (*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass, - jmethodID, ...); - jobject (*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass, - jmethodID, va_list); - jobject (*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass, - jmethodID, jvalue*); - jboolean (*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass, - jmethodID, ...); - jboolean (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass, - jmethodID, va_list); - jboolean (*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass, - jmethodID, jvalue*); - jbyte (*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass, - jmethodID, ...); - jbyte (*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass, - jmethodID, va_list); - jbyte (*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass, - jmethodID, jvalue*); - jchar (*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass, - jmethodID, ...); - jchar (*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass, - jmethodID, va_list); - jchar (*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass, - jmethodID, jvalue*); - jshort (*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass, - jmethodID, ...); - jshort (*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass, - jmethodID, va_list); - jshort (*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass, - jmethodID, jvalue*); - jint (*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass, - jmethodID, ...); - jint (*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass, - jmethodID, va_list); - jint (*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass, - jmethodID, jvalue*); - jlong (*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass, - jmethodID, ...); - jlong (*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass, - jmethodID, va_list); - jlong (*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass, - jmethodID, jvalue*); - jfloat (*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass, - jmethodID, ...); - jfloat (*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass, - jmethodID, va_list); - jfloat (*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass, - jmethodID, jvalue*); - jdouble (*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass, - jmethodID, ...); - jdouble (*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass, - jmethodID, va_list); - jdouble (*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass, - jmethodID, jvalue*); - void (*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass, - jmethodID, ...); - void (*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass, - jmethodID, va_list); - void (*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass, - jmethodID, jvalue*); - - jfieldID (*GetFieldID)(JNIEnv*, jclass, const char*, const char*); - - jobject (*GetObjectField)(JNIEnv*, jobject, jfieldID); - jboolean (*GetBooleanField)(JNIEnv*, jobject, jfieldID); - jbyte (*GetByteField)(JNIEnv*, jobject, jfieldID); - jchar (*GetCharField)(JNIEnv*, jobject, jfieldID); - jshort (*GetShortField)(JNIEnv*, jobject, jfieldID); - jint (*GetIntField)(JNIEnv*, jobject, jfieldID); - jlong (*GetLongField)(JNIEnv*, jobject, jfieldID); - jfloat (*GetFloatField)(JNIEnv*, jobject, jfieldID); - jdouble (*GetDoubleField)(JNIEnv*, jobject, jfieldID); - - void (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject); - void (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean); - void (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte); - void (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar); - void (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort); - void (*SetIntField)(JNIEnv*, jobject, jfieldID, jint); - void (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong); - void (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat); - void (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble); - - jmethodID (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*); - - jobject (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...); - jobject (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list); - jobject (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); - jboolean (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...); - jboolean (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID, - va_list); - jboolean (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID, - jvalue*); - jbyte (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...); - jbyte (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list); - jbyte (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); - jchar (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...); - jchar (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list); - jchar (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); - jshort (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...); - jshort (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list); - jshort (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); - jint (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...); - jint (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list); - jint (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); - jlong (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...); - jlong (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list); - jlong (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); - jfloat (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...); - jfloat (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list); - jfloat (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); - jdouble (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...); - jdouble (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list); - jdouble (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); - void (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...); - void (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list); - void (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*); - - jfieldID (*GetStaticFieldID)(JNIEnv*, jclass, const char*, - const char*); - - jobject (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID); - jboolean (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID); - jbyte (*GetStaticByteField)(JNIEnv*, jclass, jfieldID); - jchar (*GetStaticCharField)(JNIEnv*, jclass, jfieldID); - jshort (*GetStaticShortField)(JNIEnv*, jclass, jfieldID); - jint (*GetStaticIntField)(JNIEnv*, jclass, jfieldID); - jlong (*GetStaticLongField)(JNIEnv*, jclass, jfieldID); - jfloat (*GetStaticFloatField)(JNIEnv*, jclass, jfieldID); - jdouble (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID); - - void (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject); - void (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean); - void (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte); - void (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar); - void (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort); - void (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint); - void (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong); - void (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat); - void (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble); - - jstring (*NewString)(JNIEnv*, const jchar*, jsize); - jsize (*GetStringLength)(JNIEnv*, jstring); - const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*); - void (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*); - jstring (*NewStringUTF)(JNIEnv*, const char*); - jsize (*GetStringUTFLength)(JNIEnv*, jstring); - /* JNI spec says this returns const jbyte*, but that's inconsistent */ - const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*); - void (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*); - jsize (*GetArrayLength)(JNIEnv*, jarray); - jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject); - jobject (*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize); - void (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject); - - jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize); - jbyteArray (*NewByteArray)(JNIEnv*, jsize); - jcharArray (*NewCharArray)(JNIEnv*, jsize); - jshortArray (*NewShortArray)(JNIEnv*, jsize); - jintArray (*NewIntArray)(JNIEnv*, jsize); - jlongArray (*NewLongArray)(JNIEnv*, jsize); - jfloatArray (*NewFloatArray)(JNIEnv*, jsize); - jdoubleArray (*NewDoubleArray)(JNIEnv*, jsize); - - jboolean* (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*); - jbyte* (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*); - jchar* (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*); - jshort* (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*); - jint* (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*); - jlong* (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*); - jfloat* (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*); - jdouble* (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*); - - void (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray, - jboolean*, jint); - void (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray, - jbyte*, jint); - void (*ReleaseCharArrayElements)(JNIEnv*, jcharArray, - jchar*, jint); - void (*ReleaseShortArrayElements)(JNIEnv*, jshortArray, - jshort*, jint); - void (*ReleaseIntArrayElements)(JNIEnv*, jintArray, - jint*, jint); - void (*ReleaseLongArrayElements)(JNIEnv*, jlongArray, - jlong*, jint); - void (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray, - jfloat*, jint); - void (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray, - jdouble*, jint); - - void (*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray, - jsize, jsize, jboolean*); - void (*GetByteArrayRegion)(JNIEnv*, jbyteArray, - jsize, jsize, jbyte*); - void (*GetCharArrayRegion)(JNIEnv*, jcharArray, - jsize, jsize, jchar*); - void (*GetShortArrayRegion)(JNIEnv*, jshortArray, - jsize, jsize, jshort*); - void (*GetIntArrayRegion)(JNIEnv*, jintArray, - jsize, jsize, jint*); - void (*GetLongArrayRegion)(JNIEnv*, jlongArray, - jsize, jsize, jlong*); - void (*GetFloatArrayRegion)(JNIEnv*, jfloatArray, - jsize, jsize, jfloat*); - void (*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray, - jsize, jsize, jdouble*); - - /* spec shows these without const; some jni.h do, some don't */ - void (*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray, - jsize, jsize, const jboolean*); - void (*SetByteArrayRegion)(JNIEnv*, jbyteArray, - jsize, jsize, const jbyte*); - void (*SetCharArrayRegion)(JNIEnv*, jcharArray, - jsize, jsize, const jchar*); - void (*SetShortArrayRegion)(JNIEnv*, jshortArray, - jsize, jsize, const jshort*); - void (*SetIntArrayRegion)(JNIEnv*, jintArray, - jsize, jsize, const jint*); - void (*SetLongArrayRegion)(JNIEnv*, jlongArray, - jsize, jsize, const jlong*); - void (*SetFloatArrayRegion)(JNIEnv*, jfloatArray, - jsize, jsize, const jfloat*); - void (*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray, - jsize, jsize, const jdouble*); - - jint (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*, - jint); - jint (*UnregisterNatives)(JNIEnv*, jclass); - jint (*MonitorEnter)(JNIEnv*, jobject); - jint (*MonitorExit)(JNIEnv*, jobject); - jint (*GetJavaVM)(JNIEnv*, JavaVM**); - - void (*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*); - void (*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*); - - void* (*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*); - void (*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint); - - const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*); - void (*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*); - - jweak (*NewWeakGlobalRef)(JNIEnv*, jobject); - void (*DeleteWeakGlobalRef)(JNIEnv*, jweak); - - jboolean (*ExceptionCheck)(JNIEnv*); - - jobject (*NewDirectByteBuffer)(JNIEnv*, void*, jlong); - void* (*GetDirectBufferAddress)(JNIEnv*, jobject); - jlong (*GetDirectBufferCapacity)(JNIEnv*, jobject); - - /* added in JNI 1.6 */ - jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject); -}; - -/* - * C++ object wrapper. - * - * This is usually overlaid on a C struct whose first element is a - * JNINativeInterface*. We rely somewhat on compiler behavior. - */ -struct _JNIEnv { - /* do not rename this; it does not seem to be entirely opaque */ - const struct JNINativeInterface* functions; - -#if defined(__cplusplus) - - jint GetVersion() - { return functions->GetVersion(this); } - - jclass DefineClass(const char *name, jobject loader, const jbyte* buf, - jsize bufLen) - { return functions->DefineClass(this, name, loader, buf, bufLen); } - - jclass FindClass(const char* name) - { return functions->FindClass(this, name); } - - jmethodID FromReflectedMethod(jobject method) - { return functions->FromReflectedMethod(this, method); } - - jfieldID FromReflectedField(jobject field) - { return functions->FromReflectedField(this, field); } - - jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) - { return functions->ToReflectedMethod(this, cls, methodID, isStatic); } - - jclass GetSuperclass(jclass clazz) - { return functions->GetSuperclass(this, clazz); } - - jboolean IsAssignableFrom(jclass clazz1, jclass clazz2) - { return functions->IsAssignableFrom(this, clazz1, clazz2); } - - jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) - { return functions->ToReflectedField(this, cls, fieldID, isStatic); } - - jint Throw(jthrowable obj) - { return functions->Throw(this, obj); } - - jint ThrowNew(jclass clazz, const char* message) - { return functions->ThrowNew(this, clazz, message); } - - jthrowable ExceptionOccurred() - { return functions->ExceptionOccurred(this); } - - void ExceptionDescribe() - { functions->ExceptionDescribe(this); } - - void ExceptionClear() - { functions->ExceptionClear(this); } - - void FatalError(const char* msg) - { functions->FatalError(this, msg); } - - jint PushLocalFrame(jint capacity) - { return functions->PushLocalFrame(this, capacity); } - - jobject PopLocalFrame(jobject result) - { return functions->PopLocalFrame(this, result); } - - jobject NewGlobalRef(jobject obj) - { return functions->NewGlobalRef(this, obj); } - - void DeleteGlobalRef(jobject globalRef) - { functions->DeleteGlobalRef(this, globalRef); } - - void DeleteLocalRef(jobject localRef) - { functions->DeleteLocalRef(this, localRef); } - - jboolean IsSameObject(jobject ref1, jobject ref2) - { return functions->IsSameObject(this, ref1, ref2); } - - jobject NewLocalRef(jobject ref) - { return functions->NewLocalRef(this, ref); } - - jint EnsureLocalCapacity(jint capacity) - { return functions->EnsureLocalCapacity(this, capacity); } - - jobject AllocObject(jclass clazz) - { return functions->AllocObject(this, clazz); } - - jobject NewObject(jclass clazz, jmethodID methodID, ...) - { - va_list args; - va_start(args, methodID); - jobject result = functions->NewObjectV(this, clazz, methodID, args); - va_end(args); - return result; - } - - jobject NewObjectV(jclass clazz, jmethodID methodID, va_list args) - { return functions->NewObjectV(this, clazz, methodID, args); } - - jobject NewObjectA(jclass clazz, jmethodID methodID, jvalue* args) - { return functions->NewObjectA(this, clazz, methodID, args); } - - jclass GetObjectClass(jobject obj) - { return functions->GetObjectClass(this, obj); } - - jboolean IsInstanceOf(jobject obj, jclass clazz) - { return functions->IsInstanceOf(this, obj, clazz); } - - jmethodID GetMethodID(jclass clazz, const char* name, const char* sig) - { return functions->GetMethodID(this, clazz, name, sig); } - -#define CALL_TYPE_METHOD(_jtype, _jname) \ - _jtype Call##_jname##Method(jobject obj, jmethodID methodID, ...) \ - { \ - _jtype result; \ - va_list args; \ - va_start(args, methodID); \ - result = functions->Call##_jname##MethodV(this, obj, methodID, \ - args); \ - va_end(args); \ - return result; \ - } -#define CALL_TYPE_METHODV(_jtype, _jname) \ - _jtype Call##_jname##MethodV(jobject obj, jmethodID methodID, \ - va_list args) \ - { return functions->Call##_jname##MethodV(this, obj, methodID, args); } -#define CALL_TYPE_METHODA(_jtype, _jname) \ - _jtype Call##_jname##MethodA(jobject obj, jmethodID methodID, \ - jvalue* args) \ - { return functions->Call##_jname##MethodA(this, obj, methodID, args); } - -#define CALL_TYPE(_jtype, _jname) \ - CALL_TYPE_METHOD(_jtype, _jname) \ - CALL_TYPE_METHODV(_jtype, _jname) \ - CALL_TYPE_METHODA(_jtype, _jname) - - CALL_TYPE(jobject, Object) - CALL_TYPE(jboolean, Boolean) - CALL_TYPE(jbyte, Byte) - CALL_TYPE(jchar, Char) - CALL_TYPE(jshort, Short) - CALL_TYPE(jint, Int) - CALL_TYPE(jlong, Long) - CALL_TYPE(jfloat, Float) - CALL_TYPE(jdouble, Double) - - void CallVoidMethod(jobject obj, jmethodID methodID, ...) - { - va_list args; - va_start(args, methodID); - functions->CallVoidMethodV(this, obj, methodID, args); - va_end(args); - } - void CallVoidMethodV(jobject obj, jmethodID methodID, va_list args) - { functions->CallVoidMethodV(this, obj, methodID, args); } - void CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args) - { functions->CallVoidMethodA(this, obj, methodID, args); } - -#define CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \ - _jtype CallNonvirtual##_jname##Method(jobject obj, jclass clazz, \ - jmethodID methodID, ...) \ - { \ - _jtype result; \ - va_list args; \ - va_start(args, methodID); \ - result = functions->CallNonvirtual##_jname##MethodV(this, obj, \ - clazz, methodID, args); \ - va_end(args); \ - return result; \ - } -#define CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \ - _jtype CallNonvirtual##_jname##MethodV(jobject obj, jclass clazz, \ - jmethodID methodID, va_list args) \ - { return functions->CallNonvirtual##_jname##MethodV(this, obj, clazz, \ - methodID, args); } -#define CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) \ - _jtype CallNonvirtual##_jname##MethodA(jobject obj, jclass clazz, \ - jmethodID methodID, jvalue* args) \ - { return functions->CallNonvirtual##_jname##MethodA(this, obj, clazz, \ - methodID, args); } - -#define CALL_NONVIRT_TYPE(_jtype, _jname) \ - CALL_NONVIRT_TYPE_METHOD(_jtype, _jname) \ - CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) \ - CALL_NONVIRT_TYPE_METHODA(_jtype, _jname) - - CALL_NONVIRT_TYPE(jobject, Object) - CALL_NONVIRT_TYPE(jboolean, Boolean) - CALL_NONVIRT_TYPE(jbyte, Byte) - CALL_NONVIRT_TYPE(jchar, Char) - CALL_NONVIRT_TYPE(jshort, Short) - CALL_NONVIRT_TYPE(jint, Int) - CALL_NONVIRT_TYPE(jlong, Long) - CALL_NONVIRT_TYPE(jfloat, Float) - CALL_NONVIRT_TYPE(jdouble, Double) - - void CallNonvirtualVoidMethod(jobject obj, jclass clazz, - jmethodID methodID, ...) - { - va_list args; - va_start(args, methodID); - functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); - va_end(args); - } - void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, - jmethodID methodID, va_list args) - { functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); } - void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, - jmethodID methodID, jvalue* args) - { functions->CallNonvirtualVoidMethodA(this, obj, clazz, methodID, args); } - - jfieldID GetFieldID(jclass clazz, const char* name, const char* sig) - { return functions->GetFieldID(this, clazz, name, sig); } - - jobject GetObjectField(jobject obj, jfieldID fieldID) - { return functions->GetObjectField(this, obj, fieldID); } - jboolean GetBooleanField(jobject obj, jfieldID fieldID) - { return functions->GetBooleanField(this, obj, fieldID); } - jbyte GetByteField(jobject obj, jfieldID fieldID) - { return functions->GetByteField(this, obj, fieldID); } - jchar GetCharField(jobject obj, jfieldID fieldID) - { return functions->GetCharField(this, obj, fieldID); } - jshort GetShortField(jobject obj, jfieldID fieldID) - { return functions->GetShortField(this, obj, fieldID); } - jint GetIntField(jobject obj, jfieldID fieldID) - { return functions->GetIntField(this, obj, fieldID); } - jlong GetLongField(jobject obj, jfieldID fieldID) - { return functions->GetLongField(this, obj, fieldID); } - jfloat GetFloatField(jobject obj, jfieldID fieldID) - { return functions->GetFloatField(this, obj, fieldID); } - jdouble GetDoubleField(jobject obj, jfieldID fieldID) - { return functions->GetDoubleField(this, obj, fieldID); } - - void SetObjectField(jobject obj, jfieldID fieldID, jobject value) - { functions->SetObjectField(this, obj, fieldID, value); } - void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value) - { functions->SetBooleanField(this, obj, fieldID, value); } - void SetByteField(jobject obj, jfieldID fieldID, jbyte value) - { functions->SetByteField(this, obj, fieldID, value); } - void SetCharField(jobject obj, jfieldID fieldID, jchar value) - { functions->SetCharField(this, obj, fieldID, value); } - void SetShortField(jobject obj, jfieldID fieldID, jshort value) - { functions->SetShortField(this, obj, fieldID, value); } - void SetIntField(jobject obj, jfieldID fieldID, jint value) - { functions->SetIntField(this, obj, fieldID, value); } - void SetLongField(jobject obj, jfieldID fieldID, jlong value) - { functions->SetLongField(this, obj, fieldID, value); } - void SetFloatField(jobject obj, jfieldID fieldID, jfloat value) - { functions->SetFloatField(this, obj, fieldID, value); } - void SetDoubleField(jobject obj, jfieldID fieldID, jdouble value) - { functions->SetDoubleField(this, obj, fieldID, value); } - - jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig) - { return functions->GetStaticMethodID(this, clazz, name, sig); } - -#define CALL_STATIC_TYPE_METHOD(_jtype, _jname) \ - _jtype CallStatic##_jname##Method(jclass clazz, jmethodID methodID, \ - ...) \ - { \ - _jtype result; \ - va_list args; \ - va_start(args, methodID); \ - result = functions->CallStatic##_jname##MethodV(this, clazz, \ - methodID, args); \ - va_end(args); \ - return result; \ - } -#define CALL_STATIC_TYPE_METHODV(_jtype, _jname) \ - _jtype CallStatic##_jname##MethodV(jclass clazz, jmethodID methodID, \ - va_list args) \ - { return functions->CallStatic##_jname##MethodV(this, clazz, methodID, \ - args); } -#define CALL_STATIC_TYPE_METHODA(_jtype, _jname) \ - _jtype CallStatic##_jname##MethodA(jclass clazz, jmethodID methodID, \ - jvalue* args) \ - { return functions->CallStatic##_jname##MethodA(this, clazz, methodID, \ - args); } - -#define CALL_STATIC_TYPE(_jtype, _jname) \ - CALL_STATIC_TYPE_METHOD(_jtype, _jname) \ - CALL_STATIC_TYPE_METHODV(_jtype, _jname) \ - CALL_STATIC_TYPE_METHODA(_jtype, _jname) - - CALL_STATIC_TYPE(jobject, Object) - CALL_STATIC_TYPE(jboolean, Boolean) - CALL_STATIC_TYPE(jbyte, Byte) - CALL_STATIC_TYPE(jchar, Char) - CALL_STATIC_TYPE(jshort, Short) - CALL_STATIC_TYPE(jint, Int) - CALL_STATIC_TYPE(jlong, Long) - CALL_STATIC_TYPE(jfloat, Float) - CALL_STATIC_TYPE(jdouble, Double) - - void CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...) - { - va_list args; - va_start(args, methodID); - functions->CallStaticVoidMethodV(this, clazz, methodID, args); - va_end(args); - } - void CallStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args) - { functions->CallStaticVoidMethodV(this, clazz, methodID, args); } - void CallStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args) - { functions->CallStaticVoidMethodA(this, clazz, methodID, args); } - - jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig) - { return functions->GetStaticFieldID(this, clazz, name, sig); } - - jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) - { return functions->GetStaticObjectField(this, clazz, fieldID); } - jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) - { return functions->GetStaticBooleanField(this, clazz, fieldID); } - jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) - { return functions->GetStaticByteField(this, clazz, fieldID); } - jchar GetStaticCharField(jclass clazz, jfieldID fieldID) - { return functions->GetStaticCharField(this, clazz, fieldID); } - jshort GetStaticShortField(jclass clazz, jfieldID fieldID) - { return functions->GetStaticShortField(this, clazz, fieldID); } - jint GetStaticIntField(jclass clazz, jfieldID fieldID) - { return functions->GetStaticIntField(this, clazz, fieldID); } - jlong GetStaticLongField(jclass clazz, jfieldID fieldID) - { return functions->GetStaticLongField(this, clazz, fieldID); } - jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) - { return functions->GetStaticFloatField(this, clazz, fieldID); } - jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) - { return functions->GetStaticDoubleField(this, clazz, fieldID); } - - void SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value) - { functions->SetStaticObjectField(this, clazz, fieldID, value); } - void SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value) - { functions->SetStaticBooleanField(this, clazz, fieldID, value); } - void SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value) - { functions->SetStaticByteField(this, clazz, fieldID, value); } - void SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value) - { functions->SetStaticCharField(this, clazz, fieldID, value); } - void SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value) - { functions->SetStaticShortField(this, clazz, fieldID, value); } - void SetStaticIntField(jclass clazz, jfieldID fieldID, jint value) - { functions->SetStaticIntField(this, clazz, fieldID, value); } - void SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value) - { functions->SetStaticLongField(this, clazz, fieldID, value); } - void SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value) - { functions->SetStaticFloatField(this, clazz, fieldID, value); } - void SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value) - { functions->SetStaticDoubleField(this, clazz, fieldID, value); } - - jstring NewString(const jchar* unicodeChars, jsize len) - { return functions->NewString(this, unicodeChars, len); } - - jsize GetStringLength(jstring string) - { return functions->GetStringLength(this, string); } - - const jchar* GetStringChars(jstring string, jboolean* isCopy) - { return functions->GetStringChars(this, string, isCopy); } - - void ReleaseStringChars(jstring string, const jchar* chars) - { functions->ReleaseStringChars(this, string, chars); } - - jstring NewStringUTF(const char* bytes) - { return functions->NewStringUTF(this, bytes); } - - jsize GetStringUTFLength(jstring string) - { return functions->GetStringUTFLength(this, string); } - - const char* GetStringUTFChars(jstring string, jboolean* isCopy) - { return functions->GetStringUTFChars(this, string, isCopy); } - - void ReleaseStringUTFChars(jstring string, const char* utf) - { functions->ReleaseStringUTFChars(this, string, utf); } - - jsize GetArrayLength(jarray array) - { return functions->GetArrayLength(this, array); } - - jobjectArray NewObjectArray(jsize length, jclass elementClass, - jobject initialElement) - { return functions->NewObjectArray(this, length, elementClass, - initialElement); } - - jobject GetObjectArrayElement(jobjectArray array, jsize index) - { return functions->GetObjectArrayElement(this, array, index); } - - void SetObjectArrayElement(jobjectArray array, jsize index, jobject value) - { functions->SetObjectArrayElement(this, array, index, value); } - - jbooleanArray NewBooleanArray(jsize length) - { return functions->NewBooleanArray(this, length); } - jbyteArray NewByteArray(jsize length) - { return functions->NewByteArray(this, length); } - jcharArray NewCharArray(jsize length) - { return functions->NewCharArray(this, length); } - jshortArray NewShortArray(jsize length) - { return functions->NewShortArray(this, length); } - jintArray NewIntArray(jsize length) - { return functions->NewIntArray(this, length); } - jlongArray NewLongArray(jsize length) - { return functions->NewLongArray(this, length); } - jfloatArray NewFloatArray(jsize length) - { return functions->NewFloatArray(this, length); } - jdoubleArray NewDoubleArray(jsize length) - { return functions->NewDoubleArray(this, length); } - - jboolean* GetBooleanArrayElements(jbooleanArray array, jboolean* isCopy) - { return functions->GetBooleanArrayElements(this, array, isCopy); } - jbyte* GetByteArrayElements(jbyteArray array, jboolean* isCopy) - { return functions->GetByteArrayElements(this, array, isCopy); } - jchar* GetCharArrayElements(jcharArray array, jboolean* isCopy) - { return functions->GetCharArrayElements(this, array, isCopy); } - jshort* GetShortArrayElements(jshortArray array, jboolean* isCopy) - { return functions->GetShortArrayElements(this, array, isCopy); } - jint* GetIntArrayElements(jintArray array, jboolean* isCopy) - { return functions->GetIntArrayElements(this, array, isCopy); } - jlong* GetLongArrayElements(jlongArray array, jboolean* isCopy) - { return functions->GetLongArrayElements(this, array, isCopy); } - jfloat* GetFloatArrayElements(jfloatArray array, jboolean* isCopy) - { return functions->GetFloatArrayElements(this, array, isCopy); } - jdouble* GetDoubleArrayElements(jdoubleArray array, jboolean* isCopy) - { return functions->GetDoubleArrayElements(this, array, isCopy); } - - void ReleaseBooleanArrayElements(jbooleanArray array, jboolean* elems, - jint mode) - { functions->ReleaseBooleanArrayElements(this, array, elems, mode); } - void ReleaseByteArrayElements(jbyteArray array, jbyte* elems, - jint mode) - { functions->ReleaseByteArrayElements(this, array, elems, mode); } - void ReleaseCharArrayElements(jcharArray array, jchar* elems, - jint mode) - { functions->ReleaseCharArrayElements(this, array, elems, mode); } - void ReleaseShortArrayElements(jshortArray array, jshort* elems, - jint mode) - { functions->ReleaseShortArrayElements(this, array, elems, mode); } - void ReleaseIntArrayElements(jintArray array, jint* elems, - jint mode) - { functions->ReleaseIntArrayElements(this, array, elems, mode); } - void ReleaseLongArrayElements(jlongArray array, jlong* elems, - jint mode) - { functions->ReleaseLongArrayElements(this, array, elems, mode); } - void ReleaseFloatArrayElements(jfloatArray array, jfloat* elems, - jint mode) - { functions->ReleaseFloatArrayElements(this, array, elems, mode); } - void ReleaseDoubleArrayElements(jdoubleArray array, jdouble* elems, - jint mode) - { functions->ReleaseDoubleArrayElements(this, array, elems, mode); } - - void GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, - jboolean* buf) - { functions->GetBooleanArrayRegion(this, array, start, len, buf); } - void GetByteArrayRegion(jbyteArray array, jsize start, jsize len, - jbyte* buf) - { functions->GetByteArrayRegion(this, array, start, len, buf); } - void GetCharArrayRegion(jcharArray array, jsize start, jsize len, - jchar* buf) - { functions->GetCharArrayRegion(this, array, start, len, buf); } - void GetShortArrayRegion(jshortArray array, jsize start, jsize len, - jshort* buf) - { functions->GetShortArrayRegion(this, array, start, len, buf); } - void GetIntArrayRegion(jintArray array, jsize start, jsize len, - jint* buf) - { functions->GetIntArrayRegion(this, array, start, len, buf); } - void GetLongArrayRegion(jlongArray array, jsize start, jsize len, - jlong* buf) - { functions->GetLongArrayRegion(this, array, start, len, buf); } - void GetFloatArrayRegion(jfloatArray array, jsize start, jsize len, - jfloat* buf) - { functions->GetFloatArrayRegion(this, array, start, len, buf); } - void GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, - jdouble* buf) - { functions->GetDoubleArrayRegion(this, array, start, len, buf); } - - void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, - const jboolean* buf) - { functions->SetBooleanArrayRegion(this, array, start, len, buf); } - void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, - const jbyte* buf) - { functions->SetByteArrayRegion(this, array, start, len, buf); } - void SetCharArrayRegion(jcharArray array, jsize start, jsize len, - const jchar* buf) - { functions->SetCharArrayRegion(this, array, start, len, buf); } - void SetShortArrayRegion(jshortArray array, jsize start, jsize len, - const jshort* buf) - { functions->SetShortArrayRegion(this, array, start, len, buf); } - void SetIntArrayRegion(jintArray array, jsize start, jsize len, - const jint* buf) - { functions->SetIntArrayRegion(this, array, start, len, buf); } - void SetLongArrayRegion(jlongArray array, jsize start, jsize len, - const jlong* buf) - { functions->SetLongArrayRegion(this, array, start, len, buf); } - void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, - const jfloat* buf) - { functions->SetFloatArrayRegion(this, array, start, len, buf); } - void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, - const jdouble* buf) - { functions->SetDoubleArrayRegion(this, array, start, len, buf); } - - jint RegisterNatives(jclass clazz, const JNINativeMethod* methods, - jint nMethods) - { return functions->RegisterNatives(this, clazz, methods, nMethods); } - - jint UnregisterNatives(jclass clazz) - { return functions->UnregisterNatives(this, clazz); } - - jint MonitorEnter(jobject obj) - { return functions->MonitorEnter(this, obj); } - - jint MonitorExit(jobject obj) - { return functions->MonitorExit(this, obj); } - - jint GetJavaVM(JavaVM** vm) - { return functions->GetJavaVM(this, vm); } - - void GetStringRegion(jstring str, jsize start, jsize len, jchar* buf) - { functions->GetStringRegion(this, str, start, len, buf); } - - void GetStringUTFRegion(jstring str, jsize start, jsize len, char* buf) - { return functions->GetStringUTFRegion(this, str, start, len, buf); } - - void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy) - { return functions->GetPrimitiveArrayCritical(this, array, isCopy); } - - void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode) - { functions->ReleasePrimitiveArrayCritical(this, array, carray, mode); } - - const jchar* GetStringCritical(jstring string, jboolean* isCopy) - { return functions->GetStringCritical(this, string, isCopy); } - - void ReleaseStringCritical(jstring string, const jchar* carray) - { functions->ReleaseStringCritical(this, string, carray); } - - jweak NewWeakGlobalRef(jobject obj) - { return functions->NewWeakGlobalRef(this, obj); } - - void DeleteWeakGlobalRef(jweak obj) - { functions->DeleteWeakGlobalRef(this, obj); } - - jboolean ExceptionCheck() - { return functions->ExceptionCheck(this); } - - jobject NewDirectByteBuffer(void* address, jlong capacity) - { return functions->NewDirectByteBuffer(this, address, capacity); } - - void* GetDirectBufferAddress(jobject buf) - { return functions->GetDirectBufferAddress(this, buf); } - - jlong GetDirectBufferCapacity(jobject buf) - { return functions->GetDirectBufferCapacity(this, buf); } - - /* added in JNI 1.6 */ - jobjectRefType GetObjectRefType(jobject obj) - { return functions->GetObjectRefType(this, obj); } -#endif /*__cplusplus*/ -}; - - -/* - * JNI invocation interface. - */ -struct JNIInvokeInterface { - void* reserved0; - void* reserved1; - void* reserved2; - - jint (*DestroyJavaVM)(JavaVM*); - jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*); - jint (*DetachCurrentThread)(JavaVM*); - jint (*GetEnv)(JavaVM*, void**, jint); - jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*); -}; - -/* - * C++ version. - */ -struct _JavaVM { - const struct JNIInvokeInterface* functions; - -#if defined(__cplusplus) - jint DestroyJavaVM() - { return functions->DestroyJavaVM(this); } - jint AttachCurrentThread(JNIEnv** p_env, void* thr_args) - { return functions->AttachCurrentThread(this, p_env, thr_args); } - jint DetachCurrentThread() - { return functions->DetachCurrentThread(this); } - jint GetEnv(void** env, jint version) - { return functions->GetEnv(this, env, version); } - jint AttachCurrentThreadAsDaemon(JNIEnv** p_env, void* thr_args) - { return functions->AttachCurrentThreadAsDaemon(this, p_env, thr_args); } -#endif /*__cplusplus*/ -}; - -struct JavaVMAttachArgs { - jint version; /* must be >= JNI_VERSION_1_2 */ - const char* name; /* NULL or name of thread as modified UTF-8 str */ - jobject group; /* global ref of a ThreadGroup object, or NULL */ -}; -typedef struct JavaVMAttachArgs JavaVMAttachArgs; - -/* - * JNI 1.2+ initialization. (As of 1.6, the pre-1.2 structures are no - * longer supported.) - */ -typedef struct JavaVMOption { - const char* optionString; - void* extraInfo; -} JavaVMOption; - -typedef struct JavaVMInitArgs { - jint version; /* use JNI_VERSION_1_2 or later */ - - jint nOptions; - JavaVMOption* options; - jboolean ignoreUnrecognized; -} JavaVMInitArgs; - -#ifdef __cplusplus -extern "C" { -#endif -/* - * VM initialization functions. - * - * Note these are the only symbols exported for JNI by the VM. - */ -jint JNI_GetDefaultJavaVMInitArgs(void*); -jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*); -jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*); - -#define JNIIMPORT -#define JNIEXPORT __attribute__ ((visibility ("default"))) -#define JNICALL - -/* - * Prototypes for functions exported by loadable shared libs. These are - * called by JNI, not provided by JNI. - */ -JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved); -JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved); - -#ifdef __cplusplus -} -#endif - - -/* - * Manifest constants. - */ -#define JNI_FALSE 0 -#define JNI_TRUE 1 - -#define JNI_VERSION_1_1 0x00010001 -#define JNI_VERSION_1_2 0x00010002 -#define JNI_VERSION_1_4 0x00010004 -#define JNI_VERSION_1_6 0x00010006 - -#define JNI_OK (0) /* no error */ -#define JNI_ERR (-1) /* generic error */ -#define JNI_EDETACHED (-2) /* thread detached from the VM */ -#define JNI_EVERSION (-3) /* JNI version error */ - -#define JNI_COMMIT 1 /* copy content, do not free buffer */ -#define JNI_ABORT 2 /* free buffer w/o copying back */ - -#endif /* JNI_H_ */