[
  {
    "path": ".gitignore",
    "content": "*.o\n*.pyc\n*.so\n*~\nautom4te.cache/\nfiretools_config.h\nfiretools_config_extras.h\nsanitizer.sh\nMakefile\nconfig.log\nconfig.status\nbuild/\n*.1\n*.1.gz\nsrc/firejail-ui/moc*\nsrc/firejail-ui/qrc*\nsrc/fstats/moc*\nsrc/fstats/qrc*\nsrc/firetools/moc*\nsrc/firetools/qrc*\nsrc/fmgr/moc*\nsrc/fmgr/qrc*\nsrc/firejail-ui/.qmake.stash\nsrc/firetools/.qmake.stash\nsrc/fmgr/.qmake.stash\nsrc/fstats/.qmake.stash\nfiretools-*.tar.xz\nfiretools*.deb\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: c++\ndist: trusty\nsudo: true\n\nscript:\n  - sudo apt-get -y install libqt4-dev qt4-qmake lintian\n  - ( cd firetools ; ./configure --enable-fatal-warnings --prefix=/usr && make && sudo make install && sudo make deb)\n"
  },
  {
    "path": "COPYING",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Lesser General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.\n"
  },
  {
    "path": "Makefile.in",
    "content": "all: src firetools.1 firejail-ui.1\n\ndatarootdir=@datarootdir@\nPREFIX=@prefix@\nprefix=@prefix@\nVERSION=@PACKAGE_VERSION@\nNAME=@PACKAGE_NAME@\nPACKAGE_TARNAME=@PACKAGE_TARNAME@\nDOCDIR=@docdir@\n\n\nfiretools_config_extras.h:\n\techo \"#define PACKAGE_LIBDIR \\\"$(DESTDIR)/$(PREFIX)/lib/firetools\\\"\" > firetools_config_extras.h\n\n.PHONY: src\nsrc: firetools_config_extras.h\n\t$(MAKE) -C $@ $(MFLAGS)\n\n\nfiretools.1: src/man/firetools.txt\n\t./mkman.sh $(VERSION) src/man/firetools.txt firetools.1\n\nfirejail-ui.1: src/man/firejail-ui.txt\n\t./mkman.sh $(VERSION) src/man/firejail-ui.txt firejail-ui.1\n\nclean:;rm -f build/*; rm -f *.1 *.1.gz; make -C src clean\n\ndistclean: clean\n\tmake -C src distclean\n\trm -f firetools_config.h firetools_config_extras.h Makefile config.status config.log\n\trm -f src/firetools/config.log src/firetools/config.status #fedora fix\n\trm -f src/fmgr/config.log src/fmgr/config.status #fedora fix\n\trm -f src/debmenu/config.log src/debmenu/config.status #fedora fix\n\trm -f src/firejail-ui/config.log src/firejail-ui/config.status #fedora fix\n\trm -fr autom4te.cache\n\trm -f sanitizer.sh\n\n\nrealinstall:\n\tmkdir -p $(DESTDIR)/$(PREFIX)/bin\n\tmkdir -p $(DESTDIR)/$(PREFIX)/share/applications\n\tmkdir -p $(DESTDIR)/$(PREFIX)/share/pixmaps\n\tmkdir -p $(DESTDIR)/$(PREFIX)/lib/firetools\n\tmkdir -p $(DESTDIR)/$(DOCDIR)\n\tmkdir -p $(DESTDIR)/$(PREFIX)/share/man/man1\n\tinstall -c -m 0755 build/firetools $(DESTDIR)/$(PREFIX)/bin/.\n\tinstall -c -m 0755 build/firejail-ui $(DESTDIR)/$(PREFIX)/bin/.\n\tinstall -c -m 0755 build/fmgr $(DESTDIR)/$(PREFIX)/lib/firetools/fmgr\n\tinstall -c -m 0755 build/fstats $(DESTDIR)/$(PREFIX)/lib/firetools/fstats\n\tinstall -c -m 0644 src/firetools/uiapps $(DESTDIR)/$(PREFIX)/lib/firetools/.\n\tinstall -c -m 0644 src/firejail-ui/uimenus $(DESTDIR)/$(PREFIX)/lib/firetools/.\n\tinstall -c -m 0644 src/firejail-ui/uihelp $(DESTDIR)/$(PREFIX)/lib/firetools/.\n\tinstall -c -m 0644 src/firetools/firetools.desktop $(DESTDIR)/$(PREFIX)/share/applications/.\n\tinstall -c -m 0644 src/firejail-ui/firejail-ui.desktop $(DESTDIR)/$(PREFIX)/share/applications/.\n\tinstall -c -m 0644 src/firetools/resources/firetools.png $(DESTDIR)/$(PREFIX)/share/pixmaps/.\n\tinstall -c -m 0644 src/firetools/resources/firetools-minimal.png $(DESTDIR)/$(PREFIX)/share/pixmaps/.\n\tinstall -c -m 0644 src/firejail-ui/resources/firejail-ui.png $(DESTDIR)/$(PREFIX)/share/pixmaps/.\n\tinstall -c -m 0644 COPYING $(DESTDIR)/$(DOCDIR)/.\n\tinstall -c -m 0644 README $(DESTDIR)/$(DOCDIR)/.\n\tinstall -c -m 0644 RELNOTES $(DESTDIR)/$(DOCDIR)/.\n\trm -f firetools.1.gz\n\tgzip -n9 firetools.1\n\tinstall -c -m 0644 firetools.1.gz $(DESTDIR)/$(PREFIX)/share/man/man1/.\n\trm -f firejail-ui.1.gz\n\tgzip -n9 firejail-ui.1\n\tinstall -c -m 0644 firejail-ui.1.gz $(DESTDIR)/$(PREFIX)/share/man/man1/.\n\ninstall: all\n\t$(MAKE) realinstall\n\ninstall-strip: all\n\tstrip build/*\n\t$(MAKE) realinstall\n\nuninstall:;\n\trm -f $(DESTDIR)/$(PREFIX)/bin/firetools\n\trm -f $(DESTDIR)/$(PREFIX)/bin/firejail-ui\n\trm -f $(DESTDIR)/$(PREFIX)/share/pixmaps/firetools.png\n\trm -f $(DESTDIR)/$(PREFIX)/share/pixmaps/firetools-minimal.png\n\trm -f $(DESTDIR)/$(PREFIX)/share/pixmaps/firejail-ui.png\n\trm -f $(DESTDIR)/$(PREFIX)/share/applications/firetools.desktop\n\trm -f $(DESTDIR)/$(PREFIX)/share/applications/firejail-ui.desktop\n\trm -fr $(DESTDIR)/$(PREFIX)/share/doc/firetools\n\trm -fr $(DESTDIR)/$(PREFIX)/share/man/man1/firetools.1*\n\trm -fr $(DESTDIR)/$(PREFIX)/share/man/man1/firejail-ui.1*\n\trm -fr $(DESTDIR)/$(PREFIX)/lib/firetools\n\ndist:\n\tmv config.status config.status.old\n\tmake distclean\n\tmv config.status.old config.status\n\trm -fr $(NAME)-$(VERSION) $(NAME)-$(VERSION).tar.xz\n\tmkdir $(NAME)-$(VERSION)\n\tcd $(NAME)-$(VERSION); cp -a ../src .; rm -fr src/profile_editor; cp -a ../platform .;\n\tcd $(NAME)-$(VERSION); cp -a ../configure .; cp -a ../configure.ac .; cp -a ../Makefile.in .; cp -a ../install.sh .; cp -a ../mkdeb.sh .;cp -a ../mkask.sh .; cp -a ../mkman.sh .;cd ..\n\tcd $(NAME)-$(VERSION); cp -a ../COPYING .; cp -a ../README .; cp -a ../RELNOTES .; cd ..\n\tcd $(NAME)-$(VERSION); rm -fr `find . -name .svn`; rm -fr $(NAME)-$(VERSION); cd ..\n\ttar -cJvf $(NAME)-$(VERSION).tar.xz $(NAME)-$(VERSION)\n\trm -fr $(NAME)-$(VERSION)\n\n\ndeb: dist\n\t./mkdeb.sh $(NAME) $(VERSION)\n\ncppcheck: clean\n\tcppcheck --force .\n\nscan-build: clean\n\tscan-build make\n\nasc:; ./mkasc.sh $(VERSION)\n"
  },
  {
    "path": "README",
    "content": "Firetools is the graphical user interface of Firajail security sandbox.\n\nDownload: http://sourceforge.net/projects/firejail/files/\nDependencies: firejail, Qt4 or Qt5 library, qmake\nBuild and install: ./configure && make && sudo make install\nDocumentation and support: http://firejail.wordpress.com\nLicense: GPL v2 or later\n\nSetting up a compilation environment:\n(Debian/Ubuntu)$ sudo apt-get install build-essential qt5-default qt5-qmake qtbase5-dev-tools libqt5svg5 git\n(CentOS 7)$ sudo yum install gcc-c++ qt5-qtbase-devel qt5-qtsvg.x86_64 git\n\nCompile and install:\n$ git clone https://github.com/netblue30/firetools\n$ cd firetools\n(Debian/Ubuntu)$ ./configure --prefix=/usr && make && sudo make install\n(CentOS 7)$ ./configure --prefix=/usr --with-qmake=/usr/lib64/qt5/bin/qmake && make && sudo make install\n\n\nMaintainer:\n- netblue30 (netblue30@yahoo.com)\n\nCommitters:\n- Fred-Barclay (https://github.com/Fred-Barclay)\n- Reiner Herrmann (https://github.com/reinerh - Debian/Ubuntu maintainer)\n- smithsohu (https://github.com/smitsohu)\n- startx2017 (https://github.com/startx2017) - LTS and *bugfixes branches maintainer)\n- netblue30 (netblue30@yahoo.com)\n\nFiretools Authors:\n\nnetblue30 (netblue30@yahoo.com)\na1346054 (https://github.com/a1346054)\n\t- code cleanup\nDaniel Schildt (https://github.com/d2s)\n\t- ignore built packages in .gitignore\n\t- grayscale icon for launcher\n\t- fix/add comments throughout the code\n\t- add more auto-detected apps\n\t- improve visual style\n\t- reduce margins, improve usability\n\t- add signal-desktop icon\ndmio (https://github.com/dmio)\n\t- detect and switch qt versions with autotools\nhelmutg (https://github.com/helmutg)\n\t- Use correct host-prefixed qmake to allow cross-building\nPiraty (https://github.com/Piraty)\n\t- use system's icons when available\nReiner Herrmann\n\t- Debian and Ubuntu integration\n\t- various fixes\nTopi Miettinen (https://github.com/topimiettinen)\n\t- change labels to black to be visible with dark themes and various other fixes\nWarren Togami (https://github.com/wtogami)\n\t- rewrite of mkrpm.sh, Fedora packaging cleanup\n\nTerminal icon (gnome-terminal.png) taken from Gnome project, license LGPL v3 or CC BY-SA 3.0.\n\nLibreoffice-writer (libreoffice-writer.png) taken from LibreOffice project, license LGPL v3 (or later) or CC BY-SA 3.0 or MPL 1.1.\n\nIcedove icon (icedove.png) taken from Debian project, license MPL 1.1 or GPL v2 or LGPL v2.1.\n\nFirefox icon (firefox.png) taken from Firefox project, license MPL 2.0.\n\nfmgr and firejail-ui icons (go_top.png, go_up.png, user-home.png, gnome-fs-directory.png, empty.png)\ntake from nuoveXT 2 project (http://gnome-look.org/content/show.php/nuoveXT+2?content=56625),\nlicense LGPL\n\nfmgr and firejail-ui icons (emblem-symbolic-link.png, view-refresh.png) taken from Adwaita project\n(http://gnome-look.org/content/show.php/?content=144237), license GPL\n\n\nCopyright (C) 2015 Firetools Authors\n"
  },
  {
    "path": "README.md",
    "content": "# Firetools\n\nFiretools is the graphical user interface of Firejail security sandbox. It provides a sandbox launcher\nintegrated with the system tray, sandbox editing, management and statistics. The application is built\nusing Qt5 library.\n\nHome page: https://firejailtools.wordpress.com\n\nDownload: http://sourceforge.net/projects/firejail/files/firetools/\n\nTravis-CI status: https://travis-ci.org/netblue30/firetools\n\n\n<table><tr>\n\n<td>\n<a href=\"https://odysee.com/@netblue30:9/firetools:6\" target=\"_blank\">\n<img src=\"https://thumbs.odycdn.com/f696288045a51bc504e00c35b0a3b206.png\"\nalt=\"Firetools Demo\" width=\"240\" height=\"142\" border=\"10\" /><br/>Firetools Demo</a>\n</td>\n\n<td>\n<a href=\"https://odysee.com/@netblue30:9/intro:ceb\" target=\"_blank\">\n<img src=\"https://thumbs.odycdn.com/a909846bdce7992f1aacceb0dcc8898b.png\"\nalt=\"Firejail Introduction\" width=\"240\" height=\"142\" border=\"10\" /><br/>Firejail Introduction</a>\n</td>\n</tr></table>\n\n## Setting up a compilation environment:\n`````\n(Debian/Ubuntu)\n$ sudo apt-get install build-essential qt5-default qt5-qmake qtbase5-dev-tools libqt5svg5 git\n\n(CentOS 7)\n$ sudo yum install gcc-c++ qt5-qtbase-devel qt5-qtsvg.x86_64 git\n`````\n\n## Compile & Install\n\n`````\n$ git clone https://github.com/netblue30/firetools\n$ cd firetools\n\n(Debian/Ubuntu)\n$ ./configure\n\n(CentOS 7)\n./configure --with-qmake=/usr/lib64/qt5/bin/qmake\n\n$ make\n$ sudo make install-strip\n`````\n\n## Usage:\n`````\nFIRETOOLS(1)                                firetools man page                               FIRETOOLS(1)\n\nNAME\n       Firetools - Graphical tools collection for Firejail security sandbox\n\nSYNOPSIS\n       firetools [OPTIONS]\n\nDESCRIPTION\n       Firetools is a GUI application for Firejail.  It offers a system tray launcher for sandboxed apps,\n       sandbox editing, management, and statistics.  The software package also includes a sandbox config‐\n       uration wizard, firejail-ui.\n\n       The list of applications recognized automatically by Firetools is stored in /usr/lib/firetools/ap‐\n       plist.  To add more applications to the list drop a similar file in your home directory in ~/.con‐\n       fig/firetools/uiapps.\n\nOPTIONS\n       --autostart\n              Configure firetools to run automatically in system tray when X11 session is started.\n\n       --debug\n              Print debug messages.\n\n       -?, --help\n              Print options end exit.\n\n       --version\n              Print software version and exit.\n\nCONFIGURATION\n       /usr/lib/firetools/uiapps  file  contains  the default list of applications recognized by default.\n       The user can add more applications by creating a simillar file  in  ~/.config/firetools/uiapps  in\n       user home directory. Each line describes an application as follows:\n\n              executable; description; icon; (optional) firejail command\n\n       Some examples:\n\n              inkscape;Inkscape SVG Editor;inkscape\n              calibre;eBook Reader;/usr/share/calibre/images/lt.png\n              mpv;MPV;mpv;firejail mpv --player-operation-mode=pseudo-gui\n\nABOUT FIREJAIL\n       Firejail  is  a SUID sandbox program that reduces the risk of security breaches by restricting the\n       running environment of untrusted applications using Linux namespaces, seccomp-bpf and Linux  capa‐\n       bilities.  It allows a process and all its descendants to have their own private view of the glob‐\n       ally shared kernel resources, such as the network stack, process table, mount table.  Firejail can\n       work in a SELinux or AppArmor environment, and it is integrated with Linux Control Groups.\n\n\nLICENSE\n       This program is free software; you can redistribute it and/or modify it under the terms of the GNU\n       General Public License as published by the Free Software Foundation; either version 2 of  the  Li‐\n       cense, or (at your option) any later version.\n\n       Homepage: http://firejail.wordpress.com\n\nSEE ALSO\n       firejail(1), firejail-ui(1),\n`````\n"
  },
  {
    "path": "RELNOTES",
    "content": "firetools (0.9.72) baseline; urgency=low\n  * modif: move hardcoded apps recognized by default in uiapps file\n  * modif: remove sandbox edit dialog and replace it with uiapps file\n  * feature: added uiapps file for default and user apps configuration\n  * feature: added a system network monitor in sandbox stats\n  * feature: added apparmor support in firejail-ui\n  * feature: added bluetooth support in firejail-ui\n  * feature: print final sandbox configuration in firejail-ui\n  * bugfixes\n -- netblue30 <netblue30@yahoo.com>  Tue, 3 Jan 2023 08:00:00 -0500\n\nfiretools (0.9.64) baseline; urgency=low\n  * more fdns support\n  * support for firejail version 0.9.64\n  * bugfixes\n -- netblue30 <netblue30@yahoo.com>  Fri, 8 Jan 2021 08:00:00 -0500\n\nfiretools (0.9.62) baseline; urgency=low\n  * added fdns support\n  * added stats system tray icon\n  * split network interface stats in a separate window\n  * detect --net=none in network interface stats\n  * support for Firejail LTS versions\n  * bugfixes\n -- netblue30 <netblue30@yahoo.com>  Mon, 16 Dec 2019 08:00:00 -0500\n\nfiretools (0.9.52) baseline; urgency=low\n  * modif: moving to a grayscale color scheme\n  * feature: firewall support in stats window\n  * feature: AppArmor support in stats window\n  * feature: adding Signal to the default list of applications\n  * bugfixes and various user interface improvements\n -- netblue30 <netblue30@yahoo.com>  Thu, 1 Mar 2018 13:00:00 -0500\n\nfiretools (0.9.50) baseline; urgency=low\n  * modif: removed the periodic window update for seccomp, caps,\n     and dns\n  * feature: memory deny exec stats support\n  * feature: print security profile name in stats window\n  * feature: protocol support in firejail-ui\n  * feature: nodvd support in firejail-ui\n  * feature: novideo support in firejail-ui\n  * feature: notv support in firejail-ui\n  * enhancement: save window size for fmgr and fstats upon exit\n     and restore it next time the program is started\n  * enhancement: updated default application list\n  * enhancement: rework icon search for firetools launcher\n  * enhancement: --enable-fatal-warnings compile configuration\n  * Travis CI integration\n  * bugfixes\n -- netblue30 <netblue30@yahoo.com>  Sat, 30 Sep 2017 08:00:00 -0500\n\nfiretools (0.9.46) baseline; urgency=low\n  * split firetools in two distinct executables\n  * updated the default list of applications for firetools\n  * added firejail-ui, a configuration wizard for firejail\n  * move make dist from .tar.bz2 to .tar.xz\n  * implemented detached signatures\n  * bugfixes\n -- netblue30 <netblue30@yahoo.com>  Wed, 22 Feb 2017 08:00:00 -0500\n\nfiretools (0.9.44) baseline; urgency=low\n  * support for firejail --x11 detection\n  * bugfixes\n -- netblue30 <netblue30@yahoo.com>  Mon, 24 Oct 2016 08:00:00 -0500\n\nfiretools (0.9.40.1) baseline; urgency=low\n  * bugfixes\n -- netblue30 <netblue30@yahoo.com>  Wed, 15 Jun 2016 08:00:00 -0500\n\nfiretools (0.9.40) baseline; urgency=low\n  * Grsecurity support\n  * updated the default application list\n  * sandbox file manager (firemgr) application\n  * protocols and cpu cores support\n  * sandbox name support\n  * X11 dispaly support\n  * bugfixes\n -- netblue30 <netblue30@yahoo.com>  Sun, 29 May 2016 08:00:00 -0500\n\nfiretools (0.9.30) baseline; urgency=low\n  * 1h and 12h statistics support\n  * user namespaces support\n  * QT5 support\n  * applist update\n  * bugfixes\n -- netblue30 <netblue30@yahoo.com>  Thu, 1 Sep 2015 08:00:00 -0500\n\nfiretools (0.9.26.1) baseline; urgency=low\n  * RPM package support\n  * bugfixes\n -- netblue30 <netblue30@yahoo.com>  Tue, 10 Jun 2015 08:00:00 -0500\n\nfiretools (0.9.26) baseline; urgency=low\n  * first version\n -- netblue30 <netblue30@yahoo.com>  Tue, 19 May 2015 08:00:00 -0500\n"
  },
  {
    "path": "configure",
    "content": "#! /bin/sh\n# Guess values for system-dependent variables and create Makefiles.\n# Generated by GNU Autoconf 2.69 for firetools 0.9.73.\n#\n# Report bugs to <netblue30@yahoo.com>.\n#\n#\n# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.\n#\n#\n# This configure script is free software; the Free Software Foundation\n# gives unlimited permission to copy, distribute and modify it.\n## -------------------- ##\n## M4sh Initialization. ##\n## -------------------- ##\n\n# Be more Bourne compatible\nDUALCASE=1; export DUALCASE # for MKS sh\nif test -n \"${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :\n  emulate sh\n  NULLCMD=:\n  # Pre-4.2 versions of Zsh do word splitting on ${1+\"$@\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '${1+\"$@\"}'='\"$@\"'\n  setopt NO_GLOB_SUBST\nelse\n  case `(set -o) 2>/dev/null` in #(\n  *posix*) :\n    set -o posix ;; #(\n  *) :\n     ;;\nesac\nfi\n\n\nas_nl='\n'\nexport as_nl\n# Printing a long string crashes Solaris 7 /usr/bin/printf.\nas_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo\n# Prefer a ksh shell builtin over an external printf program on Solaris,\n# but without wasting forks for bash or zsh.\nif test -z \"$BASH_VERSION$ZSH_VERSION\" \\\n    && (test \"X`print -r -- $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='print -r --'\n  as_echo_n='print -rn --'\nelif (test \"X`printf %s $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='printf %s\\n'\n  as_echo_n='printf %s'\nelse\n  if test \"X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`\" = \"X-n $as_echo\"; then\n    as_echo_body='eval /usr/ucb/echo -n \"$1$as_nl\"'\n    as_echo_n='/usr/ucb/echo -n'\n  else\n    as_echo_body='eval expr \"X$1\" : \"X\\\\(.*\\\\)\"'\n    as_echo_n_body='eval\n      arg=$1;\n      case $arg in #(\n      *\"$as_nl\"*)\n\texpr \"X$arg\" : \"X\\\\(.*\\\\)$as_nl\";\n\targ=`expr \"X$arg\" : \".*$as_nl\\\\(.*\\\\)\"`;;\n      esac;\n      expr \"X$arg\" : \"X\\\\(.*\\\\)\" | tr -d \"$as_nl\"\n    '\n    export as_echo_n_body\n    as_echo_n='sh -c $as_echo_n_body as_echo'\n  fi\n  export as_echo_body\n  as_echo='sh -c $as_echo_body as_echo'\nfi\n\n# The user is always right.\nif test \"${PATH_SEPARATOR+set}\" != set; then\n  PATH_SEPARATOR=:\n  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {\n    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||\n      PATH_SEPARATOR=';'\n  }\nfi\n\n\n# IFS\n# We need space, tab and new line, in precisely that order.  Quoting is\n# there to prevent editors from complaining about space-tab.\n# (If _AS_PATH_WALK were called with IFS unset, it would disable word\n# splitting by setting IFS to empty value.)\nIFS=\" \"\"\t$as_nl\"\n\n# Find who we are.  Look in the path if we contain no directory separator.\nas_myself=\ncase $0 in #((\n  *[\\\\/]* ) as_myself=$0 ;;\n  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    test -r \"$as_dir/$0\" && as_myself=$as_dir/$0 && break\n  done\nIFS=$as_save_IFS\n\n     ;;\nesac\n# We did not find ourselves, most probably we were run as `sh COMMAND'\n# in which case we are not to be found in the path.\nif test \"x$as_myself\" = x; then\n  as_myself=$0\nfi\nif test ! -f \"$as_myself\"; then\n  $as_echo \"$as_myself: error: cannot find myself; rerun with an absolute file name\" >&2\n  exit 1\nfi\n\n# Unset variables that we do not need and which cause bugs (e.g. in\n# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the \"|| exit 1\"\n# suppresses any \"Segmentation fault\" message there.  '((' could\n# trigger a bug in pdksh 5.2.14.\nfor as_var in BASH_ENV ENV MAIL MAILPATH\ndo eval test x\\${$as_var+set} = xset \\\n  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :\ndone\nPS1='$ '\nPS2='> '\nPS4='+ '\n\n# NLS nuisances.\nLC_ALL=C\nexport LC_ALL\nLANGUAGE=C\nexport LANGUAGE\n\n# CDPATH.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\n# Use a proper internal environment variable to ensure we don't fall\n  # into an infinite loop, continuously re-executing ourselves.\n  if test x\"${_as_can_reexec}\" != xno && test \"x$CONFIG_SHELL\" != x; then\n    _as_can_reexec=no; export _as_can_reexec;\n    # We cannot yet assume a decent shell, so we have to provide a\n# neutralization value for shells without unset; and this also\n# works around shells that cannot unset nonexistent variables.\n# Preserve -v and -x to the replacement shell.\nBASH_ENV=/dev/null\nENV=/dev/null\n(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV\ncase $- in # ((((\n  *v*x* | *x*v* ) as_opts=-vx ;;\n  *v* ) as_opts=-v ;;\n  *x* ) as_opts=-x ;;\n  * ) as_opts= ;;\nesac\nexec $CONFIG_SHELL $as_opts \"$as_myself\" ${1+\"$@\"}\n# Admittedly, this is quite paranoid, since all the known shells bail\n# out after a failed `exec'.\n$as_echo \"$0: could not re-execute with $CONFIG_SHELL\" >&2\nas_fn_exit 255\n  fi\n  # We don't want this to propagate to other subprocesses.\n          { _as_can_reexec=; unset _as_can_reexec;}\nif test \"x$CONFIG_SHELL\" = x; then\n  as_bourne_compatible=\"if test -n \\\"\\${ZSH_VERSION+set}\\\" && (emulate sh) >/dev/null 2>&1; then :\n  emulate sh\n  NULLCMD=:\n  # Pre-4.2 versions of Zsh do word splitting on \\${1+\\\"\\$@\\\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '\\${1+\\\"\\$@\\\"}'='\\\"\\$@\\\"'\n  setopt NO_GLOB_SUBST\nelse\n  case \\`(set -o) 2>/dev/null\\` in #(\n  *posix*) :\n    set -o posix ;; #(\n  *) :\n     ;;\nesac\nfi\n\"\n  as_required=\"as_fn_return () { (exit \\$1); }\nas_fn_success () { as_fn_return 0; }\nas_fn_failure () { as_fn_return 1; }\nas_fn_ret_success () { return 0; }\nas_fn_ret_failure () { return 1; }\n\nexitcode=0\nas_fn_success || { exitcode=1; echo as_fn_success failed.; }\nas_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }\nas_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }\nas_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }\nif ( set x; as_fn_ret_success y && test x = \\\"\\$1\\\" ); then :\n\nelse\n  exitcode=1; echo positional parameters were not saved.\nfi\ntest x\\$exitcode = x0 || exit 1\ntest -x / || exit 1\"\n  as_suggested=\"  as_lineno_1=\";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested\" as_lineno_1a=\\$LINENO\n  as_lineno_2=\";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested\" as_lineno_2a=\\$LINENO\n  eval 'test \\\"x\\$as_lineno_1'\\$as_run'\\\" != \\\"x\\$as_lineno_2'\\$as_run'\\\" &&\n  test \\\"x\\`expr \\$as_lineno_1'\\$as_run' + 1\\`\\\" = \\\"x\\$as_lineno_2'\\$as_run'\\\"' || exit 1\ntest \\$(( 1 + 1 )) = 2 || exit 1\"\n  if (eval \"$as_required\") 2>/dev/null; then :\n  as_have_required=yes\nelse\n  as_have_required=no\nfi\n  if test x$as_have_required = xyes && (eval \"$as_suggested\") 2>/dev/null; then :\n\nelse\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nas_found=false\nfor as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n  as_found=:\n  case $as_dir in #(\n\t /*)\n\t   for as_base in sh bash ksh sh5; do\n\t     # Try only shells that exist, to save several forks.\n\t     as_shell=$as_dir/$as_base\n\t     if { test -f \"$as_shell\" || test -f \"$as_shell.exe\"; } &&\n\t\t    { $as_echo \"$as_bourne_compatible\"\"$as_required\" | as_run=a \"$as_shell\"; } 2>/dev/null; then :\n  CONFIG_SHELL=$as_shell as_have_required=yes\n\t\t   if { $as_echo \"$as_bourne_compatible\"\"$as_suggested\" | as_run=a \"$as_shell\"; } 2>/dev/null; then :\n  break 2\nfi\nfi\n\t   done;;\n       esac\n  as_found=false\ndone\n$as_found || { if { test -f \"$SHELL\" || test -f \"$SHELL.exe\"; } &&\n\t      { $as_echo \"$as_bourne_compatible\"\"$as_required\" | as_run=a \"$SHELL\"; } 2>/dev/null; then :\n  CONFIG_SHELL=$SHELL as_have_required=yes\nfi; }\nIFS=$as_save_IFS\n\n\n      if test \"x$CONFIG_SHELL\" != x; then :\n  export CONFIG_SHELL\n             # We cannot yet assume a decent shell, so we have to provide a\n# neutralization value for shells without unset; and this also\n# works around shells that cannot unset nonexistent variables.\n# Preserve -v and -x to the replacement shell.\nBASH_ENV=/dev/null\nENV=/dev/null\n(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV\ncase $- in # ((((\n  *v*x* | *x*v* ) as_opts=-vx ;;\n  *v* ) as_opts=-v ;;\n  *x* ) as_opts=-x ;;\n  * ) as_opts= ;;\nesac\nexec $CONFIG_SHELL $as_opts \"$as_myself\" ${1+\"$@\"}\n# Admittedly, this is quite paranoid, since all the known shells bail\n# out after a failed `exec'.\n$as_echo \"$0: could not re-execute with $CONFIG_SHELL\" >&2\nexit 255\nfi\n\n    if test x$as_have_required = xno; then :\n  $as_echo \"$0: This script requires a shell more modern than all\"\n  $as_echo \"$0: the shells that I found on your system.\"\n  if test x${ZSH_VERSION+set} = xset ; then\n    $as_echo \"$0: In particular, zsh $ZSH_VERSION has bugs and should\"\n    $as_echo \"$0: be upgraded to zsh 4.3.4 or later.\"\n  else\n    $as_echo \"$0: Please tell bug-autoconf@gnu.org and\n$0: netblue30@yahoo.com about your system, including any\n$0: error possibly output before this message. Then install\n$0: a modern shell, or manually run the script under such a\n$0: shell if you do have one.\"\n  fi\n  exit 1\nfi\nfi\nfi\nSHELL=${CONFIG_SHELL-/bin/sh}\nexport SHELL\n# Unset more variables known to interfere with behavior of common tools.\nCLICOLOR_FORCE= GREP_OPTIONS=\nunset CLICOLOR_FORCE GREP_OPTIONS\n\n## --------------------- ##\n## M4sh Shell Functions. ##\n## --------------------- ##\n# as_fn_unset VAR\n# ---------------\n# Portably unset VAR.\nas_fn_unset ()\n{\n  { eval $1=; unset $1;}\n}\nas_unset=as_fn_unset\n\n# as_fn_set_status STATUS\n# -----------------------\n# Set $? to STATUS, without forking.\nas_fn_set_status ()\n{\n  return $1\n} # as_fn_set_status\n\n# as_fn_exit STATUS\n# -----------------\n# Exit the shell with STATUS, even in a \"trap 0\" or \"set -e\" context.\nas_fn_exit ()\n{\n  set +e\n  as_fn_set_status $1\n  exit $1\n} # as_fn_exit\n\n# as_fn_mkdir_p\n# -------------\n# Create \"$as_dir\" as a directory, including parents if necessary.\nas_fn_mkdir_p ()\n{\n\n  case $as_dir in #(\n  -*) as_dir=./$as_dir;;\n  esac\n  test -d \"$as_dir\" || eval $as_mkdir_p || {\n    as_dirs=\n    while :; do\n      case $as_dir in #(\n      *\\'*) as_qdir=`$as_echo \"$as_dir\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;; #'(\n      *) as_qdir=$as_dir;;\n      esac\n      as_dirs=\"'$as_qdir' $as_dirs\"\n      as_dir=`$as_dirname -- \"$as_dir\" ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n      test -d \"$as_dir\" && break\n    done\n    test -z \"$as_dirs\" || eval \"mkdir $as_dirs\"\n  } || test -d \"$as_dir\" || as_fn_error $? \"cannot create directory $as_dir\"\n\n\n} # as_fn_mkdir_p\n\n# as_fn_executable_p FILE\n# -----------------------\n# Test if FILE is an executable regular file.\nas_fn_executable_p ()\n{\n  test -f \"$1\" && test -x \"$1\"\n} # as_fn_executable_p\n# as_fn_append VAR VALUE\n# ----------------------\n# Append the text in VALUE to the end of the definition contained in VAR. Take\n# advantage of any shell optimizations that allow amortized linear growth over\n# repeated appends, instead of the typical quadratic growth present in naive\n# implementations.\nif (eval \"as_var=1; as_var+=2; test x\\$as_var = x12\") 2>/dev/null; then :\n  eval 'as_fn_append ()\n  {\n    eval $1+=\\$2\n  }'\nelse\n  as_fn_append ()\n  {\n    eval $1=\\$$1\\$2\n  }\nfi # as_fn_append\n\n# as_fn_arith ARG...\n# ------------------\n# Perform arithmetic evaluation on the ARGs, and store the result in the\n# global $as_val. Take advantage of shells that can avoid forks. The arguments\n# must be portable across $(()) and expr.\nif (eval \"test \\$(( 1 + 1 )) = 2\") 2>/dev/null; then :\n  eval 'as_fn_arith ()\n  {\n    as_val=$(( $* ))\n  }'\nelse\n  as_fn_arith ()\n  {\n    as_val=`expr \"$@\" || test $? -eq 1`\n  }\nfi # as_fn_arith\n\n\n# as_fn_error STATUS ERROR [LINENO LOG_FD]\n# ----------------------------------------\n# Output \"`basename $0`: error: ERROR\" to stderr. If LINENO and LOG_FD are\n# provided, also output the error to LOG_FD, referencing LINENO. Then exit the\n# script with STATUS, using 1 if that was 0.\nas_fn_error ()\n{\n  as_status=$1; test $as_status -eq 0 && as_status=1\n  if test \"$4\"; then\n    as_lineno=${as_lineno-\"$3\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n    $as_echo \"$as_me:${as_lineno-$LINENO}: error: $2\" >&$4\n  fi\n  $as_echo \"$as_me: error: $2\" >&2\n  as_fn_exit $as_status\n} # as_fn_error\n\nif expr a : '\\(a\\)' >/dev/null 2>&1 &&\n   test \"X`expr 00001 : '.*\\(...\\)'`\" = X001; then\n  as_expr=expr\nelse\n  as_expr=false\nfi\n\nif (basename -- /) >/dev/null 2>&1 && test \"X`basename -- / 2>&1`\" = \"X/\"; then\n  as_basename=basename\nelse\n  as_basename=false\nfi\n\nif (as_dir=`dirname -- /` && test \"X$as_dir\" = X/) >/dev/null 2>&1; then\n  as_dirname=dirname\nelse\n  as_dirname=false\nfi\n\nas_me=`$as_basename -- \"$0\" ||\n$as_expr X/\"$0\" : '.*/\\([^/][^/]*\\)/*$' \\| \\\n\t X\"$0\" : 'X\\(//\\)$' \\| \\\n\t X\"$0\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X/\"$0\" |\n    sed '/^.*\\/\\([^/][^/]*\\)\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n\n# Avoid depending upon Character Ranges.\nas_cr_letters='abcdefghijklmnopqrstuvwxyz'\nas_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'\nas_cr_Letters=$as_cr_letters$as_cr_LETTERS\nas_cr_digits='0123456789'\nas_cr_alnum=$as_cr_Letters$as_cr_digits\n\n\n  as_lineno_1=$LINENO as_lineno_1a=$LINENO\n  as_lineno_2=$LINENO as_lineno_2a=$LINENO\n  eval 'test \"x$as_lineno_1'$as_run'\" != \"x$as_lineno_2'$as_run'\" &&\n  test \"x`expr $as_lineno_1'$as_run' + 1`\" = \"x$as_lineno_2'$as_run'\"' || {\n  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)\n  sed -n '\n    p\n    /[$]LINENO/=\n  ' <$as_myself |\n    sed '\n      s/[$]LINENO.*/&-/\n      t lineno\n      b\n      :lineno\n      N\n      :loop\n      s/[$]LINENO\\([^'$as_cr_alnum'_].*\\n\\)\\(.*\\)/\\2\\1\\2/\n      t loop\n      s/-\\n.*//\n    ' >$as_me.lineno &&\n  chmod +x \"$as_me.lineno\" ||\n    { $as_echo \"$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell\" >&2; as_fn_exit 1; }\n\n  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have\n  # already done that, so ensure we don't try to do so again and fall\n  # in an infinite loop.  This has already happened in practice.\n  _as_can_reexec=no; export _as_can_reexec\n  # Don't try to exec as it changes $[0], causing all sort of problems\n  # (the dirname of $[0] is not the place where we might find the\n  # original and so on.  Autoconf is especially sensitive to this).\n  . \"./$as_me.lineno\"\n  # Exit status is that of the last command.\n  exit\n}\n\nECHO_C= ECHO_N= ECHO_T=\ncase `echo -n x` in #(((((\n-n*)\n  case `echo 'xy\\c'` in\n  *c*) ECHO_T='\t';;\t# ECHO_T is single tab character.\n  xy)  ECHO_C='\\c';;\n  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null\n       ECHO_T='\t';;\n  esac;;\n*)\n  ECHO_N='-n';;\nesac\n\nrm -f conf$$ conf$$.exe conf$$.file\nif test -d conf$$.dir; then\n  rm -f conf$$.dir/conf$$.file\nelse\n  rm -f conf$$.dir\n  mkdir conf$$.dir 2>/dev/null\nfi\nif (echo >conf$$.file) 2>/dev/null; then\n  if ln -s conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s='ln -s'\n    # ... but there are two gotchas:\n    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.\n    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.\n    # In both cases, we have to default to `cp -pR'.\n    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||\n      as_ln_s='cp -pR'\n  elif ln conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s=ln\n  else\n    as_ln_s='cp -pR'\n  fi\nelse\n  as_ln_s='cp -pR'\nfi\nrm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file\nrmdir conf$$.dir 2>/dev/null\n\nif mkdir -p . 2>/dev/null; then\n  as_mkdir_p='mkdir -p \"$as_dir\"'\nelse\n  test -d ./-p && rmdir ./-p\n  as_mkdir_p=false\nfi\n\nas_test_x='test -x'\nas_executable_p=as_fn_executable_p\n\n# Sed expression to map a string onto a valid CPP name.\nas_tr_cpp=\"eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'\"\n\n# Sed expression to map a string onto a valid variable name.\nas_tr_sh=\"eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'\"\n\n\ntest -n \"$DJDIR\" || exec 7<&0 </dev/null\nexec 6>&1\n\n# Name of the host.\n# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,\n# so uname gets run too.\nac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`\n\n#\n# Initializations.\n#\nac_default_prefix=/usr/local\nac_clean_files=\nac_config_libobj_dir=.\nLIBOBJS=\ncross_compiling=no\nsubdirs=\nMFLAGS=\nMAKEFLAGS=\n\n# Identity of this package.\nPACKAGE_NAME='firetools'\nPACKAGE_TARNAME='firetools'\nPACKAGE_VERSION='0.9.73'\nPACKAGE_STRING='firetools 0.9.73'\nPACKAGE_BUGREPORT='netblue30@yahoo.com'\nPACKAGE_URL='http://firejail.wordpress.com'\n\nac_unique_file=\"src/firetools/main.cpp\"\n# Factoring default headers for most tests.\nac_includes_default=\"\\\n#include <stdio.h>\n#ifdef HAVE_SYS_TYPES_H\n# include <sys/types.h>\n#endif\n#ifdef HAVE_SYS_STAT_H\n# include <sys/stat.h>\n#endif\n#ifdef STDC_HEADERS\n# include <stdlib.h>\n# include <stddef.h>\n#else\n# ifdef HAVE_STDLIB_H\n#  include <stdlib.h>\n# endif\n#endif\n#ifdef HAVE_STRING_H\n# if !defined STDC_HEADERS && defined HAVE_MEMORY_H\n#  include <memory.h>\n# endif\n# include <string.h>\n#endif\n#ifdef HAVE_STRINGS_H\n# include <strings.h>\n#endif\n#ifdef HAVE_INTTYPES_H\n# include <inttypes.h>\n#endif\n#ifdef HAVE_STDINT_H\n# include <stdint.h>\n#endif\n#ifdef HAVE_UNISTD_H\n# include <unistd.h>\n#endif\"\n\nac_subst_vars='LTLIBOBJS\nLIBOBJS\nQMAKE\nHAVE_FATAL_WARNINGS\nEGREP\nGREP\nCPP\nRANLIB\nLN_S\nINSTALL_DATA\nINSTALL_SCRIPT\nINSTALL_PROGRAM\nac_ct_CXX\nCXXFLAGS\nCXX\nOBJEXT\nEXEEXT\nac_ct_CC\nCPPFLAGS\nLDFLAGS\nCFLAGS\nCC\ntarget_alias\nhost_alias\nbuild_alias\nLIBS\nECHO_T\nECHO_N\nECHO_C\nDEFS\nmandir\nlocaledir\nlibdir\npsdir\npdfdir\ndvidir\nhtmldir\ninfodir\ndocdir\noldincludedir\nincludedir\nrunstatedir\nlocalstatedir\nsharedstatedir\nsysconfdir\ndatadir\ndatarootdir\nlibexecdir\nsbindir\nbindir\nprogram_transform_name\nprefix\nexec_prefix\nPACKAGE_URL\nPACKAGE_BUGREPORT\nPACKAGE_STRING\nPACKAGE_VERSION\nPACKAGE_TARNAME\nPACKAGE_NAME\nPATH_SEPARATOR\nSHELL'\nac_subst_files=''\nac_user_opts='\nenable_option_checking\nenable_fatal_warnings\nwith_qmake\n'\n      ac_precious_vars='build_alias\nhost_alias\ntarget_alias\nCC\nCFLAGS\nLDFLAGS\nLIBS\nCPPFLAGS\nCXX\nCXXFLAGS\nCCC\nCPP'\n\n\n# Initialize some variables set by options.\nac_init_help=\nac_init_version=false\nac_unrecognized_opts=\nac_unrecognized_sep=\n# The variables have the same names as the options, with\n# dashes changed to underlines.\ncache_file=/dev/null\nexec_prefix=NONE\nno_create=\nno_recursion=\nprefix=NONE\nprogram_prefix=NONE\nprogram_suffix=NONE\nprogram_transform_name=s,x,x,\nsilent=\nsite=\nsrcdir=\nverbose=\nx_includes=NONE\nx_libraries=NONE\n\n# Installation directory options.\n# These are left unexpanded so users can \"make install exec_prefix=/foo\"\n# and all the variables that are supposed to be based on exec_prefix\n# by default will actually change.\n# Use braces instead of parens because sh, perl, etc. also accept them.\n# (The list follows the same order as the GNU Coding Standards.)\nbindir='${exec_prefix}/bin'\nsbindir='${exec_prefix}/sbin'\nlibexecdir='${exec_prefix}/libexec'\ndatarootdir='${prefix}/share'\ndatadir='${datarootdir}'\nsysconfdir='${prefix}/etc'\nsharedstatedir='${prefix}/com'\nlocalstatedir='${prefix}/var'\nrunstatedir='${localstatedir}/run'\nincludedir='${prefix}/include'\noldincludedir='/usr/include'\ndocdir='${datarootdir}/doc/${PACKAGE_TARNAME}'\ninfodir='${datarootdir}/info'\nhtmldir='${docdir}'\ndvidir='${docdir}'\npdfdir='${docdir}'\npsdir='${docdir}'\nlibdir='${exec_prefix}/lib'\nlocaledir='${datarootdir}/locale'\nmandir='${datarootdir}/man'\n\nac_prev=\nac_dashdash=\nfor ac_option\ndo\n  # If the previous option needs an argument, assign it.\n  if test -n \"$ac_prev\"; then\n    eval $ac_prev=\\$ac_option\n    ac_prev=\n    continue\n  fi\n\n  case $ac_option in\n  *=?*) ac_optarg=`expr \"X$ac_option\" : '[^=]*=\\(.*\\)'` ;;\n  *=)   ac_optarg= ;;\n  *)    ac_optarg=yes ;;\n  esac\n\n  # Accept the important Cygnus configure options, so we can diagnose typos.\n\n  case $ac_dashdash$ac_option in\n  --)\n    ac_dashdash=yes ;;\n\n  -bindir | --bindir | --bindi | --bind | --bin | --bi)\n    ac_prev=bindir ;;\n  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)\n    bindir=$ac_optarg ;;\n\n  -build | --build | --buil | --bui | --bu)\n    ac_prev=build_alias ;;\n  -build=* | --build=* | --buil=* | --bui=* | --bu=*)\n    build_alias=$ac_optarg ;;\n\n  -cache-file | --cache-file | --cache-fil | --cache-fi \\\n  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)\n    ac_prev=cache_file ;;\n  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \\\n  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)\n    cache_file=$ac_optarg ;;\n\n  --config-cache | -C)\n    cache_file=config.cache ;;\n\n  -datadir | --datadir | --datadi | --datad)\n    ac_prev=datadir ;;\n  -datadir=* | --datadir=* | --datadi=* | --datad=*)\n    datadir=$ac_optarg ;;\n\n  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \\\n  | --dataroo | --dataro | --datar)\n    ac_prev=datarootdir ;;\n  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \\\n  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)\n    datarootdir=$ac_optarg ;;\n\n  -disable-* | --disable-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*disable-\\(.*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error $? \"invalid feature name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"enable_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval enable_$ac_useropt=no ;;\n\n  -docdir | --docdir | --docdi | --doc | --do)\n    ac_prev=docdir ;;\n  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)\n    docdir=$ac_optarg ;;\n\n  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)\n    ac_prev=dvidir ;;\n  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)\n    dvidir=$ac_optarg ;;\n\n  -enable-* | --enable-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*enable-\\([^=]*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error $? \"invalid feature name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"enable_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval enable_$ac_useropt=\\$ac_optarg ;;\n\n  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \\\n  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \\\n  | --exec | --exe | --ex)\n    ac_prev=exec_prefix ;;\n  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \\\n  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \\\n  | --exec=* | --exe=* | --ex=*)\n    exec_prefix=$ac_optarg ;;\n\n  -gas | --gas | --ga | --g)\n    # Obsolete; use --with-gas.\n    with_gas=yes ;;\n\n  -help | --help | --hel | --he | -h)\n    ac_init_help=long ;;\n  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)\n    ac_init_help=recursive ;;\n  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)\n    ac_init_help=short ;;\n\n  -host | --host | --hos | --ho)\n    ac_prev=host_alias ;;\n  -host=* | --host=* | --hos=* | --ho=*)\n    host_alias=$ac_optarg ;;\n\n  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)\n    ac_prev=htmldir ;;\n  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \\\n  | --ht=*)\n    htmldir=$ac_optarg ;;\n\n  -includedir | --includedir | --includedi | --included | --include \\\n  | --includ | --inclu | --incl | --inc)\n    ac_prev=includedir ;;\n  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \\\n  | --includ=* | --inclu=* | --incl=* | --inc=*)\n    includedir=$ac_optarg ;;\n\n  -infodir | --infodir | --infodi | --infod | --info | --inf)\n    ac_prev=infodir ;;\n  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)\n    infodir=$ac_optarg ;;\n\n  -libdir | --libdir | --libdi | --libd)\n    ac_prev=libdir ;;\n  -libdir=* | --libdir=* | --libdi=* | --libd=*)\n    libdir=$ac_optarg ;;\n\n  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \\\n  | --libexe | --libex | --libe)\n    ac_prev=libexecdir ;;\n  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \\\n  | --libexe=* | --libex=* | --libe=*)\n    libexecdir=$ac_optarg ;;\n\n  -localedir | --localedir | --localedi | --localed | --locale)\n    ac_prev=localedir ;;\n  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)\n    localedir=$ac_optarg ;;\n\n  -localstatedir | --localstatedir | --localstatedi | --localstated \\\n  | --localstate | --localstat | --localsta | --localst | --locals)\n    ac_prev=localstatedir ;;\n  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \\\n  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)\n    localstatedir=$ac_optarg ;;\n\n  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)\n    ac_prev=mandir ;;\n  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)\n    mandir=$ac_optarg ;;\n\n  -nfp | --nfp | --nf)\n    # Obsolete; use --without-fp.\n    with_fp=no ;;\n\n  -no-create | --no-create | --no-creat | --no-crea | --no-cre \\\n  | --no-cr | --no-c | -n)\n    no_create=yes ;;\n\n  -no-recursion | --no-recursion | --no-recursio | --no-recursi \\\n  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)\n    no_recursion=yes ;;\n\n  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \\\n  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \\\n  | --oldin | --oldi | --old | --ol | --o)\n    ac_prev=oldincludedir ;;\n  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \\\n  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \\\n  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)\n    oldincludedir=$ac_optarg ;;\n\n  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)\n    ac_prev=prefix ;;\n  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)\n    prefix=$ac_optarg ;;\n\n  -program-prefix | --program-prefix | --program-prefi | --program-pref \\\n  | --program-pre | --program-pr | --program-p)\n    ac_prev=program_prefix ;;\n  -program-prefix=* | --program-prefix=* | --program-prefi=* \\\n  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)\n    program_prefix=$ac_optarg ;;\n\n  -program-suffix | --program-suffix | --program-suffi | --program-suff \\\n  | --program-suf | --program-su | --program-s)\n    ac_prev=program_suffix ;;\n  -program-suffix=* | --program-suffix=* | --program-suffi=* \\\n  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)\n    program_suffix=$ac_optarg ;;\n\n  -program-transform-name | --program-transform-name \\\n  | --program-transform-nam | --program-transform-na \\\n  | --program-transform-n | --program-transform- \\\n  | --program-transform | --program-transfor \\\n  | --program-transfo | --program-transf \\\n  | --program-trans | --program-tran \\\n  | --progr-tra | --program-tr | --program-t)\n    ac_prev=program_transform_name ;;\n  -program-transform-name=* | --program-transform-name=* \\\n  | --program-transform-nam=* | --program-transform-na=* \\\n  | --program-transform-n=* | --program-transform-=* \\\n  | --program-transform=* | --program-transfor=* \\\n  | --program-transfo=* | --program-transf=* \\\n  | --program-trans=* | --program-tran=* \\\n  | --progr-tra=* | --program-tr=* | --program-t=*)\n    program_transform_name=$ac_optarg ;;\n\n  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)\n    ac_prev=pdfdir ;;\n  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)\n    pdfdir=$ac_optarg ;;\n\n  -psdir | --psdir | --psdi | --psd | --ps)\n    ac_prev=psdir ;;\n  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)\n    psdir=$ac_optarg ;;\n\n  -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n  | -silent | --silent | --silen | --sile | --sil)\n    silent=yes ;;\n\n  -runstatedir | --runstatedir | --runstatedi | --runstated \\\n  | --runstate | --runstat | --runsta | --runst | --runs \\\n  | --run | --ru | --r)\n    ac_prev=runstatedir ;;\n  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \\\n  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \\\n  | --run=* | --ru=* | --r=*)\n    runstatedir=$ac_optarg ;;\n\n  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)\n    ac_prev=sbindir ;;\n  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \\\n  | --sbi=* | --sb=*)\n    sbindir=$ac_optarg ;;\n\n  -sharedstatedir | --sharedstatedir | --sharedstatedi \\\n  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \\\n  | --sharedst | --shareds | --shared | --share | --shar \\\n  | --sha | --sh)\n    ac_prev=sharedstatedir ;;\n  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \\\n  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \\\n  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \\\n  | --sha=* | --sh=*)\n    sharedstatedir=$ac_optarg ;;\n\n  -site | --site | --sit)\n    ac_prev=site ;;\n  -site=* | --site=* | --sit=*)\n    site=$ac_optarg ;;\n\n  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)\n    ac_prev=srcdir ;;\n  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)\n    srcdir=$ac_optarg ;;\n\n  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \\\n  | --syscon | --sysco | --sysc | --sys | --sy)\n    ac_prev=sysconfdir ;;\n  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \\\n  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)\n    sysconfdir=$ac_optarg ;;\n\n  -target | --target | --targe | --targ | --tar | --ta | --t)\n    ac_prev=target_alias ;;\n  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)\n    target_alias=$ac_optarg ;;\n\n  -v | -verbose | --verbose | --verbos | --verbo | --verb)\n    verbose=yes ;;\n\n  -version | --version | --versio | --versi | --vers | -V)\n    ac_init_version=: ;;\n\n  -with-* | --with-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*with-\\([^=]*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error $? \"invalid package name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"with_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval with_$ac_useropt=\\$ac_optarg ;;\n\n  -without-* | --without-*)\n    ac_useropt=`expr \"x$ac_option\" : 'x-*without-\\(.*\\)'`\n    # Reject names that are not valid shell variable names.\n    expr \"x$ac_useropt\" : \".*[^-+._$as_cr_alnum]\" >/dev/null &&\n      as_fn_error $? \"invalid package name: $ac_useropt\"\n    ac_useropt_orig=$ac_useropt\n    ac_useropt=`$as_echo \"$ac_useropt\" | sed 's/[-+.]/_/g'`\n    case $ac_user_opts in\n      *\"\n\"with_$ac_useropt\"\n\"*) ;;\n      *) ac_unrecognized_opts=\"$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig\"\n\t ac_unrecognized_sep=', ';;\n    esac\n    eval with_$ac_useropt=no ;;\n\n  --x)\n    # Obsolete; use --with-x.\n    with_x=yes ;;\n\n  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \\\n  | --x-incl | --x-inc | --x-in | --x-i)\n    ac_prev=x_includes ;;\n  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \\\n  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)\n    x_includes=$ac_optarg ;;\n\n  -x-libraries | --x-libraries | --x-librarie | --x-librari \\\n  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)\n    ac_prev=x_libraries ;;\n  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \\\n  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)\n    x_libraries=$ac_optarg ;;\n\n  -*) as_fn_error $? \"unrecognized option: \\`$ac_option'\nTry \\`$0 --help' for more information\"\n    ;;\n\n  *=*)\n    ac_envvar=`expr \"x$ac_option\" : 'x\\([^=]*\\)='`\n    # Reject names that are not valid shell variable names.\n    case $ac_envvar in #(\n      '' | [0-9]* | *[!_$as_cr_alnum]* )\n      as_fn_error $? \"invalid variable name: \\`$ac_envvar'\" ;;\n    esac\n    eval $ac_envvar=\\$ac_optarg\n    export $ac_envvar ;;\n\n  *)\n    # FIXME: should be removed in autoconf 3.0.\n    $as_echo \"$as_me: WARNING: you should use --build, --host, --target\" >&2\n    expr \"x$ac_option\" : \".*[^-._$as_cr_alnum]\" >/dev/null &&\n      $as_echo \"$as_me: WARNING: invalid host type: $ac_option\" >&2\n    : \"${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}\"\n    ;;\n\n  esac\ndone\n\nif test -n \"$ac_prev\"; then\n  ac_option=--`echo $ac_prev | sed 's/_/-/g'`\n  as_fn_error $? \"missing argument to $ac_option\"\nfi\n\nif test -n \"$ac_unrecognized_opts\"; then\n  case $enable_option_checking in\n    no) ;;\n    fatal) as_fn_error $? \"unrecognized options: $ac_unrecognized_opts\" ;;\n    *)     $as_echo \"$as_me: WARNING: unrecognized options: $ac_unrecognized_opts\" >&2 ;;\n  esac\nfi\n\n# Check all directory arguments for consistency.\nfor ac_var in\texec_prefix prefix bindir sbindir libexecdir datarootdir \\\n\t\tdatadir sysconfdir sharedstatedir localstatedir includedir \\\n\t\toldincludedir docdir infodir htmldir dvidir pdfdir psdir \\\n\t\tlibdir localedir mandir runstatedir\ndo\n  eval ac_val=\\$$ac_var\n  # Remove trailing slashes.\n  case $ac_val in\n    */ )\n      ac_val=`expr \"X$ac_val\" : 'X\\(.*[^/]\\)' \\| \"X$ac_val\" : 'X\\(.*\\)'`\n      eval $ac_var=\\$ac_val;;\n  esac\n  # Be sure to have absolute directory names.\n  case $ac_val in\n    [\\\\/$]* | ?:[\\\\/]* )  continue;;\n    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;\n  esac\n  as_fn_error $? \"expected an absolute directory name for --$ac_var: $ac_val\"\ndone\n\n# There might be people who depend on the old broken behavior: `$host'\n# used to hold the argument of --host etc.\n# FIXME: To remove some day.\nbuild=$build_alias\nhost=$host_alias\ntarget=$target_alias\n\n# FIXME: To remove some day.\nif test \"x$host_alias\" != x; then\n  if test \"x$build_alias\" = x; then\n    cross_compiling=maybe\n  elif test \"x$build_alias\" != \"x$host_alias\"; then\n    cross_compiling=yes\n  fi\nfi\n\nac_tool_prefix=\ntest -n \"$host_alias\" && ac_tool_prefix=$host_alias-\n\ntest \"$silent\" = yes && exec 6>/dev/null\n\n\nac_pwd=`pwd` && test -n \"$ac_pwd\" &&\nac_ls_di=`ls -di .` &&\nac_pwd_ls_di=`cd \"$ac_pwd\" && ls -di .` ||\n  as_fn_error $? \"working directory cannot be determined\"\ntest \"X$ac_ls_di\" = \"X$ac_pwd_ls_di\" ||\n  as_fn_error $? \"pwd does not report name of working directory\"\n\n\n# Find the source files, if location was not specified.\nif test -z \"$srcdir\"; then\n  ac_srcdir_defaulted=yes\n  # Try the directory containing this script, then the parent directory.\n  ac_confdir=`$as_dirname -- \"$as_myself\" ||\n$as_expr X\"$as_myself\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_myself\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_myself\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_myself\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$as_myself\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n  srcdir=$ac_confdir\n  if test ! -r \"$srcdir/$ac_unique_file\"; then\n    srcdir=..\n  fi\nelse\n  ac_srcdir_defaulted=no\nfi\nif test ! -r \"$srcdir/$ac_unique_file\"; then\n  test \"$ac_srcdir_defaulted\" = yes && srcdir=\"$ac_confdir or ..\"\n  as_fn_error $? \"cannot find sources ($ac_unique_file) in $srcdir\"\nfi\nac_msg=\"sources are in $srcdir, but \\`cd $srcdir' does not work\"\nac_abs_confdir=`(\n\tcd \"$srcdir\" && test -r \"./$ac_unique_file\" || as_fn_error $? \"$ac_msg\"\n\tpwd)`\n# When building in place, set srcdir=.\nif test \"$ac_abs_confdir\" = \"$ac_pwd\"; then\n  srcdir=.\nfi\n# Remove unnecessary trailing slashes from srcdir.\n# Double slashes in file names in object file debugging info\n# mess up M-x gdb in Emacs.\ncase $srcdir in\n*/) srcdir=`expr \"X$srcdir\" : 'X\\(.*[^/]\\)' \\| \"X$srcdir\" : 'X\\(.*\\)'`;;\nesac\nfor ac_var in $ac_precious_vars; do\n  eval ac_env_${ac_var}_set=\\${${ac_var}+set}\n  eval ac_env_${ac_var}_value=\\$${ac_var}\n  eval ac_cv_env_${ac_var}_set=\\${${ac_var}+set}\n  eval ac_cv_env_${ac_var}_value=\\$${ac_var}\ndone\n\n#\n# Report the --help message.\n#\nif test \"$ac_init_help\" = \"long\"; then\n  # Omit some internal or obsolete options to make the list less imposing.\n  # This message is too long to be a string in the A/UX 3.1 sh.\n  cat <<_ACEOF\n\\`configure' configures firetools 0.9.73 to adapt to many kinds of systems.\n\nUsage: $0 [OPTION]... [VAR=VALUE]...\n\nTo assign environment variables (e.g., CC, CFLAGS...), specify them as\nVAR=VALUE.  See below for descriptions of some of the useful variables.\n\nDefaults for the options are specified in brackets.\n\nConfiguration:\n  -h, --help              display this help and exit\n      --help=short        display options specific to this package\n      --help=recursive    display the short help of all the included packages\n  -V, --version           display version information and exit\n  -q, --quiet, --silent   do not print \\`checking ...' messages\n      --cache-file=FILE   cache test results in FILE [disabled]\n  -C, --config-cache      alias for \\`--cache-file=config.cache'\n  -n, --no-create         do not create output files\n      --srcdir=DIR        find the sources in DIR [configure dir or \\`..']\n\nInstallation directories:\n  --prefix=PREFIX         install architecture-independent files in PREFIX\n                          [$ac_default_prefix]\n  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX\n                          [PREFIX]\n\nBy default, \\`make install' will install all the files in\n\\`$ac_default_prefix/bin', \\`$ac_default_prefix/lib' etc.  You can specify\nan installation prefix other than \\`$ac_default_prefix' using \\`--prefix',\nfor instance \\`--prefix=\\$HOME'.\n\nFor better control, use the options below.\n\nFine tuning of the installation directories:\n  --bindir=DIR            user executables [EPREFIX/bin]\n  --sbindir=DIR           system admin executables [EPREFIX/sbin]\n  --libexecdir=DIR        program executables [EPREFIX/libexec]\n  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]\n  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]\n  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]\n  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]\n  --libdir=DIR            object code libraries [EPREFIX/lib]\n  --includedir=DIR        C header files [PREFIX/include]\n  --oldincludedir=DIR     C header files for non-gcc [/usr/include]\n  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]\n  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]\n  --infodir=DIR           info documentation [DATAROOTDIR/info]\n  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]\n  --mandir=DIR            man documentation [DATAROOTDIR/man]\n  --docdir=DIR            documentation root [DATAROOTDIR/doc/firetools]\n  --htmldir=DIR           html documentation [DOCDIR]\n  --dvidir=DIR            dvi documentation [DOCDIR]\n  --pdfdir=DIR            pdf documentation [DOCDIR]\n  --psdir=DIR             ps documentation [DOCDIR]\n_ACEOF\n\n  cat <<\\_ACEOF\n_ACEOF\nfi\n\nif test -n \"$ac_init_help\"; then\n  case $ac_init_help in\n     short | recursive ) echo \"Configuration of firetools 0.9.73:\";;\n   esac\n  cat <<\\_ACEOF\n\nOptional Features:\n  --disable-option-checking  ignore unrecognized --enable/--with options\n  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)\n  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]\n  --enable-fatal-warnings -W -Wall -Werror\n\nOptional Packages:\n  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]\n  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)\n  --with-qmake=PATH       Path to qmake executable\n\nSome influential environment variables:\n  CC          C compiler command\n  CFLAGS      C compiler flags\n  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a\n              nonstandard directory <lib dir>\n  LIBS        libraries to pass to the linker, e.g. -l<library>\n  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if\n              you have headers in a nonstandard directory <include dir>\n  CXX         C++ compiler command\n  CXXFLAGS    C++ compiler flags\n  CPP         C preprocessor\n\nUse these variables to override the choices made by `configure' or to help\nit to find libraries and programs with nonstandard names/locations.\n\nReport bugs to <netblue30@yahoo.com>.\nfiretools home page: <http://firejail.wordpress.com>.\n_ACEOF\nac_status=$?\nfi\n\nif test \"$ac_init_help\" = \"recursive\"; then\n  # If there are subdirs, report their specific --help.\n  for ac_dir in : $ac_subdirs_all; do test \"x$ac_dir\" = x: && continue\n    test -d \"$ac_dir\" ||\n      { cd \"$srcdir\" && ac_pwd=`pwd` && srcdir=. && test -d \"$ac_dir\"; } ||\n      continue\n    ac_builddir=.\n\ncase \"$ac_dir\" in\n.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;\n*)\n  ac_dir_suffix=/`$as_echo \"$ac_dir\" | sed 's|^\\.[\\\\/]||'`\n  # A \"..\" for each directory in $ac_dir_suffix.\n  ac_top_builddir_sub=`$as_echo \"$ac_dir_suffix\" | sed 's|/[^\\\\/]*|/..|g;s|/||'`\n  case $ac_top_builddir_sub in\n  \"\") ac_top_builddir_sub=. ac_top_build_prefix= ;;\n  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;\n  esac ;;\nesac\nac_abs_top_builddir=$ac_pwd\nac_abs_builddir=$ac_pwd$ac_dir_suffix\n# for backward compatibility:\nac_top_builddir=$ac_top_build_prefix\n\ncase $srcdir in\n  .)  # We are building in place.\n    ac_srcdir=.\n    ac_top_srcdir=$ac_top_builddir_sub\n    ac_abs_top_srcdir=$ac_pwd ;;\n  [\\\\/]* | ?:[\\\\/]* )  # Absolute name.\n    ac_srcdir=$srcdir$ac_dir_suffix;\n    ac_top_srcdir=$srcdir\n    ac_abs_top_srcdir=$srcdir ;;\n  *) # Relative name.\n    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix\n    ac_top_srcdir=$ac_top_build_prefix$srcdir\n    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;\nesac\nac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix\n\n    cd \"$ac_dir\" || { ac_status=$?; continue; }\n    # Check for guested configure.\n    if test -f \"$ac_srcdir/configure.gnu\"; then\n      echo &&\n      $SHELL \"$ac_srcdir/configure.gnu\" --help=recursive\n    elif test -f \"$ac_srcdir/configure\"; then\n      echo &&\n      $SHELL \"$ac_srcdir/configure\" --help=recursive\n    else\n      $as_echo \"$as_me: WARNING: no configuration information is in $ac_dir\" >&2\n    fi || ac_status=$?\n    cd \"$ac_pwd\" || { ac_status=$?; break; }\n  done\nfi\n\ntest -n \"$ac_init_help\" && exit $ac_status\nif $ac_init_version; then\n  cat <<\\_ACEOF\nfiretools configure 0.9.73\ngenerated by GNU Autoconf 2.69\n\nCopyright (C) 2012 Free Software Foundation, Inc.\nThis configure script is free software; the Free Software Foundation\ngives unlimited permission to copy, distribute and modify it.\n_ACEOF\n  exit\nfi\n\n## ------------------------ ##\n## Autoconf initialization. ##\n## ------------------------ ##\n\n# ac_fn_c_try_compile LINENO\n# --------------------------\n# Try to compile conftest.$ac_ext, and return whether this succeeded.\nac_fn_c_try_compile ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  rm -f conftest.$ac_objext\n  if { { ac_try=\"$ac_compile\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compile\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && {\n\t test -z \"$ac_c_werror_flag\" ||\n\t test ! -s conftest.err\n       } && test -s conftest.$ac_objext; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n\tac_retval=1\nfi\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_c_try_compile\n\n# ac_fn_cxx_try_compile LINENO\n# ----------------------------\n# Try to compile conftest.$ac_ext, and return whether this succeeded.\nac_fn_cxx_try_compile ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  rm -f conftest.$ac_objext\n  if { { ac_try=\"$ac_compile\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compile\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && {\n\t test -z \"$ac_cxx_werror_flag\" ||\n\t test ! -s conftest.err\n       } && test -s conftest.$ac_objext; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n\tac_retval=1\nfi\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_cxx_try_compile\n\n# ac_fn_c_try_link LINENO\n# -----------------------\n# Try to link conftest.$ac_ext, and return whether this succeeded.\nac_fn_c_try_link ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  rm -f conftest.$ac_objext conftest$ac_exeext\n  if { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && {\n\t test -z \"$ac_c_werror_flag\" ||\n\t test ! -s conftest.err\n       } && test -s conftest$ac_exeext && {\n\t test \"$cross_compiling\" = yes ||\n\t test -x conftest$ac_exeext\n       }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n\tac_retval=1\nfi\n  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information\n  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would\n  # interfere with the next link command; also delete a directory that is\n  # left behind by Apple's compiler.  We do this before executing the actions.\n  rm -rf conftest.dSYM conftest_ipa8_conftest.oo\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_c_try_link\n\n# ac_fn_c_try_cpp LINENO\n# ----------------------\n# Try to preprocess conftest.$ac_ext, and return whether this succeeded.\nac_fn_c_try_cpp ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  if { { ac_try=\"$ac_cpp conftest.$ac_ext\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_cpp conftest.$ac_ext\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    grep -v '^ *+' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n    mv -f conftest.er1 conftest.err\n  fi\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } > conftest.i && {\n\t test -z \"$ac_c_preproc_warn_flag$ac_c_werror_flag\" ||\n\t test ! -s conftest.err\n       }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n    ac_retval=1\nfi\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_c_try_cpp\n\n# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES\n# -------------------------------------------------------\n# Tests whether HEADER exists, giving a warning if it cannot be compiled using\n# the include files in INCLUDES and setting the cache variable VAR\n# accordingly.\nac_fn_c_check_header_mongrel ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  if eval \\${$3+:} false; then :\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif eval \\${$3+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\nelse\n  # Is the header compilable?\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking $2 usability\" >&5\n$as_echo_n \"checking $2 usability... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n$4\n#include <$2>\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_header_compiler=yes\nelse\n  ac_header_compiler=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler\" >&5\n$as_echo \"$ac_header_compiler\" >&6; }\n\n# Is the header present?\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking $2 presence\" >&5\n$as_echo_n \"checking $2 presence... \" >&6; }\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <$2>\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n  ac_header_preproc=yes\nelse\n  ac_header_preproc=no\nfi\nrm -f conftest.err conftest.i conftest.$ac_ext\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc\" >&5\n$as_echo \"$ac_header_preproc\" >&6; }\n\n# So?  What about this header?\ncase $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((\n  yes:no: )\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!\" >&5\n$as_echo \"$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result\" >&5\n$as_echo \"$as_me: WARNING: $2: proceeding with the compiler's result\" >&2;}\n    ;;\n  no:yes:* )\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled\" >&5\n$as_echo \"$as_me: WARNING: $2: present but cannot be compiled\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?\" >&5\n$as_echo \"$as_me: WARNING: $2:     check for missing prerequisite headers?\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation\" >&5\n$as_echo \"$as_me: WARNING: $2: see the Autoconf documentation\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \\\"Present But Cannot Be Compiled\\\"\" >&5\n$as_echo \"$as_me: WARNING: $2:     section \\\"Present But Cannot Be Compiled\\\"\" >&2;}\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result\" >&5\n$as_echo \"$as_me: WARNING: $2: proceeding with the compiler's result\" >&2;}\n( $as_echo \"## ---------------------------------- ##\n## Report this to netblue30@yahoo.com ##\n## ---------------------------------- ##\"\n     ) | sed \"s/^/$as_me: WARNING:     /\" >&2\n    ;;\nesac\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif eval \\${$3+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  eval \"$3=\\$ac_header_compiler\"\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\nfi\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n\n} # ac_fn_c_check_header_mongrel\n\n# ac_fn_c_try_run LINENO\n# ----------------------\n# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes\n# that executables *can* be run.\nac_fn_c_try_run ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  if { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'\n  { { case \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_try\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; }; then :\n  ac_retval=0\nelse\n  $as_echo \"$as_me: program exited with status $ac_status\" >&5\n       $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n       ac_retval=$ac_status\nfi\n  rm -rf conftest.dSYM conftest_ipa8_conftest.oo\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n  as_fn_set_status $ac_retval\n\n} # ac_fn_c_try_run\n\n# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES\n# -------------------------------------------------------\n# Tests whether HEADER exists and can be compiled using the include files in\n# INCLUDES, setting the cache variable VAR accordingly.\nac_fn_c_check_header_compile ()\n{\n  as_lineno=${as_lineno-\"$1\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $2\" >&5\n$as_echo_n \"checking for $2... \" >&6; }\nif eval \\${$3+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n$4\n#include <$2>\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  eval \"$3=yes\"\nelse\n  eval \"$3=no\"\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\neval ac_res=\\$$3\n\t       { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_res\" >&5\n$as_echo \"$ac_res\" >&6; }\n  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno\n\n} # ac_fn_c_check_header_compile\ncat >config.log <<_ACEOF\nThis file contains any messages produced by compilers while\nrunning configure, to aid debugging if configure makes a mistake.\n\nIt was created by firetools $as_me 0.9.73, which was\ngenerated by GNU Autoconf 2.69.  Invocation command line was\n\n  $ $0 $@\n\n_ACEOF\nexec 5>>config.log\n{\ncat <<_ASUNAME\n## --------- ##\n## Platform. ##\n## --------- ##\n\nhostname = `(hostname || uname -n) 2>/dev/null | sed 1q`\nuname -m = `(uname -m) 2>/dev/null || echo unknown`\nuname -r = `(uname -r) 2>/dev/null || echo unknown`\nuname -s = `(uname -s) 2>/dev/null || echo unknown`\nuname -v = `(uname -v) 2>/dev/null || echo unknown`\n\n/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`\n/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`\n\n/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`\n/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`\n/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`\n/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`\n/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`\n/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`\n/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`\n\n_ASUNAME\n\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    $as_echo \"PATH: $as_dir\"\n  done\nIFS=$as_save_IFS\n\n} >&5\n\ncat >&5 <<_ACEOF\n\n\n## ----------- ##\n## Core tests. ##\n## ----------- ##\n\n_ACEOF\n\n\n# Keep a trace of the command line.\n# Strip out --no-create and --no-recursion so they do not pile up.\n# Strip out --silent because we don't want to record it for future runs.\n# Also quote any args containing shell meta-characters.\n# Make two passes to allow for proper duplicate-argument suppression.\nac_configure_args=\nac_configure_args0=\nac_configure_args1=\nac_must_keep_next=false\nfor ac_pass in 1 2\ndo\n  for ac_arg\n  do\n    case $ac_arg in\n    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;\n    -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n    | -silent | --silent | --silen | --sile | --sil)\n      continue ;;\n    *\\'*)\n      ac_arg=`$as_echo \"$ac_arg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    esac\n    case $ac_pass in\n    1) as_fn_append ac_configure_args0 \" '$ac_arg'\" ;;\n    2)\n      as_fn_append ac_configure_args1 \" '$ac_arg'\"\n      if test $ac_must_keep_next = true; then\n\tac_must_keep_next=false # Got value, back to normal.\n      else\n\tcase $ac_arg in\n\t  *=* | --config-cache | -C | -disable-* | --disable-* \\\n\t  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \\\n\t  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \\\n\t  | -with-* | --with-* | -without-* | --without-* | --x)\n\t    case \"$ac_configure_args0 \" in\n\t      \"$ac_configure_args1\"*\" '$ac_arg' \"* ) continue ;;\n\t    esac\n\t    ;;\n\t  -* ) ac_must_keep_next=true ;;\n\tesac\n      fi\n      as_fn_append ac_configure_args \" '$ac_arg'\"\n      ;;\n    esac\n  done\ndone\n{ ac_configure_args0=; unset ac_configure_args0;}\n{ ac_configure_args1=; unset ac_configure_args1;}\n\n# When interrupted or exit'd, cleanup temporary files, and complete\n# config.log.  We remove comments because anyway the quotes in there\n# would cause problems or look ugly.\n# WARNING: Use '\\'' to represent an apostrophe within the trap.\n# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.\ntrap 'exit_status=$?\n  # Save into config.log some information that might help in debugging.\n  {\n    echo\n\n    $as_echo \"## ---------------- ##\n## Cache variables. ##\n## ---------------- ##\"\n    echo\n    # The following way of writing the cache mishandles newlines in values,\n(\n  for ac_var in `(set) 2>&1 | sed -n '\\''s/^\\([a-zA-Z_][a-zA-Z0-9_]*\\)=.*/\\1/p'\\''`; do\n    eval ac_val=\\$$ac_var\n    case $ac_val in #(\n    *${as_nl}*)\n      case $ac_var in #(\n      *_cv_*) { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline\" >&5\n$as_echo \"$as_me: WARNING: cache variable $ac_var contains a newline\" >&2;} ;;\n      esac\n      case $ac_var in #(\n      _ | IFS | as_nl) ;; #(\n      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(\n      *) { eval $ac_var=; unset $ac_var;} ;;\n      esac ;;\n    esac\n  done\n  (set) 2>&1 |\n    case $as_nl`(ac_space='\\'' '\\''; set) 2>&1` in #(\n    *${as_nl}ac_space=\\ *)\n      sed -n \\\n\t\"s/'\\''/'\\''\\\\\\\\'\\'''\\''/g;\n\t  s/^\\\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\\\)=\\\\(.*\\\\)/\\\\1='\\''\\\\2'\\''/p\"\n      ;; #(\n    *)\n      sed -n \"/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p\"\n      ;;\n    esac |\n    sort\n)\n    echo\n\n    $as_echo \"## ----------------- ##\n## Output variables. ##\n## ----------------- ##\"\n    echo\n    for ac_var in $ac_subst_vars\n    do\n      eval ac_val=\\$$ac_var\n      case $ac_val in\n      *\\'\\''*) ac_val=`$as_echo \"$ac_val\" | sed \"s/'\\''/'\\''\\\\\\\\\\\\\\\\'\\'''\\''/g\"`;;\n      esac\n      $as_echo \"$ac_var='\\''$ac_val'\\''\"\n    done | sort\n    echo\n\n    if test -n \"$ac_subst_files\"; then\n      $as_echo \"## ------------------- ##\n## File substitutions. ##\n## ------------------- ##\"\n      echo\n      for ac_var in $ac_subst_files\n      do\n\teval ac_val=\\$$ac_var\n\tcase $ac_val in\n\t*\\'\\''*) ac_val=`$as_echo \"$ac_val\" | sed \"s/'\\''/'\\''\\\\\\\\\\\\\\\\'\\'''\\''/g\"`;;\n\tesac\n\t$as_echo \"$ac_var='\\''$ac_val'\\''\"\n      done | sort\n      echo\n    fi\n\n    if test -s confdefs.h; then\n      $as_echo \"## ----------- ##\n## confdefs.h. ##\n## ----------- ##\"\n      echo\n      cat confdefs.h\n      echo\n    fi\n    test \"$ac_signal\" != 0 &&\n      $as_echo \"$as_me: caught signal $ac_signal\"\n    $as_echo \"$as_me: exit $exit_status\"\n  } >&5\n  rm -f core *.core core.conftest.* &&\n    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&\n    exit $exit_status\n' 0\nfor ac_signal in 1 2 13 15; do\n  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal\ndone\nac_signal=0\n\n# confdefs.h avoids OS command line length limits that DEFS can exceed.\nrm -f -r conftest* confdefs.h\n\n$as_echo \"/* confdefs.h */\" > confdefs.h\n\n# Predefined preprocessor variables.\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_NAME \"$PACKAGE_NAME\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_VERSION \"$PACKAGE_VERSION\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_STRING \"$PACKAGE_STRING\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"\n_ACEOF\n\ncat >>confdefs.h <<_ACEOF\n#define PACKAGE_URL \"$PACKAGE_URL\"\n_ACEOF\n\n\n# Let the site file select an alternate cache file if it wants to.\n# Prefer an explicitly selected file to automatically selected ones.\nac_site_file1=NONE\nac_site_file2=NONE\nif test -n \"$CONFIG_SITE\"; then\n  # We do not want a PATH search for config.site.\n  case $CONFIG_SITE in #((\n    -*)  ac_site_file1=./$CONFIG_SITE;;\n    */*) ac_site_file1=$CONFIG_SITE;;\n    *)   ac_site_file1=./$CONFIG_SITE;;\n  esac\nelif test \"x$prefix\" != xNONE; then\n  ac_site_file1=$prefix/share/config.site\n  ac_site_file2=$prefix/etc/config.site\nelse\n  ac_site_file1=$ac_default_prefix/share/config.site\n  ac_site_file2=$ac_default_prefix/etc/config.site\nfi\nfor ac_site_file in \"$ac_site_file1\" \"$ac_site_file2\"\ndo\n  test \"x$ac_site_file\" = xNONE && continue\n  if test /dev/null != \"$ac_site_file\" && test -r \"$ac_site_file\"; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file\" >&5\n$as_echo \"$as_me: loading site script $ac_site_file\" >&6;}\n    sed 's/^/| /' \"$ac_site_file\" >&5\n    . \"$ac_site_file\" \\\n      || { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error $? \"failed to load site script $ac_site_file\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\n  fi\ndone\n\nif test -r \"$cache_file\"; then\n  # Some versions of bash will fail to source /dev/null (special files\n  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.\n  if test /dev/null != \"$cache_file\" && test -f \"$cache_file\"; then\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: loading cache $cache_file\" >&5\n$as_echo \"$as_me: loading cache $cache_file\" >&6;}\n    case $cache_file in\n      [\\\\/]* | ?:[\\\\/]* ) . \"$cache_file\";;\n      *)                      . \"./$cache_file\";;\n    esac\n  fi\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: creating cache $cache_file\" >&5\n$as_echo \"$as_me: creating cache $cache_file\" >&6;}\n  >$cache_file\nfi\n\n# Check that the precious variables saved in the cache have kept the same\n# value.\nac_cache_corrupted=false\nfor ac_var in $ac_precious_vars; do\n  eval ac_old_set=\\$ac_cv_env_${ac_var}_set\n  eval ac_new_set=\\$ac_env_${ac_var}_set\n  eval ac_old_val=\\$ac_cv_env_${ac_var}_value\n  eval ac_new_val=\\$ac_env_${ac_var}_value\n  case $ac_old_set,$ac_new_set in\n    set,)\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: error: \\`$ac_var' was set to \\`$ac_old_val' in the previous run\" >&5\n$as_echo \"$as_me: error: \\`$ac_var' was set to \\`$ac_old_val' in the previous run\" >&2;}\n      ac_cache_corrupted=: ;;\n    ,set)\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: error: \\`$ac_var' was not set in the previous run\" >&5\n$as_echo \"$as_me: error: \\`$ac_var' was not set in the previous run\" >&2;}\n      ac_cache_corrupted=: ;;\n    ,);;\n    *)\n      if test \"x$ac_old_val\" != \"x$ac_new_val\"; then\n\t# differences in whitespace do not lead to failure.\n\tac_old_val_w=`echo x $ac_old_val`\n\tac_new_val_w=`echo x $ac_new_val`\n\tif test \"$ac_old_val_w\" != \"$ac_new_val_w\"; then\n\t  { $as_echo \"$as_me:${as_lineno-$LINENO}: error: \\`$ac_var' has changed since the previous run:\" >&5\n$as_echo \"$as_me: error: \\`$ac_var' has changed since the previous run:\" >&2;}\n\t  ac_cache_corrupted=:\n\telse\n\t  { $as_echo \"$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \\`$ac_var' since the previous run:\" >&5\n$as_echo \"$as_me: warning: ignoring whitespace changes in \\`$ac_var' since the previous run:\" >&2;}\n\t  eval $ac_var=\\$ac_old_val\n\tfi\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}:   former value:  \\`$ac_old_val'\" >&5\n$as_echo \"$as_me:   former value:  \\`$ac_old_val'\" >&2;}\n\t{ $as_echo \"$as_me:${as_lineno-$LINENO}:   current value: \\`$ac_new_val'\" >&5\n$as_echo \"$as_me:   current value: \\`$ac_new_val'\" >&2;}\n      fi;;\n  esac\n  # Pass precious variables to config.status.\n  if test \"$ac_new_set\" = set; then\n    case $ac_new_val in\n    *\\'*) ac_arg=$ac_var=`$as_echo \"$ac_new_val\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    *) ac_arg=$ac_var=$ac_new_val ;;\n    esac\n    case \" $ac_configure_args \" in\n      *\" '$ac_arg' \"*) ;; # Avoid dups.  Use of quotes ensures accuracy.\n      *) as_fn_append ac_configure_args \" '$ac_arg'\" ;;\n    esac\n  fi\ndone\nif $ac_cache_corrupted; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build\" >&5\n$as_echo \"$as_me: error: changes in the environment can compromise the build\" >&2;}\n  as_fn_error $? \"run \\`make distclean' and/or \\`rm $cache_file' and start over\" \"$LINENO\" 5\nfi\n## -------------------- ##\n## Main body of script. ##\n## -------------------- ##\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n\n#AC_CONFIG_HEADERS([config.h])\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}gcc\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}gcc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_CC+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_CC=\"${ac_tool_prefix}gcc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_CC\"; then\n  ac_ct_CC=$CC\n  # Extract the first word of \"gcc\", so it can be a program name with args.\nset dummy gcc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_ac_ct_CC+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_CC\"; then\n  ac_cv_prog_ac_ct_CC=\"$ac_ct_CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_ac_ct_CC=\"gcc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_CC=$ac_cv_prog_ac_ct_CC\nif test -n \"$ac_ct_CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC\" >&5\n$as_echo \"$ac_ct_CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_CC\" = x; then\n    CC=\"\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    CC=$ac_ct_CC\n  fi\nelse\n  CC=\"$ac_cv_prog_CC\"\nfi\n\nif test -z \"$CC\"; then\n          if test -n \"$ac_tool_prefix\"; then\n    # Extract the first word of \"${ac_tool_prefix}cc\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}cc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_CC+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_CC=\"${ac_tool_prefix}cc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  fi\nfi\nif test -z \"$CC\"; then\n  # Extract the first word of \"cc\", so it can be a program name with args.\nset dummy cc; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_CC+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\n  ac_prog_rejected=no\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    if test \"$as_dir/$ac_word$ac_exec_ext\" = \"/usr/ucb/cc\"; then\n       ac_prog_rejected=yes\n       continue\n     fi\n    ac_cv_prog_CC=\"cc\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nif test $ac_prog_rejected = yes; then\n  # We found a bogon in the path, so make sure we never use it.\n  set dummy $ac_cv_prog_CC\n  shift\n  if test $# != 0; then\n    # We chose a different compiler from the bogus one.\n    # However, it has the same basename, so the bogon will be chosen\n    # first if we set CC to just the basename; use the full file name.\n    shift\n    ac_cv_prog_CC=\"$as_dir/$ac_word${1+' '}$@\"\n  fi\nfi\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$CC\"; then\n  if test -n \"$ac_tool_prefix\"; then\n  for ac_prog in cl.exe\n  do\n    # Extract the first word of \"$ac_tool_prefix$ac_prog\", so it can be a program name with args.\nset dummy $ac_tool_prefix$ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_CC+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CC\"; then\n  ac_cv_prog_CC=\"$CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_CC=\"$ac_tool_prefix$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCC=$ac_cv_prog_CC\nif test -n \"$CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CC\" >&5\n$as_echo \"$CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n    test -n \"$CC\" && break\n  done\nfi\nif test -z \"$CC\"; then\n  ac_ct_CC=$CC\n  for ac_prog in cl.exe\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_ac_ct_CC+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_CC\"; then\n  ac_cv_prog_ac_ct_CC=\"$ac_ct_CC\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_ac_ct_CC=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_CC=$ac_cv_prog_ac_ct_CC\nif test -n \"$ac_ct_CC\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC\" >&5\n$as_echo \"$ac_ct_CC\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$ac_ct_CC\" && break\ndone\n\n  if test \"x$ac_ct_CC\" = x; then\n    CC=\"\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    CC=$ac_ct_CC\n  fi\nfi\n\nfi\n\n\ntest -z \"$CC\" && { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error $? \"no acceptable C compiler found in \\$PATH\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\n\n# Provide some information about the compiler.\n$as_echo \"$as_me:${as_lineno-$LINENO}: checking for C compiler version\" >&5\nset X $ac_compile\nac_compiler=$2\nfor ac_option in --version -v -V -qversion; do\n  { { ac_try=\"$ac_compiler $ac_option >&5\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compiler $ac_option >&5\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    sed '10a\\\n... rest of stderr output deleted ...\n         10q' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n  fi\n  rm -f conftest.er1 conftest.err\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\ndone\n\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nac_clean_files_save=$ac_clean_files\nac_clean_files=\"$ac_clean_files a.out a.out.dSYM a.exe b.out\"\n# Try to create an executable without -o first, disregard a.out.\n# It will help us diagnose broken compilers, and finding out an intuition\n# of exeext.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether the C compiler works\" >&5\n$as_echo_n \"checking whether the C compiler works... \" >&6; }\nac_link_default=`$as_echo \"$ac_link\" | sed 's/ -o *conftest[^ ]*//'`\n\n# The possible output files:\nac_files=\"a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*\"\n\nac_rmfiles=\nfor ac_file in $ac_files\ndo\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;\n    * ) ac_rmfiles=\"$ac_rmfiles $ac_file\";;\n  esac\ndone\nrm -f $ac_rmfiles\n\nif { { ac_try=\"$ac_link_default\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link_default\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then :\n  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.\n# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'\n# in a Makefile.  We should not override ac_cv_exeext if it was cached,\n# so that the user can short-circuit this test for compilers unknown to\n# Autoconf.\nfor ac_file in $ac_files ''\ndo\n  test -f \"$ac_file\" || continue\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )\n\t;;\n    [ab].out )\n\t# We found the default executable, but exeext='' is most\n\t# certainly right.\n\tbreak;;\n    *.* )\n\tif test \"${ac_cv_exeext+set}\" = set && test \"$ac_cv_exeext\" != no;\n\tthen :; else\n\t   ac_cv_exeext=`expr \"$ac_file\" : '[^.]*\\(\\..*\\)'`\n\tfi\n\t# We set ac_cv_exeext here because the later test for it is not\n\t# safe: cross compilers may not add the suffix if given an `-o'\n\t# argument, so we may need to know it at that point already.\n\t# Even if this section looks crufty: it has the advantage of\n\t# actually working.\n\tbreak;;\n    * )\n\tbreak;;\n  esac\ndone\ntest \"$ac_cv_exeext\" = no && ac_cv_exeext=\n\nelse\n  ac_file=''\nfi\nif test -z \"$ac_file\"; then :\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\n$as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n{ { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error 77 \"C compiler cannot create executables\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name\" >&5\n$as_echo_n \"checking for C compiler default output file name... \" >&6; }\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_file\" >&5\n$as_echo \"$ac_file\" >&6; }\nac_exeext=$ac_cv_exeext\n\nrm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out\nac_clean_files=$ac_clean_files_save\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for suffix of executables\" >&5\n$as_echo_n \"checking for suffix of executables... \" >&6; }\nif { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then :\n  # If both `conftest.exe' and `conftest' are `present' (well, observable)\n# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will\n# work properly (i.e., refer to `conftest.exe'), while it won't with\n# `rm'.\nfor ac_file in conftest.exe conftest conftest.*; do\n  test -f \"$ac_file\" || continue\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;\n    *.* ) ac_cv_exeext=`expr \"$ac_file\" : '[^.]*\\(\\..*\\)'`\n\t  break;;\n    * ) break;;\n  esac\ndone\nelse\n  { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error $? \"cannot compute suffix of executables: cannot compile and link\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\nfi\nrm -f conftest conftest$ac_cv_exeext\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext\" >&5\n$as_echo \"$ac_cv_exeext\" >&6; }\n\nrm -f conftest.$ac_ext\nEXEEXT=$ac_cv_exeext\nac_exeext=$EXEEXT\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdio.h>\nint\nmain ()\n{\nFILE *f = fopen (\"conftest.out\", \"w\");\n return ferror (f) || fclose (f) != 0;\n\n  ;\n  return 0;\n}\n_ACEOF\nac_clean_files=\"$ac_clean_files conftest.out\"\n# Check that the compiler produces executables we can run.  If not, either\n# the compiler is broken, or we cross compile.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling\" >&5\n$as_echo_n \"checking whether we are cross compiling... \" >&6; }\nif test \"$cross_compiling\" != yes; then\n  { { ac_try=\"$ac_link\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_link\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\n  if { ac_try='./conftest$ac_cv_exeext'\n  { { case \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_try\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; }; then\n    cross_compiling=no\n  else\n    if test \"$cross_compiling\" = maybe; then\n\tcross_compiling=yes\n    else\n\t{ { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error $? \"cannot run C compiled programs.\nIf you meant to cross compile, use \\`--host'.\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\n    fi\n  fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $cross_compiling\" >&5\n$as_echo \"$cross_compiling\" >&6; }\n\nrm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out\nac_clean_files=$ac_clean_files_save\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for suffix of object files\" >&5\n$as_echo_n \"checking for suffix of object files... \" >&6; }\nif ${ac_cv_objext+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nrm -f conftest.o conftest.obj\nif { { ac_try=\"$ac_compile\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compile\") 2>&5\n  ac_status=$?\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }; then :\n  for ac_file in conftest.o conftest.obj conftest.*; do\n  test -f \"$ac_file\" || continue;\n  case $ac_file in\n    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;\n    *) ac_cv_objext=`expr \"$ac_file\" : '.*\\.\\(.*\\)'`\n       break;;\n  esac\ndone\nelse\n  $as_echo \"$as_me: failed program was:\" >&5\nsed 's/^/| /' conftest.$ac_ext >&5\n\n{ { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error $? \"cannot compute suffix of object files: cannot compile\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\nfi\nrm -f conftest.$ac_cv_objext conftest.$ac_ext\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext\" >&5\n$as_echo \"$ac_cv_objext\" >&6; }\nOBJEXT=$ac_cv_objext\nac_objext=$OBJEXT\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler\" >&5\n$as_echo_n \"checking whether we are using the GNU C compiler... \" >&6; }\nif ${ac_cv_c_compiler_gnu+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n#ifndef __GNUC__\n       choke me\n#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_compiler_gnu=yes\nelse\n  ac_compiler_gnu=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nac_cv_c_compiler_gnu=$ac_compiler_gnu\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu\" >&5\n$as_echo \"$ac_cv_c_compiler_gnu\" >&6; }\nif test $ac_compiler_gnu = yes; then\n  GCC=yes\nelse\n  GCC=\nfi\nac_test_CFLAGS=${CFLAGS+set}\nac_save_CFLAGS=$CFLAGS\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g\" >&5\n$as_echo_n \"checking whether $CC accepts -g... \" >&6; }\nif ${ac_cv_prog_cc_g+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_save_c_werror_flag=$ac_c_werror_flag\n   ac_c_werror_flag=yes\n   ac_cv_prog_cc_g=no\n   CFLAGS=\"-g\"\n   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_g=yes\nelse\n  CFLAGS=\"\"\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n\nelse\n  ac_c_werror_flag=$ac_save_c_werror_flag\n\t CFLAGS=\"-g\"\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_g=yes\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n   ac_c_werror_flag=$ac_save_c_werror_flag\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g\" >&5\n$as_echo \"$ac_cv_prog_cc_g\" >&6; }\nif test \"$ac_test_CFLAGS\" = set; then\n  CFLAGS=$ac_save_CFLAGS\nelif test $ac_cv_prog_cc_g = yes; then\n  if test \"$GCC\" = yes; then\n    CFLAGS=\"-g -O2\"\n  else\n    CFLAGS=\"-g\"\n  fi\nelse\n  if test \"$GCC\" = yes; then\n    CFLAGS=\"-O2\"\n  else\n    CFLAGS=\n  fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89\" >&5\n$as_echo_n \"checking for $CC option to accept ISO C89... \" >&6; }\nif ${ac_cv_prog_cc_c89+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_cv_prog_cc_c89=no\nac_save_CC=$CC\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdarg.h>\n#include <stdio.h>\nstruct stat;\n/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */\nstruct buf { int x; };\nFILE * (*rcsopen) (struct buf *, struct stat *, int);\nstatic char *e (p, i)\n     char **p;\n     int i;\n{\n  return p[i];\n}\nstatic char *f (char * (*g) (char **, int), char **p, ...)\n{\n  char *s;\n  va_list v;\n  va_start (v,p);\n  s = g (p, va_arg (v,int));\n  va_end (v);\n  return s;\n}\n\n/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has\n   function prototypes and stuff, but not '\\xHH' hex character constants.\n   These don't provoke an error unfortunately, instead are silently treated\n   as 'x'.  The following induces an error, until -std is added to get\n   proper ANSI mode.  Curiously '\\x00'!='x' always comes out true, for an\n   array size at least.  It's necessary to write '\\x00'==0 to get something\n   that's true only with -std.  */\nint osf4_cc_array ['\\x00' == 0 ? 1 : -1];\n\n/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters\n   inside strings and character constants.  */\n#define FOO(x) 'x'\nint xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];\n\nint test (int i, double x);\nstruct s1 {int (*f) (int a);};\nstruct s2 {int (*f) (double a);};\nint pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);\nint argc;\nchar **argv;\nint\nmain ()\n{\nreturn f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];\n  ;\n  return 0;\n}\n_ACEOF\nfor ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \\\n\t-Ae \"-Aa -D_HPUX_SOURCE\" \"-Xc -D__EXTENSIONS__\"\ndo\n  CC=\"$ac_save_CC $ac_arg\"\n  if ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cc_c89=$ac_arg\nfi\nrm -f core conftest.err conftest.$ac_objext\n  test \"x$ac_cv_prog_cc_c89\" != \"xno\" && break\ndone\nrm -f conftest.$ac_ext\nCC=$ac_save_CC\n\nfi\n# AC_CACHE_VAL\ncase \"x$ac_cv_prog_cc_c89\" in\n  x)\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: none needed\" >&5\n$as_echo \"none needed\" >&6; } ;;\n  xno)\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: unsupported\" >&5\n$as_echo \"unsupported\" >&6; } ;;\n  *)\n    CC=\"$CC $ac_cv_prog_cc_c89\"\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89\" >&5\n$as_echo \"$ac_cv_prog_cc_c89\" >&6; } ;;\nesac\nif test \"x$ac_cv_prog_cc_c89\" != xno; then :\n\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nac_ext=cpp\nac_cpp='$CXXCPP $CPPFLAGS'\nac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_cxx_compiler_gnu\nif test -z \"$CXX\"; then\n  if test -n \"$CCC\"; then\n    CXX=$CCC\n  else\n    if test -n \"$ac_tool_prefix\"; then\n  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC\n  do\n    # Extract the first word of \"$ac_tool_prefix$ac_prog\", so it can be a program name with args.\nset dummy $ac_tool_prefix$ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_CXX+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$CXX\"; then\n  ac_cv_prog_CXX=\"$CXX\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_CXX=\"$ac_tool_prefix$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nCXX=$ac_cv_prog_CXX\nif test -n \"$CXX\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CXX\" >&5\n$as_echo \"$CXX\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n    test -n \"$CXX\" && break\n  done\nfi\nif test -z \"$CXX\"; then\n  ac_ct_CXX=$CXX\n  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC\ndo\n  # Extract the first word of \"$ac_prog\", so it can be a program name with args.\nset dummy $ac_prog; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_ac_ct_CXX+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_CXX\"; then\n  ac_cv_prog_ac_ct_CXX=\"$ac_ct_CXX\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_ac_ct_CXX=\"$ac_prog\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_CXX=$ac_cv_prog_ac_ct_CXX\nif test -n \"$ac_ct_CXX\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX\" >&5\n$as_echo \"$ac_ct_CXX\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\n  test -n \"$ac_ct_CXX\" && break\ndone\n\n  if test \"x$ac_ct_CXX\" = x; then\n    CXX=\"g++\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    CXX=$ac_ct_CXX\n  fi\nfi\n\n  fi\nfi\n# Provide some information about the compiler.\n$as_echo \"$as_me:${as_lineno-$LINENO}: checking for C++ compiler version\" >&5\nset X $ac_compile\nac_compiler=$2\nfor ac_option in --version -v -V -qversion; do\n  { { ac_try=\"$ac_compiler $ac_option >&5\"\ncase \"(($ac_try\" in\n  *\\\"* | *\\`* | *\\\\*) ac_try_echo=\\$ac_try;;\n  *) ac_try_echo=$ac_try;;\nesac\neval ac_try_echo=\"\\\"\\$as_me:${as_lineno-$LINENO}: $ac_try_echo\\\"\"\n$as_echo \"$ac_try_echo\"; } >&5\n  (eval \"$ac_compiler $ac_option >&5\") 2>conftest.err\n  ac_status=$?\n  if test -s conftest.err; then\n    sed '10a\\\n... rest of stderr output deleted ...\n         10q' conftest.err >conftest.er1\n    cat conftest.er1 >&5\n  fi\n  rm -f conftest.er1 conftest.err\n  $as_echo \"$as_me:${as_lineno-$LINENO}: \\$? = $ac_status\" >&5\n  test $ac_status = 0; }\ndone\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler\" >&5\n$as_echo_n \"checking whether we are using the GNU C++ compiler... \" >&6; }\nif ${ac_cv_cxx_compiler_gnu+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n#ifndef __GNUC__\n       choke me\n#endif\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_compiler_gnu=yes\nelse\n  ac_compiler_gnu=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nac_cv_cxx_compiler_gnu=$ac_compiler_gnu\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu\" >&5\n$as_echo \"$ac_cv_cxx_compiler_gnu\" >&6; }\nif test $ac_compiler_gnu = yes; then\n  GXX=yes\nelse\n  GXX=\nfi\nac_test_CXXFLAGS=${CXXFLAGS+set}\nac_save_CXXFLAGS=$CXXFLAGS\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g\" >&5\n$as_echo_n \"checking whether $CXX accepts -g... \" >&6; }\nif ${ac_cv_prog_cxx_g+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_save_cxx_werror_flag=$ac_cxx_werror_flag\n   ac_cxx_werror_flag=yes\n   ac_cv_prog_cxx_g=no\n   CXXFLAGS=\"-g\"\n   cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cxx_g=yes\nelse\n  CXXFLAGS=\"\"\n      cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n\nelse\n  ac_cxx_werror_flag=$ac_save_cxx_werror_flag\n\t CXXFLAGS=\"-g\"\n\t cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_cxx_try_compile \"$LINENO\"; then :\n  ac_cv_prog_cxx_g=yes\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n   ac_cxx_werror_flag=$ac_save_cxx_werror_flag\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g\" >&5\n$as_echo \"$ac_cv_prog_cxx_g\" >&6; }\nif test \"$ac_test_CXXFLAGS\" = set; then\n  CXXFLAGS=$ac_save_CXXFLAGS\nelif test $ac_cv_prog_cxx_g = yes; then\n  if test \"$GXX\" = yes; then\n    CXXFLAGS=\"-g -O2\"\n  else\n    CXXFLAGS=\"-g\"\n  fi\nelse\n  if test \"$GXX\" = yes; then\n    CXXFLAGS=\"-O2\"\n  else\n    CXXFLAGS=\n  fi\nfi\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\nac_aux_dir=\nfor ac_dir in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"; do\n  if test -f \"$ac_dir/install-sh\"; then\n    ac_aux_dir=$ac_dir\n    ac_install_sh=\"$ac_aux_dir/install-sh -c\"\n    break\n  elif test -f \"$ac_dir/install.sh\"; then\n    ac_aux_dir=$ac_dir\n    ac_install_sh=\"$ac_aux_dir/install.sh -c\"\n    break\n  elif test -f \"$ac_dir/shtool\"; then\n    ac_aux_dir=$ac_dir\n    ac_install_sh=\"$ac_aux_dir/shtool install -c\"\n    break\n  fi\ndone\nif test -z \"$ac_aux_dir\"; then\n  as_fn_error $? \"cannot find install-sh, install.sh, or shtool in \\\"$srcdir\\\" \\\"$srcdir/..\\\" \\\"$srcdir/../..\\\"\" \"$LINENO\" 5\nfi\n\n# These three variables are undocumented and unsupported,\n# and are intended to be withdrawn in a future Autoconf release.\n# They can cause serious problems if a builder's source tree is in a directory\n# whose full name contains unusual characters.\nac_config_guess=\"$SHELL $ac_aux_dir/config.guess\"  # Please don't use this var.\nac_config_sub=\"$SHELL $ac_aux_dir/config.sub\"  # Please don't use this var.\nac_configure=\"$SHELL $ac_aux_dir/configure\"  # Please don't use this var.\n\n\n# Find a good install program.  We prefer a C program (faster),\n# so one script is as good as another.  But avoid the broken or\n# incompatible versions:\n# SysV /etc/install, /usr/sbin/install\n# SunOS /usr/etc/install\n# IRIX /sbin/install\n# AIX /bin/install\n# AmigaOS /C/install, which installs bootblocks on floppy discs\n# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag\n# AFS /usr/afsws/bin/install, which mishandles nonexistent args\n# SVR4 /usr/ucb/install, which tries to use the nonexistent group \"staff\"\n# OS/2's system install, which has a completely different semantic\n# ./install, which can be erroneously created by make from ./install.sh.\n# Reject install programs that cannot install multiple files.\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install\" >&5\n$as_echo_n \"checking for a BSD-compatible install... \" >&6; }\nif test -z \"$INSTALL\"; then\nif ${ac_cv_path_install+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    # Account for people who put trailing slashes in PATH elements.\ncase $as_dir/ in #((\n  ./ | .// | /[cC]/* | \\\n  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \\\n  ?:[\\\\/]os2[\\\\/]install[\\\\/]* | ?:[\\\\/]OS2[\\\\/]INSTALL[\\\\/]* | \\\n  /usr/ucb/* ) ;;\n  *)\n    # OSF1 and SCO ODT 3.0 have their own names for install.\n    # Don't use installbsd from OSF since it installs stuff as root\n    # by default.\n    for ac_prog in ginstall scoinst install; do\n      for ac_exec_ext in '' $ac_executable_extensions; do\n\tif as_fn_executable_p \"$as_dir/$ac_prog$ac_exec_ext\"; then\n\t  if test $ac_prog = install &&\n\t    grep dspmsg \"$as_dir/$ac_prog$ac_exec_ext\" >/dev/null 2>&1; then\n\t    # AIX install.  It has an incompatible calling convention.\n\t    :\n\t  elif test $ac_prog = install &&\n\t    grep pwplus \"$as_dir/$ac_prog$ac_exec_ext\" >/dev/null 2>&1; then\n\t    # program-specific install script used by HP pwplus--don't use.\n\t    :\n\t  else\n\t    rm -rf conftest.one conftest.two conftest.dir\n\t    echo one > conftest.one\n\t    echo two > conftest.two\n\t    mkdir conftest.dir\n\t    if \"$as_dir/$ac_prog$ac_exec_ext\" -c conftest.one conftest.two \"`pwd`/conftest.dir\" &&\n\t      test -s conftest.one && test -s conftest.two &&\n\t      test -s conftest.dir/conftest.one &&\n\t      test -s conftest.dir/conftest.two\n\t    then\n\t      ac_cv_path_install=\"$as_dir/$ac_prog$ac_exec_ext -c\"\n\t      break 3\n\t    fi\n\t  fi\n\tfi\n      done\n    done\n    ;;\nesac\n\n  done\nIFS=$as_save_IFS\n\nrm -rf conftest.one conftest.two conftest.dir\n\nfi\n  if test \"${ac_cv_path_install+set}\" = set; then\n    INSTALL=$ac_cv_path_install\n  else\n    # As a last resort, use the slow shell script.  Don't cache a\n    # value for INSTALL within a source directory, because that will\n    # break other packages using the cache if that directory is\n    # removed, or if the value is a relative name.\n    INSTALL=$ac_install_sh\n  fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $INSTALL\" >&5\n$as_echo \"$INSTALL\" >&6; }\n\n# Use test -z because SunOS4 sh mishandles braces in ${var-val}.\n# It thinks the first close brace ends the variable substitution.\ntest -z \"$INSTALL_PROGRAM\" && INSTALL_PROGRAM='${INSTALL}'\n\ntest -z \"$INSTALL_SCRIPT\" && INSTALL_SCRIPT='${INSTALL}'\n\ntest -z \"$INSTALL_DATA\" && INSTALL_DATA='${INSTALL} -m 644'\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking whether ln -s works\" >&5\n$as_echo_n \"checking whether ln -s works... \" >&6; }\nLN_S=$as_ln_s\nif test \"$LN_S\" = \"ln -s\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: yes\" >&5\n$as_echo \"yes\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no, using $LN_S\" >&5\n$as_echo \"no, using $LN_S\" >&6; }\nfi\n\nif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}ranlib\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}ranlib; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_RANLIB+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$RANLIB\"; then\n  ac_cv_prog_RANLIB=\"$RANLIB\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_RANLIB=\"${ac_tool_prefix}ranlib\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nRANLIB=$ac_cv_prog_RANLIB\nif test -n \"$RANLIB\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $RANLIB\" >&5\n$as_echo \"$RANLIB\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_prog_RANLIB\"; then\n  ac_ct_RANLIB=$RANLIB\n  # Extract the first word of \"ranlib\", so it can be a program name with args.\nset dummy ranlib; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_prog_ac_ct_RANLIB+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -n \"$ac_ct_RANLIB\"; then\n  ac_cv_prog_ac_ct_RANLIB=\"$ac_ct_RANLIB\" # Let the user override the test.\nelse\nas_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_prog_ac_ct_RANLIB=\"ranlib\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\nfi\nfi\nac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB\nif test -n \"$ac_ct_RANLIB\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB\" >&5\n$as_echo \"$ac_ct_RANLIB\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_ct_RANLIB\" = x; then\n    RANLIB=\":\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    RANLIB=$ac_ct_RANLIB\n  fi\nelse\n  RANLIB=\"$ac_cv_prog_RANLIB\"\nfi\n\n\n# checking pthread library\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for main in -lpthread\" >&5\n$as_echo_n \"checking for main in -lpthread... \" >&6; }\nif ${ac_cv_lib_pthread_main+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  ac_check_lib_save_LIBS=$LIBS\nLIBS=\"-lpthread  $LIBS\"\ncat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n\n\nint\nmain ()\n{\nreturn main ();\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_link \"$LINENO\"; then :\n  ac_cv_lib_pthread_main=yes\nelse\n  ac_cv_lib_pthread_main=no\nfi\nrm -f core conftest.err conftest.$ac_objext \\\n    conftest$ac_exeext conftest.$ac_ext\nLIBS=$ac_check_lib_save_LIBS\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main\" >&5\n$as_echo \"$ac_cv_lib_pthread_main\" >&6; }\nif test \"x$ac_cv_lib_pthread_main\" = xyes; then :\n  cat >>confdefs.h <<_ACEOF\n#define HAVE_LIBPTHREAD 1\n_ACEOF\n\n  LIBS=\"-lpthread $LIBS\"\n\nelse\n  as_fn_error $? \"*** POSIX thread support not installed - please install first ***\" \"$LINENO\" 5\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor\" >&5\n$as_echo_n \"checking how to run the C preprocessor... \" >&6; }\n# On Suns, sometimes $CPP names a directory.\nif test -n \"$CPP\" && test -d \"$CPP\"; then\n  CPP=\nfi\nif test -z \"$CPP\"; then\n  if ${ac_cv_prog_CPP+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n      # Double quotes because CPP needs to be expanded\n    for CPP in \"$CC -E\" \"$CC -E -traditional-cpp\" \"/lib/cpp\"\n    do\n      ac_preproc_ok=false\nfor ac_c_preproc_warn_flag in '' yes\ndo\n  # Use a header file that comes with gcc, so configuring glibc\n  # with a fresh cross-compiler works.\n  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n  # <limits.h> exists even on freestanding compilers.\n  # On the NeXT, cc -E runs the code through the compiler's parser,\n  # not just through cpp. \"Syntax error\" is here to catch this case.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\t\t     Syntax error\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n\nelse\n  # Broken: fails on valid input.\ncontinue\nfi\nrm -f conftest.err conftest.i conftest.$ac_ext\n\n  # OK, works on sane cases.  Now check whether nonexistent headers\n  # can be detected and how.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ac_nonexistent.h>\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n  # Broken: success on invalid input.\ncontinue\nelse\n  # Passes both tests.\nac_preproc_ok=:\nbreak\nfi\nrm -f conftest.err conftest.i conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.i conftest.err conftest.$ac_ext\nif $ac_preproc_ok; then :\n  break\nfi\n\n    done\n    ac_cv_prog_CPP=$CPP\n\nfi\n  CPP=$ac_cv_prog_CPP\nelse\n  ac_cv_prog_CPP=$CPP\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $CPP\" >&5\n$as_echo \"$CPP\" >&6; }\nac_preproc_ok=false\nfor ac_c_preproc_warn_flag in '' yes\ndo\n  # Use a header file that comes with gcc, so configuring glibc\n  # with a fresh cross-compiler works.\n  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since\n  # <limits.h> exists even on freestanding compilers.\n  # On the NeXT, cc -E runs the code through the compiler's parser,\n  # not just through cpp. \"Syntax error\" is here to catch this case.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#ifdef __STDC__\n# include <limits.h>\n#else\n# include <assert.h>\n#endif\n\t\t     Syntax error\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n\nelse\n  # Broken: fails on valid input.\ncontinue\nfi\nrm -f conftest.err conftest.i conftest.$ac_ext\n\n  # OK, works on sane cases.  Now check whether nonexistent headers\n  # can be detected and how.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ac_nonexistent.h>\n_ACEOF\nif ac_fn_c_try_cpp \"$LINENO\"; then :\n  # Broken: success on invalid input.\ncontinue\nelse\n  # Passes both tests.\nac_preproc_ok=:\nbreak\nfi\nrm -f conftest.err conftest.i conftest.$ac_ext\n\ndone\n# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.\nrm -f conftest.i conftest.err conftest.$ac_ext\nif $ac_preproc_ok; then :\n\nelse\n  { { $as_echo \"$as_me:${as_lineno-$LINENO}: error: in \\`$ac_pwd':\" >&5\n$as_echo \"$as_me: error: in \\`$ac_pwd':\" >&2;}\nas_fn_error $? \"C preprocessor \\\"$CPP\\\" fails sanity check\nSee \\`config.log' for more details\" \"$LINENO\" 5; }\nfi\n\nac_ext=c\nac_cpp='$CPP $CPPFLAGS'\nac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'\nac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'\nac_compiler_gnu=$ac_cv_c_compiler_gnu\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e\" >&5\n$as_echo_n \"checking for grep that handles long lines and -e... \" >&6; }\nif ${ac_cv_path_GREP+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if test -z \"$GREP\"; then\n  ac_path_GREP_found=false\n  # Loop through the user's path and test for each of PROGNAME-LIST\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_prog in grep ggrep; do\n    for ac_exec_ext in '' $ac_executable_extensions; do\n      ac_path_GREP=\"$as_dir/$ac_prog$ac_exec_ext\"\n      as_fn_executable_p \"$ac_path_GREP\" || continue\n# Check for GNU ac_path_GREP and select it if it is found.\n  # Check for GNU $ac_path_GREP\ncase `\"$ac_path_GREP\" --version 2>&1` in\n*GNU*)\n  ac_cv_path_GREP=\"$ac_path_GREP\" ac_path_GREP_found=:;;\n*)\n  ac_count=0\n  $as_echo_n 0123456789 >\"conftest.in\"\n  while :\n  do\n    cat \"conftest.in\" \"conftest.in\" >\"conftest.tmp\"\n    mv \"conftest.tmp\" \"conftest.in\"\n    cp \"conftest.in\" \"conftest.nl\"\n    $as_echo 'GREP' >> \"conftest.nl\"\n    \"$ac_path_GREP\" -e 'GREP$' -e '-(cannot match)-' < \"conftest.nl\" >\"conftest.out\" 2>/dev/null || break\n    diff \"conftest.out\" \"conftest.nl\" >/dev/null 2>&1 || break\n    as_fn_arith $ac_count + 1 && ac_count=$as_val\n    if test $ac_count -gt ${ac_path_GREP_max-0}; then\n      # Best one so far, save it but keep looking for a better one\n      ac_cv_path_GREP=\"$ac_path_GREP\"\n      ac_path_GREP_max=$ac_count\n    fi\n    # 10*(2^10) chars as input seems more than enough\n    test $ac_count -gt 10 && break\n  done\n  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;\nesac\n\n      $ac_path_GREP_found && break 3\n    done\n  done\n  done\nIFS=$as_save_IFS\n  if test -z \"$ac_cv_path_GREP\"; then\n    as_fn_error $? \"no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin\" \"$LINENO\" 5\n  fi\nelse\n  ac_cv_path_GREP=$GREP\nfi\n\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP\" >&5\n$as_echo \"$ac_cv_path_GREP\" >&6; }\n GREP=\"$ac_cv_path_GREP\"\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for egrep\" >&5\n$as_echo_n \"checking for egrep... \" >&6; }\nif ${ac_cv_path_EGREP+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1\n   then ac_cv_path_EGREP=\"$GREP -E\"\n   else\n     if test -z \"$EGREP\"; then\n  ac_path_EGREP_found=false\n  # Loop through the user's path and test for each of PROGNAME-LIST\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_prog in egrep; do\n    for ac_exec_ext in '' $ac_executable_extensions; do\n      ac_path_EGREP=\"$as_dir/$ac_prog$ac_exec_ext\"\n      as_fn_executable_p \"$ac_path_EGREP\" || continue\n# Check for GNU ac_path_EGREP and select it if it is found.\n  # Check for GNU $ac_path_EGREP\ncase `\"$ac_path_EGREP\" --version 2>&1` in\n*GNU*)\n  ac_cv_path_EGREP=\"$ac_path_EGREP\" ac_path_EGREP_found=:;;\n*)\n  ac_count=0\n  $as_echo_n 0123456789 >\"conftest.in\"\n  while :\n  do\n    cat \"conftest.in\" \"conftest.in\" >\"conftest.tmp\"\n    mv \"conftest.tmp\" \"conftest.in\"\n    cp \"conftest.in\" \"conftest.nl\"\n    $as_echo 'EGREP' >> \"conftest.nl\"\n    \"$ac_path_EGREP\" 'EGREP$' < \"conftest.nl\" >\"conftest.out\" 2>/dev/null || break\n    diff \"conftest.out\" \"conftest.nl\" >/dev/null 2>&1 || break\n    as_fn_arith $ac_count + 1 && ac_count=$as_val\n    if test $ac_count -gt ${ac_path_EGREP_max-0}; then\n      # Best one so far, save it but keep looking for a better one\n      ac_cv_path_EGREP=\"$ac_path_EGREP\"\n      ac_path_EGREP_max=$ac_count\n    fi\n    # 10*(2^10) chars as input seems more than enough\n    test $ac_count -gt 10 && break\n  done\n  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;\nesac\n\n      $ac_path_EGREP_found && break 3\n    done\n  done\n  done\nIFS=$as_save_IFS\n  if test -z \"$ac_cv_path_EGREP\"; then\n    as_fn_error $? \"no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin\" \"$LINENO\" 5\n  fi\nelse\n  ac_cv_path_EGREP=$EGREP\nfi\n\n   fi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP\" >&5\n$as_echo \"$ac_cv_path_EGREP\" >&6; }\n EGREP=\"$ac_cv_path_EGREP\"\n\n\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for ANSI C header files\" >&5\n$as_echo_n \"checking for ANSI C header files... \" >&6; }\nif ${ac_cv_header_stdc+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdlib.h>\n#include <stdarg.h>\n#include <string.h>\n#include <float.h>\n\nint\nmain ()\n{\n\n  ;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_compile \"$LINENO\"; then :\n  ac_cv_header_stdc=yes\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f core conftest.err conftest.$ac_objext conftest.$ac_ext\n\nif test $ac_cv_header_stdc = yes; then\n  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <string.h>\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"memchr\" >/dev/null 2>&1; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f conftest*\n\nfi\n\nif test $ac_cv_header_stdc = yes; then\n  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <stdlib.h>\n\n_ACEOF\nif (eval \"$ac_cpp conftest.$ac_ext\") 2>&5 |\n  $EGREP \"free\" >/dev/null 2>&1; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f conftest*\n\nfi\n\nif test $ac_cv_header_stdc = yes; then\n  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.\n  if test \"$cross_compiling\" = yes; then :\n  :\nelse\n  cat confdefs.h - <<_ACEOF >conftest.$ac_ext\n/* end confdefs.h.  */\n#include <ctype.h>\n#include <stdlib.h>\n#if ((' ' & 0x0FF) == 0x020)\n# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')\n# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))\n#else\n# define ISLOWER(c) \\\n\t\t   (('a' <= (c) && (c) <= 'i') \\\n\t\t     || ('j' <= (c) && (c) <= 'r') \\\n\t\t     || ('s' <= (c) && (c) <= 'z'))\n# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))\n#endif\n\n#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))\nint\nmain ()\n{\n  int i;\n  for (i = 0; i < 256; i++)\n    if (XOR (islower (i), ISLOWER (i))\n\t|| toupper (i) != TOUPPER (i))\n      return 2;\n  return 0;\n}\n_ACEOF\nif ac_fn_c_try_run \"$LINENO\"; then :\n\nelse\n  ac_cv_header_stdc=no\nfi\nrm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \\\n  conftest.$ac_objext conftest.beam conftest.$ac_ext\nfi\n\nfi\nfi\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc\" >&5\n$as_echo \"$ac_cv_header_stdc\" >&6; }\nif test $ac_cv_header_stdc = yes; then\n\n$as_echo \"#define STDC_HEADERS 1\" >>confdefs.h\n\nfi\n\n# On IRIX 5.3, sys/types and inttypes.h are conflicting.\nfor ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \\\n\t\t  inttypes.h stdint.h unistd.h\ndo :\n  as_ac_Header=`$as_echo \"ac_cv_header_$ac_header\" | $as_tr_sh`\nac_fn_c_check_header_compile \"$LINENO\" \"$ac_header\" \"$as_ac_Header\" \"$ac_includes_default\n\"\nif eval test \\\"x\\$\"$as_ac_Header\"\\\" = x\"yes\"; then :\n  cat >>confdefs.h <<_ACEOF\n#define `$as_echo \"HAVE_$ac_header\" | $as_tr_cpp` 1\n_ACEOF\n\nfi\n\ndone\n\n\nac_fn_c_check_header_mongrel \"$LINENO\" \"pthread.h\" \"ac_cv_header_pthread_h\" \"$ac_includes_default\"\nif test \"x$ac_cv_header_pthread_h\" = xyes; then :\n\nelse\n  as_fn_error $? \"*** POSIX thread support not installed - please install first ***\" \"$LINENO\" 5\nfi\n\n\n\n\nHAVE_FATAL_WARNINGS=\"\"\n# Check whether --enable-fatal_warnings was given.\nif test \"${enable_fatal_warnings+set}\" = set; then :\n  enableval=$enable_fatal_warnings;\nfi\n\nif test \"x$enable_fatal_warnings\" = \"xyes\"; then :\n\n\tHAVE_FATAL_WARNINGS=\"-W -Wall -Werror\"\n\n\nfi\n\n\n\nQMAKE=\"\"\n\n# Check whether --with-qmake was given.\nif test \"${with_qmake+set}\" = set; then :\n  withval=$with_qmake;\n\tqmake=\"$withval\"\n\tQMAKE=\"$qmake\"\n\nelse\n\n\tif test -n \"$ac_tool_prefix\"; then\n  # Extract the first word of \"${ac_tool_prefix}qmake\", so it can be a program name with args.\nset dummy ${ac_tool_prefix}qmake; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_path_QMAKE+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  case $QMAKE in\n  [\\\\/]* | ?:[\\\\/]*)\n  ac_cv_path_QMAKE=\"$QMAKE\" # Let the user override the test with a path.\n  ;;\n  *)\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_path_QMAKE=\"$as_dir/$ac_word$ac_exec_ext\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\n  ;;\nesac\nfi\nQMAKE=$ac_cv_path_QMAKE\nif test -n \"$QMAKE\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $QMAKE\" >&5\n$as_echo \"$QMAKE\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n\nfi\nif test -z \"$ac_cv_path_QMAKE\"; then\n  ac_pt_QMAKE=$QMAKE\n  # Extract the first word of \"qmake\", so it can be a program name with args.\nset dummy qmake; ac_word=$2\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: checking for $ac_word\" >&5\n$as_echo_n \"checking for $ac_word... \" >&6; }\nif ${ac_cv_path_ac_pt_QMAKE+:} false; then :\n  $as_echo_n \"(cached) \" >&6\nelse\n  case $ac_pt_QMAKE in\n  [\\\\/]* | ?:[\\\\/]*)\n  ac_cv_path_ac_pt_QMAKE=\"$ac_pt_QMAKE\" # Let the user override the test with a path.\n  ;;\n  *)\n  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    for ac_exec_ext in '' $ac_executable_extensions; do\n  if as_fn_executable_p \"$as_dir/$ac_word$ac_exec_ext\"; then\n    ac_cv_path_ac_pt_QMAKE=\"$as_dir/$ac_word$ac_exec_ext\"\n    $as_echo \"$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext\" >&5\n    break 2\n  fi\ndone\n  done\nIFS=$as_save_IFS\n\n  ;;\nesac\nfi\nac_pt_QMAKE=$ac_cv_path_ac_pt_QMAKE\nif test -n \"$ac_pt_QMAKE\"; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: $ac_pt_QMAKE\" >&5\n$as_echo \"$ac_pt_QMAKE\" >&6; }\nelse\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: result: no\" >&5\n$as_echo \"no\" >&6; }\nfi\n\n  if test \"x$ac_pt_QMAKE\" = x; then\n    QMAKE=\"\"\n  else\n    case $cross_compiling:$ac_tool_warned in\nyes:)\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet\" >&5\n$as_echo \"$as_me: WARNING: using cross tools not prefixed with host triplet\" >&2;}\nac_tool_warned=yes ;;\nesac\n    QMAKE=$ac_pt_QMAKE\n  fi\nelse\n  QMAKE=\"$ac_cv_path_QMAKE\"\nfi\n\n\n\nfi\n\necho \"trying $QMAKE\"\n\n\n#if test -f /usr/lib64/qt4/bin/qmake; then\n#\tQMAKE=/usr/lib64/qt4/bin/qmake\n#fi\n\nif test -z \"$QMAKE\"\nthen\n\tas_fn_error $? \"qmake and/or Qt are missing, please install them.\" \"$LINENO\" 5\nfi\nif test -f \"$QMAKE\"\nthen\n\techo \"found $QMAKE\"\nelse\n\tas_fn_error $? \"qmake and/or Qt are missing, please install them.\" \"$LINENO\" 5\nfi\n\n$QMAKE -v\n\ncd src/firetools && CXXFLAGS=\"$CXXFLAGS $HAVE_FATAL_WARNINGS\" $QMAKE && cd ../..\ncd src/firejail-ui && CXXFLAGS=\"$CXXFLAGS $HAVE_FATAL_WARNINGS\" $QMAKE && cd ../..\ncd src/fstats && CXXFLAGS=\"$CXXFLAGS $HAVE_FATAL_WARNINGS\" $QMAKE && cd ../..\ncd src/fmgr && CXXFLAGS=\"$CXXFLAGS $HAVE_FATAL_WARNINGS\" $QMAKE && cd ../..\n\ncp confdefs.h firetools_config.h\nac_config_files=\"$ac_config_files Makefile\"\n\ncat >confcache <<\\_ACEOF\n# This file is a shell script that caches the results of configure\n# tests run on this system so they can be shared between configure\n# scripts and configure runs, see configure's option --config-cache.\n# It is not useful on other systems.  If it contains results you don't\n# want to keep, you may remove or edit it.\n#\n# config.status only pays attention to the cache file if you give it\n# the --recheck option to rerun configure.\n#\n# `ac_cv_env_foo' variables (set or unset) will be overridden when\n# loading this file, other *unset* `ac_cv_foo' will be assigned the\n# following values.\n\n_ACEOF\n\n# The following way of writing the cache mishandles newlines in values,\n# but we know of no workaround that is simple, portable, and efficient.\n# So, we kill variables containing newlines.\n# Ultrix sh set writes to stderr and can't be redirected directly,\n# and sets the high bit in the cache file unless we assign to the vars.\n(\n  for ac_var in `(set) 2>&1 | sed -n 's/^\\([a-zA-Z_][a-zA-Z0-9_]*\\)=.*/\\1/p'`; do\n    eval ac_val=\\$$ac_var\n    case $ac_val in #(\n    *${as_nl}*)\n      case $ac_var in #(\n      *_cv_*) { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline\" >&5\n$as_echo \"$as_me: WARNING: cache variable $ac_var contains a newline\" >&2;} ;;\n      esac\n      case $ac_var in #(\n      _ | IFS | as_nl) ;; #(\n      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(\n      *) { eval $ac_var=; unset $ac_var;} ;;\n      esac ;;\n    esac\n  done\n\n  (set) 2>&1 |\n    case $as_nl`(ac_space=' '; set) 2>&1` in #(\n    *${as_nl}ac_space=\\ *)\n      # `set' does not quote correctly, so add quotes: double-quote\n      # substitution turns \\\\\\\\ into \\\\, and sed turns \\\\ into \\.\n      sed -n \\\n\t\"s/'/'\\\\\\\\''/g;\n\t  s/^\\\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\\\)=\\\\(.*\\\\)/\\\\1='\\\\2'/p\"\n      ;; #(\n    *)\n      # `set' quotes correctly as required by POSIX, so do not add quotes.\n      sed -n \"/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p\"\n      ;;\n    esac |\n    sort\n) |\n  sed '\n     /^ac_cv_env_/b end\n     t clear\n     :clear\n     s/^\\([^=]*\\)=\\(.*[{}].*\\)$/test \"${\\1+set}\" = set || &/\n     t end\n     s/^\\([^=]*\\)=\\(.*\\)$/\\1=${\\1=\\2}/\n     :end' >>confcache\nif diff \"$cache_file\" confcache >/dev/null 2>&1; then :; else\n  if test -w \"$cache_file\"; then\n    if test \"x$cache_file\" != \"x/dev/null\"; then\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: updating cache $cache_file\" >&5\n$as_echo \"$as_me: updating cache $cache_file\" >&6;}\n      if test ! -f \"$cache_file\" || test -h \"$cache_file\"; then\n\tcat confcache >\"$cache_file\"\n      else\n        case $cache_file in #(\n        */* | ?:*)\n\t  mv -f confcache \"$cache_file\"$$ &&\n\t  mv -f \"$cache_file\"$$ \"$cache_file\" ;; #(\n        *)\n\t  mv -f confcache \"$cache_file\" ;;\n\tesac\n      fi\n    fi\n  else\n    { $as_echo \"$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file\" >&5\n$as_echo \"$as_me: not updating unwritable cache $cache_file\" >&6;}\n  fi\nfi\nrm -f confcache\n\ntest \"x$prefix\" = xNONE && prefix=$ac_default_prefix\n# Let make expand exec_prefix.\ntest \"x$exec_prefix\" = xNONE && exec_prefix='${prefix}'\n\n# Transform confdefs.h into DEFS.\n# Protect against shell expansion while executing Makefile rules.\n# Protect against Makefile macro expansion.\n#\n# If the first sed substitution is executed (which looks for macros that\n# take arguments), then branch to the quote section.  Otherwise,\n# look for a macro that doesn't take arguments.\nac_script='\n:mline\n/\\\\$/{\n N\n s,\\\\\\n,,\n b mline\n}\nt clear\n:clear\ns/^[\t ]*#[\t ]*define[\t ][\t ]*\\([^\t (][^\t (]*([^)]*)\\)[\t ]*\\(.*\\)/-D\\1=\\2/g\nt quote\ns/^[\t ]*#[\t ]*define[\t ][\t ]*\\([^\t ][^\t ]*\\)[\t ]*\\(.*\\)/-D\\1=\\2/g\nt quote\nb any\n:quote\ns/[\t `~#$^&*(){}\\\\|;'\\''\"<>?]/\\\\&/g\ns/\\[/\\\\&/g\ns/\\]/\\\\&/g\ns/\\$/$$/g\nH\n:any\n${\n\tg\n\ts/^\\n//\n\ts/\\n/ /g\n\tp\n}\n'\nDEFS=`sed -n \"$ac_script\" confdefs.h`\n\n\nac_libobjs=\nac_ltlibobjs=\nU=\nfor ac_i in : $LIBOBJS; do test \"x$ac_i\" = x: && continue\n  # 1. Remove the extension, and $U if already installed.\n  ac_script='s/\\$U\\././;s/\\.o$//;s/\\.obj$//'\n  ac_i=`$as_echo \"$ac_i\" | sed \"$ac_script\"`\n  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR\n  #    will be set to the directory where LIBOBJS objects are built.\n  as_fn_append ac_libobjs \" \\${LIBOBJDIR}$ac_i\\$U.$ac_objext\"\n  as_fn_append ac_ltlibobjs \" \\${LIBOBJDIR}$ac_i\"'$U.lo'\ndone\nLIBOBJS=$ac_libobjs\n\nLTLIBOBJS=$ac_ltlibobjs\n\n\n\n: \"${CONFIG_STATUS=./config.status}\"\nac_write_fail=0\nac_clean_files_save=$ac_clean_files\nac_clean_files=\"$ac_clean_files $CONFIG_STATUS\"\n{ $as_echo \"$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS\" >&5\n$as_echo \"$as_me: creating $CONFIG_STATUS\" >&6;}\nas_write_fail=0\ncat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1\n#! $SHELL\n# Generated by $as_me.\n# Run this file to recreate the current configuration.\n# Compiler output produced by configure, useful for debugging\n# configure, is in config.log if it exists.\n\ndebug=false\nac_cs_recheck=false\nac_cs_silent=false\n\nSHELL=\\${CONFIG_SHELL-$SHELL}\nexport SHELL\n_ASEOF\ncat >>$CONFIG_STATUS <<\\_ASEOF || as_write_fail=1\n## -------------------- ##\n## M4sh Initialization. ##\n## -------------------- ##\n\n# Be more Bourne compatible\nDUALCASE=1; export DUALCASE # for MKS sh\nif test -n \"${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :\n  emulate sh\n  NULLCMD=:\n  # Pre-4.2 versions of Zsh do word splitting on ${1+\"$@\"}, which\n  # is contrary to our usage.  Disable this feature.\n  alias -g '${1+\"$@\"}'='\"$@\"'\n  setopt NO_GLOB_SUBST\nelse\n  case `(set -o) 2>/dev/null` in #(\n  *posix*) :\n    set -o posix ;; #(\n  *) :\n     ;;\nesac\nfi\n\n\nas_nl='\n'\nexport as_nl\n# Printing a long string crashes Solaris 7 /usr/bin/printf.\nas_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo\nas_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo\n# Prefer a ksh shell builtin over an external printf program on Solaris,\n# but without wasting forks for bash or zsh.\nif test -z \"$BASH_VERSION$ZSH_VERSION\" \\\n    && (test \"X`print -r -- $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='print -r --'\n  as_echo_n='print -rn --'\nelif (test \"X`printf %s $as_echo`\" = \"X$as_echo\") 2>/dev/null; then\n  as_echo='printf %s\\n'\n  as_echo_n='printf %s'\nelse\n  if test \"X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`\" = \"X-n $as_echo\"; then\n    as_echo_body='eval /usr/ucb/echo -n \"$1$as_nl\"'\n    as_echo_n='/usr/ucb/echo -n'\n  else\n    as_echo_body='eval expr \"X$1\" : \"X\\\\(.*\\\\)\"'\n    as_echo_n_body='eval\n      arg=$1;\n      case $arg in #(\n      *\"$as_nl\"*)\n\texpr \"X$arg\" : \"X\\\\(.*\\\\)$as_nl\";\n\targ=`expr \"X$arg\" : \".*$as_nl\\\\(.*\\\\)\"`;;\n      esac;\n      expr \"X$arg\" : \"X\\\\(.*\\\\)\" | tr -d \"$as_nl\"\n    '\n    export as_echo_n_body\n    as_echo_n='sh -c $as_echo_n_body as_echo'\n  fi\n  export as_echo_body\n  as_echo='sh -c $as_echo_body as_echo'\nfi\n\n# The user is always right.\nif test \"${PATH_SEPARATOR+set}\" != set; then\n  PATH_SEPARATOR=:\n  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {\n    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||\n      PATH_SEPARATOR=';'\n  }\nfi\n\n\n# IFS\n# We need space, tab and new line, in precisely that order.  Quoting is\n# there to prevent editors from complaining about space-tab.\n# (If _AS_PATH_WALK were called with IFS unset, it would disable word\n# splitting by setting IFS to empty value.)\nIFS=\" \"\"\t$as_nl\"\n\n# Find who we are.  Look in the path if we contain no directory separator.\nas_myself=\ncase $0 in #((\n  *[\\\\/]* ) as_myself=$0 ;;\n  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR\nfor as_dir in $PATH\ndo\n  IFS=$as_save_IFS\n  test -z \"$as_dir\" && as_dir=.\n    test -r \"$as_dir/$0\" && as_myself=$as_dir/$0 && break\n  done\nIFS=$as_save_IFS\n\n     ;;\nesac\n# We did not find ourselves, most probably we were run as `sh COMMAND'\n# in which case we are not to be found in the path.\nif test \"x$as_myself\" = x; then\n  as_myself=$0\nfi\nif test ! -f \"$as_myself\"; then\n  $as_echo \"$as_myself: error: cannot find myself; rerun with an absolute file name\" >&2\n  exit 1\nfi\n\n# Unset variables that we do not need and which cause bugs (e.g. in\n# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the \"|| exit 1\"\n# suppresses any \"Segmentation fault\" message there.  '((' could\n# trigger a bug in pdksh 5.2.14.\nfor as_var in BASH_ENV ENV MAIL MAILPATH\ndo eval test x\\${$as_var+set} = xset \\\n  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :\ndone\nPS1='$ '\nPS2='> '\nPS4='+ '\n\n# NLS nuisances.\nLC_ALL=C\nexport LC_ALL\nLANGUAGE=C\nexport LANGUAGE\n\n# CDPATH.\n(unset CDPATH) >/dev/null 2>&1 && unset CDPATH\n\n\n# as_fn_error STATUS ERROR [LINENO LOG_FD]\n# ----------------------------------------\n# Output \"`basename $0`: error: ERROR\" to stderr. If LINENO and LOG_FD are\n# provided, also output the error to LOG_FD, referencing LINENO. Then exit the\n# script with STATUS, using 1 if that was 0.\nas_fn_error ()\n{\n  as_status=$1; test $as_status -eq 0 && as_status=1\n  if test \"$4\"; then\n    as_lineno=${as_lineno-\"$3\"} as_lineno_stack=as_lineno_stack=$as_lineno_stack\n    $as_echo \"$as_me:${as_lineno-$LINENO}: error: $2\" >&$4\n  fi\n  $as_echo \"$as_me: error: $2\" >&2\n  as_fn_exit $as_status\n} # as_fn_error\n\n\n# as_fn_set_status STATUS\n# -----------------------\n# Set $? to STATUS, without forking.\nas_fn_set_status ()\n{\n  return $1\n} # as_fn_set_status\n\n# as_fn_exit STATUS\n# -----------------\n# Exit the shell with STATUS, even in a \"trap 0\" or \"set -e\" context.\nas_fn_exit ()\n{\n  set +e\n  as_fn_set_status $1\n  exit $1\n} # as_fn_exit\n\n# as_fn_unset VAR\n# ---------------\n# Portably unset VAR.\nas_fn_unset ()\n{\n  { eval $1=; unset $1;}\n}\nas_unset=as_fn_unset\n# as_fn_append VAR VALUE\n# ----------------------\n# Append the text in VALUE to the end of the definition contained in VAR. Take\n# advantage of any shell optimizations that allow amortized linear growth over\n# repeated appends, instead of the typical quadratic growth present in naive\n# implementations.\nif (eval \"as_var=1; as_var+=2; test x\\$as_var = x12\") 2>/dev/null; then :\n  eval 'as_fn_append ()\n  {\n    eval $1+=\\$2\n  }'\nelse\n  as_fn_append ()\n  {\n    eval $1=\\$$1\\$2\n  }\nfi # as_fn_append\n\n# as_fn_arith ARG...\n# ------------------\n# Perform arithmetic evaluation on the ARGs, and store the result in the\n# global $as_val. Take advantage of shells that can avoid forks. The arguments\n# must be portable across $(()) and expr.\nif (eval \"test \\$(( 1 + 1 )) = 2\") 2>/dev/null; then :\n  eval 'as_fn_arith ()\n  {\n    as_val=$(( $* ))\n  }'\nelse\n  as_fn_arith ()\n  {\n    as_val=`expr \"$@\" || test $? -eq 1`\n  }\nfi # as_fn_arith\n\n\nif expr a : '\\(a\\)' >/dev/null 2>&1 &&\n   test \"X`expr 00001 : '.*\\(...\\)'`\" = X001; then\n  as_expr=expr\nelse\n  as_expr=false\nfi\n\nif (basename -- /) >/dev/null 2>&1 && test \"X`basename -- / 2>&1`\" = \"X/\"; then\n  as_basename=basename\nelse\n  as_basename=false\nfi\n\nif (as_dir=`dirname -- /` && test \"X$as_dir\" = X/) >/dev/null 2>&1; then\n  as_dirname=dirname\nelse\n  as_dirname=false\nfi\n\nas_me=`$as_basename -- \"$0\" ||\n$as_expr X/\"$0\" : '.*/\\([^/][^/]*\\)/*$' \\| \\\n\t X\"$0\" : 'X\\(//\\)$' \\| \\\n\t X\"$0\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X/\"$0\" |\n    sed '/^.*\\/\\([^/][^/]*\\)\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\/\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n\n# Avoid depending upon Character Ranges.\nas_cr_letters='abcdefghijklmnopqrstuvwxyz'\nas_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'\nas_cr_Letters=$as_cr_letters$as_cr_LETTERS\nas_cr_digits='0123456789'\nas_cr_alnum=$as_cr_Letters$as_cr_digits\n\nECHO_C= ECHO_N= ECHO_T=\ncase `echo -n x` in #(((((\n-n*)\n  case `echo 'xy\\c'` in\n  *c*) ECHO_T='\t';;\t# ECHO_T is single tab character.\n  xy)  ECHO_C='\\c';;\n  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null\n       ECHO_T='\t';;\n  esac;;\n*)\n  ECHO_N='-n';;\nesac\n\nrm -f conf$$ conf$$.exe conf$$.file\nif test -d conf$$.dir; then\n  rm -f conf$$.dir/conf$$.file\nelse\n  rm -f conf$$.dir\n  mkdir conf$$.dir 2>/dev/null\nfi\nif (echo >conf$$.file) 2>/dev/null; then\n  if ln -s conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s='ln -s'\n    # ... but there are two gotchas:\n    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.\n    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.\n    # In both cases, we have to default to `cp -pR'.\n    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||\n      as_ln_s='cp -pR'\n  elif ln conf$$.file conf$$ 2>/dev/null; then\n    as_ln_s=ln\n  else\n    as_ln_s='cp -pR'\n  fi\nelse\n  as_ln_s='cp -pR'\nfi\nrm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file\nrmdir conf$$.dir 2>/dev/null\n\n\n# as_fn_mkdir_p\n# -------------\n# Create \"$as_dir\" as a directory, including parents if necessary.\nas_fn_mkdir_p ()\n{\n\n  case $as_dir in #(\n  -*) as_dir=./$as_dir;;\n  esac\n  test -d \"$as_dir\" || eval $as_mkdir_p || {\n    as_dirs=\n    while :; do\n      case $as_dir in #(\n      *\\'*) as_qdir=`$as_echo \"$as_dir\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;; #'(\n      *) as_qdir=$as_dir;;\n      esac\n      as_dirs=\"'$as_qdir' $as_dirs\"\n      as_dir=`$as_dirname -- \"$as_dir\" ||\n$as_expr X\"$as_dir\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$as_dir\" : 'X\\(//\\)$' \\| \\\n\t X\"$as_dir\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$as_dir\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n      test -d \"$as_dir\" && break\n    done\n    test -z \"$as_dirs\" || eval \"mkdir $as_dirs\"\n  } || test -d \"$as_dir\" || as_fn_error $? \"cannot create directory $as_dir\"\n\n\n} # as_fn_mkdir_p\nif mkdir -p . 2>/dev/null; then\n  as_mkdir_p='mkdir -p \"$as_dir\"'\nelse\n  test -d ./-p && rmdir ./-p\n  as_mkdir_p=false\nfi\n\n\n# as_fn_executable_p FILE\n# -----------------------\n# Test if FILE is an executable regular file.\nas_fn_executable_p ()\n{\n  test -f \"$1\" && test -x \"$1\"\n} # as_fn_executable_p\nas_test_x='test -x'\nas_executable_p=as_fn_executable_p\n\n# Sed expression to map a string onto a valid CPP name.\nas_tr_cpp=\"eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'\"\n\n# Sed expression to map a string onto a valid variable name.\nas_tr_sh=\"eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'\"\n\n\nexec 6>&1\n## ----------------------------------- ##\n## Main body of $CONFIG_STATUS script. ##\n## ----------------------------------- ##\n_ASEOF\ntest $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n# Save the log message, to keep $0 and so on meaningful, and to\n# report actual input values of CONFIG_FILES etc. instead of their\n# values after options handling.\nac_log=\"\nThis file was extended by firetools $as_me 0.9.73, which was\ngenerated by GNU Autoconf 2.69.  Invocation command line was\n\n  CONFIG_FILES    = $CONFIG_FILES\n  CONFIG_HEADERS  = $CONFIG_HEADERS\n  CONFIG_LINKS    = $CONFIG_LINKS\n  CONFIG_COMMANDS = $CONFIG_COMMANDS\n  $ $0 $@\n\non `(hostname || uname -n) 2>/dev/null | sed 1q`\n\"\n\n_ACEOF\n\ncase $ac_config_files in *\"\n\"*) set x $ac_config_files; shift; ac_config_files=$*;;\nesac\n\n\n\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n# Files that config.status was made for.\nconfig_files=\"$ac_config_files\"\n\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nac_cs_usage=\"\\\n\\`$as_me' instantiates files and other configuration actions\nfrom templates according to the current configuration.  Unless the files\nand actions are specified as TAGs, all are instantiated by default.\n\nUsage: $0 [OPTION]... [TAG]...\n\n  -h, --help       print this help, then exit\n  -V, --version    print version number and configuration settings, then exit\n      --config     print configuration, then exit\n  -q, --quiet, --silent\n                   do not print progress messages\n  -d, --debug      don't remove temporary files\n      --recheck    update $as_me by reconfiguring in the same conditions\n      --file=FILE[:TEMPLATE]\n                   instantiate the configuration file FILE\n\nConfiguration files:\n$config_files\n\nReport bugs to <netblue30@yahoo.com>.\nfiretools home page: <http://firejail.wordpress.com>.\"\n\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\nac_cs_config=\"`$as_echo \"$ac_configure_args\" | sed 's/^ //; s/[\\\\\"\"\\`\\$]/\\\\\\\\&/g'`\"\nac_cs_version=\"\\\\\nfiretools config.status 0.9.73\nconfigured by $0, generated by GNU Autoconf 2.69,\n  with options \\\\\"\\$ac_cs_config\\\\\"\n\nCopyright (C) 2012 Free Software Foundation, Inc.\nThis config.status script is free software; the Free Software Foundation\ngives unlimited permission to copy, distribute and modify it.\"\n\nac_pwd='$ac_pwd'\nsrcdir='$srcdir'\nINSTALL='$INSTALL'\ntest -n \"\\$AWK\" || AWK=awk\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n# The default lists apply if the user does not specify any file.\nac_need_defaults=:\nwhile test $# != 0\ndo\n  case $1 in\n  --*=?*)\n    ac_option=`expr \"X$1\" : 'X\\([^=]*\\)='`\n    ac_optarg=`expr \"X$1\" : 'X[^=]*=\\(.*\\)'`\n    ac_shift=:\n    ;;\n  --*=)\n    ac_option=`expr \"X$1\" : 'X\\([^=]*\\)='`\n    ac_optarg=\n    ac_shift=:\n    ;;\n  *)\n    ac_option=$1\n    ac_optarg=$2\n    ac_shift=shift\n    ;;\n  esac\n\n  case $ac_option in\n  # Handling of the options.\n  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)\n    ac_cs_recheck=: ;;\n  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )\n    $as_echo \"$ac_cs_version\"; exit ;;\n  --config | --confi | --conf | --con | --co | --c )\n    $as_echo \"$ac_cs_config\"; exit ;;\n  --debug | --debu | --deb | --de | --d | -d )\n    debug=: ;;\n  --file | --fil | --fi | --f )\n    $ac_shift\n    case $ac_optarg in\n    *\\'*) ac_optarg=`$as_echo \"$ac_optarg\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"` ;;\n    '') as_fn_error $? \"missing file argument\" ;;\n    esac\n    as_fn_append CONFIG_FILES \" '$ac_optarg'\"\n    ac_need_defaults=false;;\n  --he | --h |  --help | --hel | -h )\n    $as_echo \"$ac_cs_usage\"; exit ;;\n  -q | -quiet | --quiet | --quie | --qui | --qu | --q \\\n  | -silent | --silent | --silen | --sile | --sil | --si | --s)\n    ac_cs_silent=: ;;\n\n  # This is an error.\n  -*) as_fn_error $? \"unrecognized option: \\`$1'\nTry \\`$0 --help' for more information.\" ;;\n\n  *) as_fn_append ac_config_targets \" $1\"\n     ac_need_defaults=false ;;\n\n  esac\n  shift\ndone\n\nac_configure_extra_args=\n\nif $ac_cs_silent; then\n  exec 6>/dev/null\n  ac_configure_extra_args=\"$ac_configure_extra_args --silent\"\nfi\n\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\nif \\$ac_cs_recheck; then\n  set X $SHELL '$0' $ac_configure_args \\$ac_configure_extra_args --no-create --no-recursion\n  shift\n  \\$as_echo \"running CONFIG_SHELL=$SHELL \\$*\" >&6\n  CONFIG_SHELL='$SHELL'\n  export CONFIG_SHELL\n  exec \"\\$@\"\nfi\n\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nexec 5>>config.log\n{\n  echo\n  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX\n## Running $as_me. ##\n_ASBOX\n  $as_echo \"$ac_log\"\n} >&5\n\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n\n# Handling of arguments.\nfor ac_config_target in $ac_config_targets\ndo\n  case $ac_config_target in\n    \"Makefile\") CONFIG_FILES=\"$CONFIG_FILES Makefile\" ;;\n\n  *) as_fn_error $? \"invalid argument: \\`$ac_config_target'\" \"$LINENO\" 5;;\n  esac\ndone\n\n\n# If the user did not use the arguments to specify the items to instantiate,\n# then the envvar interface is used.  Set only those that are not.\n# We use the long form for the default assignment because of an extremely\n# bizarre bug on SunOS 4.1.3.\nif $ac_need_defaults; then\n  test \"${CONFIG_FILES+set}\" = set || CONFIG_FILES=$config_files\nfi\n\n# Have a temporary directory for convenience.  Make it in the build tree\n# simply because there is no reason against having it here, and in addition,\n# creating and moving files from /tmp can sometimes cause problems.\n# Hook for its removal unless debugging.\n# Note that there is a small window in which the directory will not be cleaned:\n# after its creation but before its name has been assigned to `$tmp'.\n$debug ||\n{\n  tmp= ac_tmp=\n  trap 'exit_status=$?\n  : \"${ac_tmp:=$tmp}\"\n  { test ! -d \"$ac_tmp\" || rm -fr \"$ac_tmp\"; } && exit $exit_status\n' 0\n  trap 'as_fn_exit 1' 1 2 13 15\n}\n# Create a (secure) tmp directory for tmp files.\n\n{\n  tmp=`(umask 077 && mktemp -d \"./confXXXXXX\") 2>/dev/null` &&\n  test -d \"$tmp\"\n}  ||\n{\n  tmp=./conf$$-$RANDOM\n  (umask 077 && mkdir \"$tmp\")\n} || as_fn_error $? \"cannot create a temporary directory in .\" \"$LINENO\" 5\nac_tmp=$tmp\n\n# Set up the scripts for CONFIG_FILES section.\n# No need to generate them if there are no CONFIG_FILES.\n# This happens for instance with `./config.status config.h'.\nif test -n \"$CONFIG_FILES\"; then\n\n\nac_cr=`echo X | tr X '\\015'`\n# On cygwin, bash can eat \\r inside `` if the user requested igncr.\n# But we know of no other shell where ac_cr would be empty at this\n# point, so we can use a bashism as a fallback.\nif test \"x$ac_cr\" = x; then\n  eval ac_cr=\\$\\'\\\\r\\'\nfi\nac_cs_awk_cr=`$AWK 'BEGIN { print \"a\\rb\" }' </dev/null 2>/dev/null`\nif test \"$ac_cs_awk_cr\" = \"a${ac_cr}b\"; then\n  ac_cs_awk_cr='\\\\r'\nelse\n  ac_cs_awk_cr=$ac_cr\nfi\n\necho 'BEGIN {' >\"$ac_tmp/subs1.awk\" &&\n_ACEOF\n\n\n{\n  echo \"cat >conf$$subs.awk <<_ACEOF\" &&\n  echo \"$ac_subst_vars\" | sed 's/.*/&!$&$ac_delim/' &&\n  echo \"_ACEOF\"\n} >conf$$subs.sh ||\n  as_fn_error $? \"could not make $CONFIG_STATUS\" \"$LINENO\" 5\nac_delim_num=`echo \"$ac_subst_vars\" | grep -c '^'`\nac_delim='%!_!# '\nfor ac_last_try in false false false false false :; do\n  . ./conf$$subs.sh ||\n    as_fn_error $? \"could not make $CONFIG_STATUS\" \"$LINENO\" 5\n\n  ac_delim_n=`sed -n \"s/.*$ac_delim\\$/X/p\" conf$$subs.awk | grep -c X`\n  if test $ac_delim_n = $ac_delim_num; then\n    break\n  elif $ac_last_try; then\n    as_fn_error $? \"could not make $CONFIG_STATUS\" \"$LINENO\" 5\n  else\n    ac_delim=\"$ac_delim!$ac_delim _$ac_delim!! \"\n  fi\ndone\nrm -f conf$$subs.sh\n\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\ncat >>\"\\$ac_tmp/subs1.awk\" <<\\\\_ACAWK &&\n_ACEOF\nsed -n '\nh\ns/^/S[\"/; s/!.*/\"]=/\np\ng\ns/^[^!]*!//\n:repl\nt repl\ns/'\"$ac_delim\"'$//\nt delim\n:nl\nh\ns/\\(.\\{148\\}\\)..*/\\1/\nt more1\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\\\\n\"\\\\/\np\nn\nb repl\n:more1\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"\\\\/\np\ng\ns/.\\{148\\}//\nt nl\n:delim\nh\ns/\\(.\\{148\\}\\)..*/\\1/\nt more2\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"/\np\nb\n:more2\ns/[\"\\\\]/\\\\&/g; s/^/\"/; s/$/\"\\\\/\np\ng\ns/.\\{148\\}//\nt delim\n' <conf$$subs.awk | sed '\n/^[^\"\"]/{\n  N\n  s/\\n//\n}\n' >>$CONFIG_STATUS || ac_write_fail=1\nrm -f conf$$subs.awk\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n_ACAWK\ncat >>\"\\$ac_tmp/subs1.awk\" <<_ACAWK &&\n  for (key in S) S_is_set[key] = 1\n  FS = \"\u0007\"\n\n}\n{\n  line = $ 0\n  nfields = split(line, field, \"@\")\n  substed = 0\n  len = length(field[1])\n  for (i = 2; i < nfields; i++) {\n    key = field[i]\n    keylen = length(key)\n    if (S_is_set[key]) {\n      value = S[key]\n      line = substr(line, 1, len) \"\" value \"\" substr(line, len + keylen + 3)\n      len += length(value) + length(field[++i])\n      substed = 1\n    } else\n      len += 1 + keylen\n  }\n\n  print line\n}\n\n_ACAWK\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nif sed \"s/$ac_cr//\" < /dev/null > /dev/null 2>&1; then\n  sed \"s/$ac_cr\\$//; s/$ac_cr/$ac_cs_awk_cr/g\"\nelse\n  cat\nfi < \"$ac_tmp/subs1.awk\" > \"$ac_tmp/subs.awk\" \\\n  || as_fn_error $? \"could not setup config files machinery\" \"$LINENO\" 5\n_ACEOF\n\n# VPATH may cause trouble with some makes, so we remove sole $(srcdir),\n# ${srcdir} and @srcdir@ entries from VPATH if srcdir is \".\", strip leading and\n# trailing colons and then remove the whole line if VPATH becomes empty\n# (actually we leave an empty line to preserve line numbers).\nif test \"x$srcdir\" = x.; then\n  ac_vpsub='/^[\t ]*VPATH[\t ]*=[\t ]*/{\nh\ns///\ns/^/:/\ns/[\t ]*$/:/\ns/:\\$(srcdir):/:/g\ns/:\\${srcdir}:/:/g\ns/:@srcdir@:/:/g\ns/^:*//\ns/:*$//\nx\ns/\\(=[\t ]*\\).*/\\1/\nG\ns/\\n//\ns/^[^=]*=[\t ]*$//\n}'\nfi\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\nfi # test -n \"$CONFIG_FILES\"\n\n\neval set X \"  :F $CONFIG_FILES      \"\nshift\nfor ac_tag\ndo\n  case $ac_tag in\n  :[FHLC]) ac_mode=$ac_tag; continue;;\n  esac\n  case $ac_mode$ac_tag in\n  :[FHL]*:*);;\n  :L* | :C*:*) as_fn_error $? \"invalid tag \\`$ac_tag'\" \"$LINENO\" 5;;\n  :[FH]-) ac_tag=-:-;;\n  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;\n  esac\n  ac_save_IFS=$IFS\n  IFS=:\n  set x $ac_tag\n  IFS=$ac_save_IFS\n  shift\n  ac_file=$1\n  shift\n\n  case $ac_mode in\n  :L) ac_source=$1;;\n  :[FH])\n    ac_file_inputs=\n    for ac_f\n    do\n      case $ac_f in\n      -) ac_f=\"$ac_tmp/stdin\";;\n      *) # Look for the file first in the build tree, then in the source tree\n\t # (if the path is not absolute).  The absolute path cannot be DOS-style,\n\t # because $ac_f cannot contain `:'.\n\t test -f \"$ac_f\" ||\n\t   case $ac_f in\n\t   [\\\\/$]*) false;;\n\t   *) test -f \"$srcdir/$ac_f\" && ac_f=\"$srcdir/$ac_f\";;\n\t   esac ||\n\t   as_fn_error 1 \"cannot find input file: \\`$ac_f'\" \"$LINENO\" 5;;\n      esac\n      case $ac_f in *\\'*) ac_f=`$as_echo \"$ac_f\" | sed \"s/'/'\\\\\\\\\\\\\\\\''/g\"`;; esac\n      as_fn_append ac_file_inputs \" '$ac_f'\"\n    done\n\n    # Let's still pretend it is `configure' which instantiates (i.e., don't\n    # use $as_me), people would be surprised to read:\n    #    /* config.h.  Generated by config.status.  */\n    configure_input='Generated from '`\n\t  $as_echo \"$*\" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'\n\t`' by configure.'\n    if test x\"$ac_file\" != x-; then\n      configure_input=\"$ac_file.  $configure_input\"\n      { $as_echo \"$as_me:${as_lineno-$LINENO}: creating $ac_file\" >&5\n$as_echo \"$as_me: creating $ac_file\" >&6;}\n    fi\n    # Neutralize special characters interpreted by sed in replacement strings.\n    case $configure_input in #(\n    *\\&* | *\\|* | *\\\\* )\n       ac_sed_conf_input=`$as_echo \"$configure_input\" |\n       sed 's/[\\\\\\\\&|]/\\\\\\\\&/g'`;; #(\n    *) ac_sed_conf_input=$configure_input;;\n    esac\n\n    case $ac_tag in\n    *:-:* | *:-) cat >\"$ac_tmp/stdin\" \\\n      || as_fn_error $? \"could not create $ac_file\" \"$LINENO\" 5 ;;\n    esac\n    ;;\n  esac\n\n  ac_dir=`$as_dirname -- \"$ac_file\" ||\n$as_expr X\"$ac_file\" : 'X\\(.*[^/]\\)//*[^/][^/]*/*$' \\| \\\n\t X\"$ac_file\" : 'X\\(//\\)[^/]' \\| \\\n\t X\"$ac_file\" : 'X\\(//\\)$' \\| \\\n\t X\"$ac_file\" : 'X\\(/\\)' \\| . 2>/dev/null ||\n$as_echo X\"$ac_file\" |\n    sed '/^X\\(.*[^/]\\)\\/\\/*[^/][^/]*\\/*$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)[^/].*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\/\\)$/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  /^X\\(\\/\\).*/{\n\t    s//\\1/\n\t    q\n\t  }\n\t  s/.*/./; q'`\n  as_dir=\"$ac_dir\"; as_fn_mkdir_p\n  ac_builddir=.\n\ncase \"$ac_dir\" in\n.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;\n*)\n  ac_dir_suffix=/`$as_echo \"$ac_dir\" | sed 's|^\\.[\\\\/]||'`\n  # A \"..\" for each directory in $ac_dir_suffix.\n  ac_top_builddir_sub=`$as_echo \"$ac_dir_suffix\" | sed 's|/[^\\\\/]*|/..|g;s|/||'`\n  case $ac_top_builddir_sub in\n  \"\") ac_top_builddir_sub=. ac_top_build_prefix= ;;\n  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;\n  esac ;;\nesac\nac_abs_top_builddir=$ac_pwd\nac_abs_builddir=$ac_pwd$ac_dir_suffix\n# for backward compatibility:\nac_top_builddir=$ac_top_build_prefix\n\ncase $srcdir in\n  .)  # We are building in place.\n    ac_srcdir=.\n    ac_top_srcdir=$ac_top_builddir_sub\n    ac_abs_top_srcdir=$ac_pwd ;;\n  [\\\\/]* | ?:[\\\\/]* )  # Absolute name.\n    ac_srcdir=$srcdir$ac_dir_suffix;\n    ac_top_srcdir=$srcdir\n    ac_abs_top_srcdir=$srcdir ;;\n  *) # Relative name.\n    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix\n    ac_top_srcdir=$ac_top_build_prefix$srcdir\n    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;\nesac\nac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix\n\n\n  case $ac_mode in\n  :F)\n  #\n  # CONFIG_FILE\n  #\n\n  case $INSTALL in\n  [\\\\/$]* | ?:[\\\\/]* ) ac_INSTALL=$INSTALL ;;\n  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;\n  esac\n_ACEOF\n\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n# If the template does not know about datarootdir, expand it.\n# FIXME: This hack should be removed a few years after 2.60.\nac_datarootdir_hack=; ac_datarootdir_seen=\nac_sed_dataroot='\n/datarootdir/ {\n  p\n  q\n}\n/@datadir@/p\n/@docdir@/p\n/@infodir@/p\n/@localedir@/p\n/@mandir@/p'\ncase `eval \"sed -n \\\"\\$ac_sed_dataroot\\\" $ac_file_inputs\"` in\n*datarootdir*) ac_datarootdir_seen=yes;;\n*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting\" >&5\n$as_echo \"$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting\" >&2;}\n_ACEOF\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\n  ac_datarootdir_hack='\n  s&@datadir@&$datadir&g\n  s&@docdir@&$docdir&g\n  s&@infodir@&$infodir&g\n  s&@localedir@&$localedir&g\n  s&@mandir@&$mandir&g\n  s&\\\\\\${datarootdir}&$datarootdir&g' ;;\nesac\n_ACEOF\n\n# Neutralize VPATH when `$srcdir' = `.'.\n# Shell code in configure.ac might set extrasub.\n# FIXME: do we really want to maintain this feature?\ncat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1\nac_sed_extra=\"$ac_vpsub\n$extrasub\n_ACEOF\ncat >>$CONFIG_STATUS <<\\_ACEOF || ac_write_fail=1\n:t\n/@[a-zA-Z_][a-zA-Z_0-9]*@/!b\ns|@configure_input@|$ac_sed_conf_input|;t t\ns&@top_builddir@&$ac_top_builddir_sub&;t t\ns&@top_build_prefix@&$ac_top_build_prefix&;t t\ns&@srcdir@&$ac_srcdir&;t t\ns&@abs_srcdir@&$ac_abs_srcdir&;t t\ns&@top_srcdir@&$ac_top_srcdir&;t t\ns&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t\ns&@builddir@&$ac_builddir&;t t\ns&@abs_builddir@&$ac_abs_builddir&;t t\ns&@abs_top_builddir@&$ac_abs_top_builddir&;t t\ns&@INSTALL@&$ac_INSTALL&;t t\n$ac_datarootdir_hack\n\"\neval sed \\\"\\$ac_sed_extra\\\" \"$ac_file_inputs\" | $AWK -f \"$ac_tmp/subs.awk\" \\\n  >$ac_tmp/out || as_fn_error $? \"could not create $ac_file\" \"$LINENO\" 5\n\ntest -z \"$ac_datarootdir_hack$ac_datarootdir_seen\" &&\n  { ac_out=`sed -n '/\\${datarootdir}/p' \"$ac_tmp/out\"`; test -n \"$ac_out\"; } &&\n  { ac_out=`sed -n '/^[\t ]*datarootdir[\t ]*:*=/p' \\\n      \"$ac_tmp/out\"`; test -z \"$ac_out\"; } &&\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \\`datarootdir'\nwhich seems to be undefined.  Please make sure it is defined\" >&5\n$as_echo \"$as_me: WARNING: $ac_file contains a reference to the variable \\`datarootdir'\nwhich seems to be undefined.  Please make sure it is defined\" >&2;}\n\n  rm -f \"$ac_tmp/stdin\"\n  case $ac_file in\n  -) cat \"$ac_tmp/out\" && rm -f \"$ac_tmp/out\";;\n  *) rm -f \"$ac_file\" && mv \"$ac_tmp/out\" \"$ac_file\";;\n  esac \\\n  || as_fn_error $? \"could not create $ac_file\" \"$LINENO\" 5\n ;;\n\n\n\n  esac\n\ndone # for ac_tag\n\n\nas_fn_exit 0\n_ACEOF\nac_clean_files=$ac_clean_files_save\n\ntest $ac_write_fail = 0 ||\n  as_fn_error $? \"write failure creating $CONFIG_STATUS\" \"$LINENO\" 5\n\n\n# configure is writing to config.log, and then calls config.status.\n# config.status does its own redirection, appending to config.log.\n# Unfortunately, on DOS this fails, as config.log is still kept open\n# by configure, so config.status won't be able to write to it; its\n# output is simply discarded.  So we exec the FD to /dev/null,\n# effectively closing config.log, so it can be properly (re)opened and\n# appended to by config.status.  When coming back to configure, we\n# need to make the FD available again.\nif test \"$no_create\" != yes; then\n  ac_cs_success=:\n  ac_config_status_args=\n  test \"$silent\" = yes &&\n    ac_config_status_args=\"$ac_config_status_args --quiet\"\n  exec 5>/dev/null\n  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false\n  exec 5>>config.log\n  # Use ||, not &&, to avoid exiting from the if with $? = 1, which\n  # would make configure fail if this is the last instruction.\n  $ac_cs_success || as_fn_exit 1\nfi\nif test -n \"$ac_unrecognized_opts\" && test \"$enable_option_checking\" != no; then\n  { $as_echo \"$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts\" >&5\n$as_echo \"$as_me: WARNING: unrecognized options: $ac_unrecognized_opts\" >&2;}\nfi\n\n\necho\necho \"Required run time packages:\"\necho \"      firejail\"\necho \"      libqt5svg5 (Qt5 SVG icon library) if the program was compiled for Qt5.\"\necho\n"
  },
  {
    "path": "configure.ac",
    "content": "AC_PREREQ([2.68])\nAC_INIT(firetools, 0.9.73, netblue30@yahoo.com, , http://firejail.wordpress.com)\nAC_CONFIG_SRCDIR([src/firetools/main.cpp])\n#AC_CONFIG_HEADERS([config.h])\n\nAC_PROG_CC\nAC_PROG_CXX\nAC_PROG_INSTALL\nAC_PROG_LN_S\nAC_PROG_RANLIB\n\n# checking pthread library\nAC_CHECK_LIB([pthread], [main], [], AC_MSG_ERROR([*** POSIX thread support not installed - please install first ***]))\nAC_CHECK_HEADER(pthread.h,,AC_MSG_ERROR([*** POSIX thread support not installed - please install first ***]))\n\n\nHAVE_FATAL_WARNINGS=\"\"\nAC_ARG_ENABLE([fatal_warnings],\n    AS_HELP_STRING([--enable-fatal-warnings], [-W -Wall -Werror]))\nAS_IF([test \"x$enable_fatal_warnings\" = \"xyes\"], [\n\tHAVE_FATAL_WARNINGS=\"-W -Wall -Werror\"\n\tAC_SUBST(HAVE_FATAL_WARNINGS)\n])\n\n\n\nQMAKE=\"\"\nAC_ARG_WITH(\n    qmake,\n    AS_HELP_STRING(\n\t[--with-qmake=PATH],\n\t[Path to qmake executable]\n    ),\n    [\n\tqmake=\"$withval\"\n\tQMAKE=\"$qmake\"\n    ],\n    [\n\tAC_PATH_TOOL([QMAKE],[qmake])\n    ]\n)\necho \"trying $QMAKE\"\n\n\n#if test -f /usr/lib64/qt4/bin/qmake; then\n#\tQMAKE=/usr/lib64/qt4/bin/qmake\n#fi\n\nif test -z \"$QMAKE\"\nthen\n\tAC_MSG_ERROR([qmake and/or Qt are missing, please install them.])\nfi\nif test -f \"$QMAKE\"\nthen\n\techo \"found $QMAKE\"\nelse\n\tAC_MSG_ERROR([qmake and/or Qt are missing, please install them.])\nfi\n\n$QMAKE -v\n\ncd src/firetools && CXXFLAGS=\"$CXXFLAGS $HAVE_FATAL_WARNINGS\" $QMAKE && cd ../..\ncd src/firejail-ui && CXXFLAGS=\"$CXXFLAGS $HAVE_FATAL_WARNINGS\" $QMAKE && cd ../..\ncd src/fstats && CXXFLAGS=\"$CXXFLAGS $HAVE_FATAL_WARNINGS\" $QMAKE && cd ../..\ncd src/fmgr && CXXFLAGS=\"$CXXFLAGS $HAVE_FATAL_WARNINGS\" $QMAKE && cd ../..\n\ncp confdefs.h firetools_config.h\nAC_OUTPUT(Makefile)\n\necho\necho \"Required run time packages:\"\necho \"      firejail\"\necho \"      libqt5svg5 (Qt5 SVG icon library) if the program was compiled for Qt5.\"\necho\n"
  },
  {
    "path": "install.sh",
    "content": "#!/bin/sh\n\necho \"installing...\"\n"
  },
  {
    "path": "mkasc.sh",
    "content": "#!/bin/sh\n\necho \"Calculating SHA256 for all files in /transfer - firetools version $1\"\n\ncd /transfer\nsha256sum -- * > \"firetools-$1-unsigned\"\ngpg --clearsign --digest-algo SHA256 < \"firetools-$1-unsigned\" > \"firetools-$1.asc\"\ngpg --verify \"firetools-$1.asc\"\ngpg --detach-sign --armor \"firetools-$1.tar.xz\"\nrm \"firetools-$1-unsigned\"\n"
  },
  {
    "path": "mkdeb.sh",
    "content": "#!/bin/sh\n\n# a code archive should already be available\n\nTOP=$(pwd)\nCODE_ARCHIVE=\"$1-$2.tar.xz\"\nCODE_DIR=\"$1-$2\"\nINSTALL_DIR=\"$TOP/debian\"\nDEBIAN_CTRL_DIR=\"$TOP/debian/DEBIAN\"\nDEBIAN_CTRL_DIR+=\"/debian/DEBIAN\"\n\necho \"*****************************************\"\necho \"code archive: $CODE_ARCHIVE\"\necho \"code directory: $CODE_DIR\"\necho \"install directory: $INSTALL_DIR\"\necho \"debian control directory: $DEBIAN_CTRL_DIR\"\necho \"*****************************************\"\n\ntar -xJvf \"$CODE_ARCHIVE\"\nmkdir -p \"$INSTALL_DIR\"\ncd \"$CODE_DIR\"\n./configure --prefix=/usr\nmake -j4\nDESTDIR=$INSTALL_DIR make install-strip\n\ncd ..\necho \"*****************************************\"\nSIZE=$(du -s debian/usr)\necho \"install size $SIZE\"\necho \"*****************************************\"\n\nINSTALL_DIR=\"$TOP/debian/usr\"\n\nmv \"$INSTALL_DIR/share/doc/firetools/RELNOTES\" \"$INSTALL_DIR/share/doc/firetools/changelog.Debian\"\ngzip -9 -n \"$INSTALL_DIR/share/doc/firetools/changelog.Debian\"\nrm \"$INSTALL_DIR/share/doc/firetools/COPYING\"\ncp platform/debian/copyright \"$INSTALL_DIR/share/doc/firetools/.\"\nmkdir -p \"$DEBIAN_CTRL_DIR\"\nsed \"s/FIRETOOLSVER/$2/g\" platform/debian/control > \"$DEBIAN_CTRL_DIR/control\"\nfind ./debian -type d -exec chmod 755 {} +\ndpkg-deb --build debian\nlintian debian.deb\nmv debian.deb \"firetools_$2_1_amd64.deb\"\necho \"if building a 32bit package, rename the deb file manually\"\nrm -fr debian\nrm -fr \"$CODE_DIR\"\n"
  },
  {
    "path": "mkman.sh",
    "content": "#!/bin/sh\n\nset -e\n\nsed \"s/VERSION/$1/g\" $2 > $3\nMONTH=$(LC_ALL=C date -u --date=\"@${SOURCE_DATE_EPOCH:-$(date +%s)}\" +%b)\nsed -i \"s/MONTH/$MONTH/g\" $3\nYEAR=$(LC_ALL=C date -u --date=\"@${SOURCE_DATE_EPOCH:-$(date +%s)}\" +%Y)\nsed -i \"s/YEAR/$YEAR/g\" $3\n"
  },
  {
    "path": "platform/debian/control",
    "content": "Package: firetools\nVersion: FIRETOOLSVER-1\nArchitecture: amd64\nMaintainer: netblue30 <netblue30@yahoo.com>\nInstalled-Size: 684\nDepends: libqt5gui5, libqt5svg5, libc6\nSection: admin\nPriority: optional\nHomepage: http://firejail.sourceforge.net\nDescription: Firejail graphical user interface program.\n Firejail  is  a  SUID sandbox program that reduces the risk of security\n breaches by restricting the running environment of untrusted applications\n using Linux namespaces, seccmp-bpf and Linux capabilities.\n .\n Firetools is the graphical interface of Firejail. Built using Qt4/Qt5 library,\n it provides a sandbox launcher, editing, management and statistics.\n"
  },
  {
    "path": "platform/debian/copyright",
    "content": "\nThis is the Debian/Ubuntu prepackaged version of firetools.\n\n    Firetools is the graphical interface of Firejail security sandbox.\n    \n    Copyright (C) 2014,2017 Firetools Authors (see README file for more details)\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc., 51\n    Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.\n\nThe complete text of the GNU General Public License can be found\nin /usr/share/common-licenses/GPL-2.\n\nHomepage: http://firejail.sourceforge.net.\n\n"
  },
  {
    "path": "platform/rpm/firetools.spec",
    "content": "%define        __spec_install_post %{nil}\n%define          debug_package %{nil}\n%define        __os_install_post %{_dbpath}/brp-compress\n\nSummary: Firejail graphical user interface\nName: firetools\nVersion: FIRETOOLSVERSION\nRelease: 1%{?dist}\nLicense: GPL+\nGroup: Development/Tools\nSOURCE0 : %{name}-%{version}.tar.xz\nURL: http://firejail.sourceforege.net\n\nBuildRequires: qt5-qtbase-devel\nRequires:      firejail qt5-qtsvg\n\n%description\nFiretools is the graphical user interface of Firejail.\nFirejail is a SUID sandbox program that reduces the risk of security breaches\nby restricting the running environment of untrusted applications using Linux\nnamespaces, seccomp-bpf and Linux capabilities. It allows a process and all\nits descendants to have their  own  private view of the globally  shared  kernel\nresources, such as the network stack, process table, mount table.  Firejail can\nwork in a SELinux or AppArmor environment, and it is integrated with Linux\nControl Groups.\n\n%prep\n%setup -q\n\n\n%build\n%configure --with-qmake=/usr/bin/qmake-qt5\nmake %{?_smp_mflags}\n\n\n%install\nrm -rf $RPM_BUILD_ROOT\n%make_install\nrm -rf $RPM_BUILD_ROOT/%{_docdir}/\n\n\n%files\n%defattr(-,root,root,-)\n%doc COPYING README RELNOTES\n%{_bindir}/*\n%{_mandir}/*\n%{_datadir}/applications/firetools.desktop\n%{_datadir}/pixmaps/firetools.png\n%{_datadir}/pixmaps/firetools-minimal.png\n \n\n%changelog\n* Wed Sep 21 2016 Warren Togami <wtogami@gmail.com> 0.9.40.1-1\n- clean up rpm spec to roughly Fedora Packaging Guidelines\n- easy self-contained build from git repo with ./mkrpm.sh as a non-root user\n\n* Wed Jun 15 2016 netblue30 <netblue30@yahoo.com> 0.9.40.1-1\n- bugfixes\n\n* Sun May 29 2016 netblue30 <netblue30@yahoo.com> 0.9.40-1\n - Grsecurity support\n - updated the default application list\n - sandbox file manager (firemgr) application\n - protocols and cpu cores support\n - sandbox name support\n - X11 dispaly support\n - bugfixes\n\n* Sat Oct 3 2015 netblue30 <netblue30@yahoo.com> 0.9.30-1\n - 1h and 12h statistics support\n - user namespaces support\n - QT5 support\n - applist update\n - bugfixes\n\n* Mon Jun 15 2015  netblue30 <netblue30@yahoo.com> 0.9.26.1\n - First rpm package release\n\n"
  },
  {
    "path": "platform/rpm/mkrpm.sh",
    "content": "#!/bin/bash\n\n###\n###  mkrpm.sh\n###  NAME and VER are read from configure.ac.\n###  The VER git tag is exported into a tarball and built into an RPM package.\n###\n\nset -e # stop upon non-zero return\n#set -x # print everything this script does\n\n# Sanity check: necessary tools\nfor CMD in git sed rpmbuild; do\n  if ! which $CMD > /dev/null 2>&1; then\n    echo \"ERROR: Command not found: $CMD\" && exit 255\n  fi\ndone\n# Sanity check: base source directory is expected\nfor DIRNAME in $(dirname $0)/../rpm $(dirname $0)/../../platform; do\n  if [ ! -d $DIRNAME ]; then\n    echo \"ERROR: Unexpected directory, aborting.\"\n    exit 255\n  fi\ndone\nPATH_TO_BASESRC=$(readlink -f $(dirname $0)/../../)\nNAME=$(grep AC_INIT $PATH_TO_BASESRC/configure.ac | sed -r 's/^AC_INIT\\(([a-z]+),.*/\\1/')\n VER=$(grep AC_INIT $PATH_TO_BASESRC/configure.ac | sed -r 's/^AC_INIT\\([a-z]+, ?([\\.0-9]+),.*/\\1/')\n\n# export tarball archive from git tag\ncd $PATH_TO_BASESRC\nmkdir -p build\ngit -c tar.tar.xz.command=\"xz -c9\" archive --prefix=$NAME-$VER/ -o build/$NAME-$VER.tar.xz $VER\nPATH_TO_TARBALL=$(readlink -f build/$NAME-$VER.tar.xz)\nPATH_TO_SPEC=$(readlink -f platform/rpm/$NAME.spec)\ncd -\n\n# fresh temporary rpmbuild _topdir for each build\nmkdir -p $HOME/tmprpmbuild\nexport RPMTMPDIR=$(mktemp -d -p $HOME/tmprpmbuild)\nmkdir -p $RPMTMPDIR/{RPMS,SRPMS,BUILD,SOURCES,SPECS}\n\n# stage rpmbuild inputs\ncp $PATH_TO_TARBALL                                 $RPMTMPDIR/SOURCES/\ncp $PATH_TO_SPEC                                    $RPMTMPDIR/SPECS/\nsed -i \"s/Version: FIRETOOLSVERSION/Version: $VER/\" $RPMTMPDIR/SPECS/$NAME.spec\n\n# build\nrpmbuild --define='_topdir %{getenv:RPMTMPDIR}' -ba $RPMTMPDIR/SPECS/$NAME.spec\n\n# copy rpmbuild outputs to build/ directory\nrm -rf $PATH_TO_BASESRC/build/*.rpm\ncp $(find $RPMTMPDIR -name '*.rpm') $PATH_TO_BASESRC/build/\n\n# success\necho\necho \"    BUILD COMPLETE\"\necho\nfind $PATH_TO_BASESRC/build/ -name '*.rpm'\n"
  },
  {
    "path": "platform/rpm/old-mkrpm.sh",
    "content": "#!/bin/bash\nVER=\"0.9.62\"\n\ncd ~\nrm -fr rpmbuild\n\nmkdir -p ~/rpmbuild/{RPMS,SRPMS,BUILD,SOURCES,SPECS,tmp}\ncat <<EOF >~/.rpmmacros\n%_topdir   %(echo $HOME)/rpmbuild\n%_tmppath  %{_topdir}/tmp\nEOF\n\ncd ~/rpmbuild\n\nmkdir -p firetools-$VER/usr/bin\ninstall -m 755 /usr/bin/firetools firetools-$VER/usr/bin/.\ninstall -m 755 /usr/bin/firejail-ui firetools-$VER/usr/bin/.\n\nmkdir -p firetools-$VER/usr/lib/firetools\ninstall  -m 755 /usr/lib/firetools/fmgr firetools-$VER/usr/lib/firetools/.\ninstall  -m 755 /usr/lib/firetools/fstats firetools-$VER/usr/lib/firetools/.\ninstall  -m 644 /usr/lib/firetools/uimenus firetools-$VER/usr/lib/firetools/.\ninstall  -m 644 /usr/lib/firetools/uihelp firetools-$VER/usr/lib/firetools/.\n\nmkdir -p firetools-$VER/usr/share/applications/\ninstall -m 644 /usr/share/applications/firetools.desktop firetools-$VER/usr/share/applications/.\ninstall -m 644 /usr/share/applications/firejail-ui.desktop firetools-$VER/usr/share/applications/.\n\nmkdir -p  firetools-$VER/usr/share/pixmaps\ninstall -m 644 /usr/share/pixmaps/firetools-minimal.png firetools-$VER/usr/share/pixmaps/.\ninstall -m 644 /usr/share/pixmaps/firetools.png firetools-$VER/usr/share/pixmaps/.\ninstall -m 644 /usr/share/pixmaps/firetools-minimal.png firetools-$VER/usr/share/pixmaps/.\ninstall -m 644 /usr/share/pixmaps/firejail-ui.png firetools-$VER/usr/share/pixmaps/.\n\nmkdir -p firetools-$VER/usr/share/doc/firetools\ninstall -m 644 /usr/share/doc/firetools/COPYING firetools-$VER/usr/share/doc/firetools/.\ninstall -m 644 /usr/share/doc/firetools/README firetools-$VER/usr/share/doc/firetools/.\ninstall -m 644 /usr/share/doc/firetools/RELNOTES firetools-$VER/usr/share/doc/firetools/.\n\nmkdir -p firetools-$VER/usr/share/man/man1\ninstall -m 644 /usr/share/man/man1/firetools.1.gz firetools-$VER/usr/share/man/man1/.\ninstall -m 644 /usr/share/man/man1/firejail-ui.1.gz firetools-$VER/usr/share/man/man1/.\n\n\ntar -czvf firetools-$VER.tar.gz firetools-$VER\ncp firetools-$VER.tar.gz SOURCES/.\n\ncat <<EOF > SPECS/firetools.spec\n%define        __spec_install_post %{nil}\n%define          debug_package %{nil}\n%define        __os_install_post %{_dbpath}/brp-compress\nSummary: Firejail user interface\nName: firetools\nVersion: $VER\nRelease: 1\nLicense: GPL+\nGroup: Development/Tools\nSOURCE0 : %{name}-%{version}.tar.gz\nURL: http://firejail.sourceforege.net\nBuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root\n%description\nFiretools is the graphical user interface of Firejail.\nFirejail is a SUID sandbox program that reduces the risk of security breaches\nby restricting the running environment of untrusted applications using Linux\nnamespaces, seccomp-bpf and Linux capabilities. It allows a process and all\nits descendants to have their  own  private view of the globally  shared  kernel\nresources, such as the network stack, process table, mount table.  Firejail can\nwork in a SELinux or AppArmor environment, and it is integrated with Linux\nControl Groups.\n%prep\n%setup -q\n%build\n%install\nrm -rf %{buildroot}\nmkdir -p  %{buildroot}\ncp -a * %{buildroot}\n%clean\nrm -rf %{buildroot}\n%files\n%defattr(-,root,root,-)\n%{_bindir}/*\n%{_docdir}/*\n%{_mandir}/*\n/usr/share/applications/firetools.desktop\n/usr/share/applications/firejail-ui.desktop\n/usr/share/pixmaps/firetools.png\n/usr/share/pixmaps/firetools-minimal.png\n/usr/share/pixmaps/firejail-ui.png\n/usr/lib/firetools/fmgr\n/usr/lib/firetools/fstats\n/usr/lib/firetools/uihelp\n/usr/lib/firetools/uimenus\n\n%changelog\n\n* Tue Dec 17 2019 netblue30 <netblue30@yahoo.com> 0.9.62-1\n\n* Thu Jan 24 2019 netblue30 <netblue30@yahoo.com> 0.9.58-1\n\n* Fri Mar 2 2018 netblue30 <netblue30@yahoo.com> 0.9.52-1\n\n* Mon Oct 2 2017 netblue30 <netblue30@yahoo.com> 0.9.50-1\n\n* Fri Feb 24 2017 netblue30 <netblue30@yahoo.com> 0.9.46-1\n - split firetools in two distinct executables\n - updated the default list of applications for firetools\n - added firejail-ui, a configuration wizard for firejail\n - move make dist from .tar.bz2 to .tar.xz\n - implemented detached signatures\n - bugfixes\n\n* Mon Oct 24 2016 netblue30 <netblue30@yahoo.com> 0.9.44-1\n - support for firejail --x11 detection\n - bugfixes\n\n* Sun May 29 2016 netblue30 <netblue30@yahoo.com> 0.9.40-1\n - Grsecurity support\n - updated the default application list\n - sandbox file manager (firemgr) application\n - protocols and cpu cores support\n - sandbox name support\n - X11 dispaly support\n - bugfixes\n* Sat Oct 3 2015 netblue30 <netblue30@yahoo.com> 0.9.30-1\n - 1h and 12h statistics support\n - user namespaces support\n - QT5 support\n - applist update\n - bugfixes\n* Mon Jun 15 2015  netblue30 <netblue30@yahoo.com> 0.9.26.1\n - First rpm package release\nEOF\n\n\nrpmbuild -ba SPECS/firetools.spec\nrpm -qpl RPMS/x86_64/firetools-$VER-1.x86_64.rpm\ncd ..\nrm -f firetools-$VER-1.x86_64.rpm\ncp rpmbuild/RPMS/x86_64/firetools-$VER-1.x86_64.rpm .\n"
  },
  {
    "path": "src/common/common.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n\n#ifndef COMMON_H\n#define COMMON_H\n//#define _GNU_SOURCE\n#include <stdio.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <stddef.h>\n#include <string.h>\n#include <ctype.h>\n#include <assert.h>\n\n#define errExit(msg)    do { char msgout[500]; sprintf(msgout, \"Error %s:%s(%d)\", msg, __FUNCTION__, __LINE__); perror(msgout); exit(1);} while (0)\n\n// macro to print ip addresses in a printf statement\n#define PRINT_IP(A) \\\n((int) (((A) >> 24) & 0xFF)),  ((int) (((A) >> 16) & 0xFF)), ((int) (((A) >> 8) & 0xFF)), ((int) ( (A) & 0xFF))\n\n// macro to print a mac addresses in a printf statement\n#define PRINT_MAC(A) \\\n((unsigned) (*(A)) & 0xff), ((unsigned) (*((A) + 1) & 0xff)), ((unsigned) (*((A) + 2) & 0xff)), \\\n((unsigned) (*((A) + 3)) & 0xff), ((unsigned) (*((A) + 4) & 0xff)), ((unsigned) (*((A) + 5)) & 0xff)\n\n// convert a network mask to the number of bits\nstatic inline uint8_t mask2bits(uint32_t mask) {\n\tuint32_t tmp = 0x80000000;\n\tint i;\n\tuint8_t rv = 0;\n\n\tfor (i = 0; i < 32; i++, tmp >>= 1) {\n\t\tif (tmp & mask)\n\t\t\trv++;\n\t\telse\n\t\t\tbreak;\n\t}\n\treturn rv;\n}\n\n// read an IPv4 address and convert it to uint32_t\nstatic inline int atoip(const char *str, uint32_t *ip) {\n\tunsigned a, b, c, d;\n\n\t// allow only numbers\n\tconst char *ptr = str;\n\twhile (*ptr != '\\0') {\n\t\tif (isdigit(*ptr) || *ptr == '.')\n\t\t\t;\n\t\telse\n\t\t\treturn 1;\n\t\tptr++;\n\t}\n\n\tif (sscanf(str, \"%u.%u.%u.%u\", &a, &b, &c, &d) != 4 || a > 255 || b > 255 || c > 255 || d > 255)\n\t\treturn 1;\n\t\t\n\t*ip = a * 0x1000000 + b * 0x10000 + c * 0x100 + d;\n\treturn 0;\n}\n\n// verify ip address is in the ifip/ifmask network range\nstatic inline char *in_netrange(uint32_t ip, uint32_t ifip, uint32_t ifmask) {\n\tif ((ip & ifmask) != (ifip & ifmask))\n\t\treturn (char *) \"Error: the IP address is not in the interface range\\n\";\n\telse if ((ip & ifmask) == ip)\n\t\treturn (char *) \"Error: the IP address is a network address\\n\";\n\telse if ((ip | ~ifmask) == ip)\n\t\treturn (char *) \"Error: the IP address is a network address\\n\";\n\treturn NULL;\n}\n\n#endif\n"
  },
  {
    "path": "src/common/hyperlink.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include \"hyperlink.h\"\n\nHyperlink::Hyperlink( const QString & text, QWidget * parent )\n:QLabel(parent) {\n\t(void) text;\n}\n\nvoid Hyperlink::mousePressEvent ( QMouseEvent * event ) {\n\t(void) event;\n\temit clicked();\n}\n"
  },
  {
    "path": "src/common/hyperlink.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef HYPERLINK_H\n#define HYPERLINK_H\n#include <QLabel>\n\nclass Hyperlink : public QLabel\n{\nQ_OBJECT\n\tpublic:\n\tHyperlink( const QString & text, QWidget * parent = 0 );\n\t~Hyperlink(){}\n\nsignals:\n\tvoid clicked();\n\nprotected:\n\tvoid mousePressEvent ( QMouseEvent * event ) ;\n\n};\n#endif\n"
  },
  {
    "path": "src/common/pid.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include \"common.h\"\n#include \"pid.h\"\n#include \"utils.h\"\n#include <string.h>\n#include <sys/types.h>\n#include <pwd.h>\n#include <sys/ioctl.h>\n#include <dirent.h>\n#include <limits.h>\n\n#define PIDS_BUFLEN 4096\nProcess *pids = 0;\nProcessData *pids_data = 0;\nint pids_first = 0;\nint pids_last = 0;\nint max_pids = 32769;\nstatic int pid_proc_cmdline_x11_xpra_xephyr(const pid_t pid);\n\n// get the memory associated with this pid\nvoid pid_getmem(unsigned pid, unsigned *rss, unsigned *shared) {\n\t// open stat file\n\tchar *file;\n\tif (asprintf(&file, \"/proc/%u/statm\", pid) == -1) {\n\t\tperror(\"asprintf\");\n\t\texit(1);\n\t}\n\n\tFILE *fp = fopen(file, \"r\");\n\tif (!fp) {\n\t\tfree(file);\n\t\treturn;\n\t}\n\tfree(file);\n\n\tunsigned a, b, c;\n\tif (3 != fscanf(fp, \"%u %u %u\", &a, &b, &c)) {\n\t\tfclose(fp);\n\t\treturn;\n\t}\n\t*rss += b;\n\t*shared += c;\n\tfclose(fp);\n}\n\n\nvoid pid_get_cpu_time(unsigned pid, unsigned *utime, unsigned *stime) {\n\t// open stat file\n\tchar *file;\n\tif (asprintf(&file, \"/proc/%u/stat\", pid) == -1) {\n\t\tperror(\"asprintf\");\n\t\texit(1);\n\t}\n\tFILE *fp = fopen(file, \"r\");\n\tif (!fp) {\n\t\tfree(file);\n\t\treturn;\n\t}\n\tfree(file);\n\n\tchar line[PIDS_BUFLEN];\n\tif (fgets(line, PIDS_BUFLEN - 1, fp)) {\n\t\tchar *ptr = line;\n\t\t// jump 13 fields\n\t\tint i;\n\t\tfor (i = 0; i < 13; i++) {\n\t\t\twhile (*ptr != ' ' && *ptr != '\\t' && *ptr != '\\0')\n\t\t\t\tptr++;\n\t\t\tif (*ptr == '\\0')\n\t\t\t\tgoto myexit;\n\t\t\tptr++;\n\t\t}\n\t\tif (2 != sscanf(ptr, \"%u %u\", utime, stime))\n\t\t\tgoto myexit;\n\t}\n\nmyexit:\n\tfclose(fp);\n}\n\nunsigned long long pid_get_start_time(unsigned pid) {\n\t// open stat file\n\tchar *file;\n\tif (asprintf(&file, \"/proc/%u/stat\", pid) == -1) {\n\t\tperror(\"asprintf\");\n\t\texit(1);\n\t}\n\tFILE *fp = fopen(file, \"r\");\n\tif (!fp) {\n\t\tfree(file);\n\t\treturn 0;\n\t}\n\tfree(file);\n\n\tchar line[PIDS_BUFLEN];\n\tunsigned long long retval = 0;\n\tif (fgets(line, PIDS_BUFLEN - 1, fp)) {\n\t\tchar *ptr = line;\n\t\t// jump 21 fields\n\t\tint i;\n\t\tfor (i = 0; i < 21; i++) {\n\t\t\twhile (*ptr != ' ' && *ptr != '\\t' && *ptr != '\\0')\n\t\t\t\tptr++;\n\t\t\tif (*ptr == '\\0')\n\t\t\t\tgoto myexit;\n\t\t\tptr++;\n\t\t}\n\t\tif (1 != sscanf(ptr, \"%llu\", &retval))\n\t\t\tgoto myexit;\n\t}\n\nmyexit:\n\tfclose(fp);\n\treturn retval;\n}\n\nchar *pid_get_user_name(uid_t uid) {\n\tstruct passwd *pw = getpwuid(uid);\n\tif (pw)\n\t\treturn strdup(pw->pw_name);\n\treturn NULL;\n}\n\nuid_t pid_get_uid(pid_t pid) {\n\tuid_t rv = 0;\n\n\t// open stat file\n\tchar *file;\n\tif (asprintf(&file, \"/proc/%u/status\", pid) == -1) {\n\t\tperror(\"asprintf\");\n\t\texit(1);\n\t}\n\tFILE *fp = fopen(file, \"r\");\n\tif (!fp) {\n\t\tfree(file);\n\t\treturn 0;\n\t}\n\n\t// look for firejail executable name\n\tchar buf[PIDS_BUFLEN];\n\twhile (fgets(buf, PIDS_BUFLEN - 1, fp)) {\n\t\tif (strncmp(buf, \"Uid:\", 4) == 0) {\n\t\t\tchar *ptr = buf + 5;\n\t\t\twhile (*ptr != '\\0' && (*ptr == ' ' || *ptr == '\\t')) {\n\t\t\t\tptr++;\n\t\t\t}\n\t\t\tif (*ptr == '\\0')\n\t\t\t\tgoto doexit;\n\n\t\t\trv = atoi(ptr);\n\t\t\tbreak; // break regardless!\n\t\t}\n\t}\ndoexit:\n\tfclose(fp);\n\tfree(file);\n\treturn rv;\n}\n\n\n// recursivity!!!\n\n// mon_pid: pid of sandbox to be monitored, 0 if all sandboxes are included\nvoid pid_read(pid_t mon_pid) {\n//timetrace_start();\n\tif (pids == NULL) {\n\t\tFILE *fp = fopen(\"/proc/sys/kernel/pid_max\", \"r\");\n\t\tif (fp) {\n\t\t\tint val;\n\t\t\tif (fscanf(fp, \"%d\", &val) == 1) {\n\t\t\t\tif (val >= max_pids)\n\t\t\t\t\tmax_pids = val + 1;\n\t\t\t}\n\t\t\tfclose(fp);\n\t\t}\n\t\tpids = (Process *) malloc(sizeof(Process) * max_pids + 1);\n\t\tif (pids == NULL)\n\t\t\terrExit(\"malloc\");\n\t\tmemset(pids, 0, sizeof(Process) * max_pids);\n\t\tpids_data = (ProcessData *) malloc(sizeof(ProcessData) * max_pids + 1);\n\t\tif (pids == NULL)\n\t\t\terrExit(\"malloc\");\n\t\tmemset(pids_data, 0, sizeof(Process) * max_pids);\n\t}\n\n\tmemset(pids + pids_first, 0, sizeof(Process) * (pids_last - pids_first + 1));\n\tpids_first = 0;\n\tpids_last = 0;\n\tpid_t mypid = getpid();\n\n\tDIR *dir;\n\tif (!(dir = opendir(\"/proc\"))) {\n\t\t// sleep 2 seconds and try again\n\t\tsleep(2);\n\t\tif (!(dir = opendir(\"/proc\"))) {\n\t\t\tfprintf(stderr, \"Error: cannot open /proc directory\\n\");\n\t\t\texit(1);\n\t\t}\n\t}\n\n\tpid_t child = -1;\n\tstruct dirent *entry;\n\tchar *end;\n\twhile (child < 0 && (entry = readdir(dir))) {\n\t\tpid_t pid = strtol(entry->d_name, &end, 10);\n\t\tpid %= max_pids;\n\t\tpids_last = pid;\n\t\tif (end == entry->d_name || *end)\n\t\t\tcontinue;\n\t\tif (pid == mypid)\n\t\t\tcontinue;\n\n\t\t// open stat file\n\t\tchar *file;\n\t\tif (asprintf(&file, \"/proc/%u/status\", pid) == -1) {\n\t\t\tperror(\"asprintf\");\n\t\t\texit(1);\n\t\t}\n\t\tFILE *fp = fopen(file, \"r\");\n\t\tif (!fp) {\n\t\t\tfree(file);\n\t\t\tcontinue;\n\t\t}\n\n\t\tmemset(&pids_data[pid], 0, sizeof(ProcessData));\n\n\t\t// look for firejail executable name\n\t\tchar buf[PIDS_BUFLEN];\n\t\twhile (fgets(buf, PIDS_BUFLEN - 1, fp)) {\n\t\t\tif (strncmp(buf, \"Name:\", 5) == 0) {\n\t\t\t\tchar *ptr = buf + 5;\n\t\t\t\twhile (*ptr != '\\0' && (*ptr == ' ' || *ptr == '\\t')) {\n\t\t\t\t\tptr++;\n\t\t\t\t}\n\t\t\t\tif (*ptr == '\\0') {\n\t\t\t\t\tfprintf(stderr, \"Error: cannot read /proc file\\n\");\n\t\t\t\t\texit(1);\n\t\t\t\t}\n\n\t\t\t\tif ((strncmp(ptr, \"firejail\", 8) == 0) && (mon_pid == 0 || mon_pid == pid)) {\n\t\t\t\t\tif (pid_proc_cmdline_x11_xpra_xephyr(pid))\n\t\t\t\t\t\tpids[pid].level = 0;\n\t\t\t\t\telse {\n\t\t\t\t\t\tpids[pid].level = 1;\n\t\t\t\t\t\tif (pids_first == 0)\n\t\t\t\t\t\t\tpids_first = pid;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tpids[pid].level = 0;\n\t\t\t}\n\t\t\tif (strncmp(buf, \"State:\", 6) == 0) {\n\t\t\t\tif (strstr(buf, \"(zombie)\"))\n\t\t\t\t\tpids[pid].level = 0;\n\t\t\t}\n\t\t\telse if (strncmp(buf, \"PPid:\", 5) == 0) {\n\t\t\t\tchar *ptr = buf + 5;\n\t\t\t\twhile (*ptr != '\\0' && (*ptr == ' ' || *ptr == '\\t')) {\n\t\t\t\t\tptr++;\n\t\t\t\t}\n\t\t\t\tif (*ptr == '\\0') {\n\t\t\t\t\tfprintf(stderr, \"Error: cannot read /proc file\\n\");\n\t\t\t\t\texit(1);\n\t\t\t\t}\n\t\t\t\tunsigned parent = atoi(ptr);\n\t\t\t\tparent %= max_pids;\n\t\t\t\tpids_data[pid].parent = parent;\n\t\t\t\tif (pids[parent].level > 0)\n\t\t\t\t\tpids[pid].level = (pids[parent].level == UCHAR_MAX)? UCHAR_MAX:  pids[parent].level + 1;\n//if (pids[pid].level)\n//printf(\"pid %d level %u  parent %d\\n\", pid, pids[pid].level, pids_data[pid].parent);\n\t\t\t}\n\t\t\telse if (strncmp(buf, \"Uid:\", 4) == 0) {\n\t\t\t\tif (pids[pid].level > 0) {\n\t\t\t\t\tchar *ptr = buf + 5;\n\t\t\t\t\twhile (*ptr != '\\0' && (*ptr == ' ' || *ptr == '\\t')) {\n\t\t\t\t\t\tptr++;\n\t\t\t\t\t}\n\t\t\t\t\tif (*ptr == '\\0') {\n\t\t\t\t\t\tfprintf(stderr, \"Error: cannot read /proc file\\n\");\n\t\t\t\t\t\texit(1);\n\t\t\t\t\t}\n\t\t\t\t\tpids_data[pid].uid = atoi(ptr);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tfclose(fp);\n\t\tfree(file);\n\t}\n\tclosedir(dir);\n}\n\n// return 1 if error\nint name2pid(const char *name, pid_t *pid) {\n\tpid_t parent = getpid();\n\n\tDIR *dir;\n\tif (!(dir = opendir(\"/proc\"))) {\n\t\t// sleep 2 seconds and try again\n\t\tsleep(2);\n\t\tif (!(dir = opendir(\"/proc\"))) {\n\t\t\tfprintf(stderr, \"Error: cannot open /proc directory\\n\");\n\t\t\texit(1);\n\t\t}\n\t}\n\n\tstruct dirent *entry;\n\tchar *end;\n\twhile ((entry = readdir(dir))) {\n\t\tpid_t newpid = strtol(entry->d_name, &end, 10);\n\t\tif (end == entry->d_name || *end)\n\t\t\tcontinue;\n\t\tif (newpid == parent)\n\t\t\tcontinue;\n\n\t\t// check if this is a firejail executable\n\t\tchar *comm = pid_proc_comm(newpid);\n\t\tif (comm) {\n\t\t\t// remove \\n\n\t\t\tchar *ptr = strchr(comm, '\\n');\n\t\t\tif (ptr)\n\t\t\t\t*ptr = '\\0';\n\t\t\tif (strcmp(comm, \"firejail\")) {\n\t\t\t\tfree(comm);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfree(comm);\n\t\t}\n\n\t\tchar *cmd = pid_proc_cmdline(newpid);\n\t\tif (cmd) {\n\t\t\t// mark the end of the name\n\t\t\tchar *ptr = strstr(cmd, \"--name=\");\n\t\t\tchar *start = ptr;\n\t\t\tif (!ptr) {\n\t\t\t\tfree(cmd);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\twhile (*ptr != ' ' && *ptr != '\\t' && *ptr != '\\0')\n\t\t\t\tptr++;\n\t\t\t*ptr = '\\0';\n\t\t\tint rv = strcmp(start + 7, name);\n\t\t\tif (rv == 0) {\n\t\t\t\tfree(cmd);\n\t\t\t\t*pid = newpid;\n\t\t\t\tclosedir(dir);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tfree(cmd);\n\t\t}\n\t}\n\tclosedir(dir);\n\treturn 1;\n}\n\n#define BUFLEN 4096\nchar *pid_proc_comm(const pid_t pid) {\n\t// open /proc/pid/cmdline file\n\tchar *fname;\n\tint fd;\n\tif (asprintf(&fname, \"/proc/%d//comm\", pid) == -1)\n\t\treturn NULL;\n\tif ((fd = open(fname, O_RDONLY)) < 0) {\n\t\tfree(fname);\n\t\treturn NULL;\n\t}\n\tfree(fname);\n\n\t// read file\n\tchar buffer[BUFLEN];\n\tssize_t len;\n\tif ((len = read(fd, buffer, sizeof(buffer) - 1)) <= 0) {\n\t\tclose(fd);\n\t\treturn NULL;\n\t}\n\tbuffer[len] = '\\0';\n\tclose(fd);\n\n\t// remove \\n\n\tchar *ptr = strchr(buffer, '\\n');\n\tif (ptr)\n\t\t*ptr = '\\0';\n\n\t// return a malloc copy of the command line\n\tchar *rv = strdup(buffer);\n\tif (strlen(rv) == 0) {\n\t\tfree(rv);\n\t\treturn NULL;\n\t}\n\treturn rv;\n}\n\nchar *pid_proc_cmdline(const pid_t pid) {\n\t// open /proc/pid/cmdline file\n\tchar *fname;\n\tint fd;\n\tif (asprintf(&fname, \"/proc/%d/cmdline\", pid) == -1)\n\t\treturn NULL;\n\tif ((fd = open(fname, O_RDONLY)) < 0) {\n\t\tfree(fname);\n\t\treturn NULL;\n\t}\n\tfree(fname);\n\n\t// read file\n\tunsigned char buffer[BUFLEN];\n\tssize_t len;\n\tif ((len = read(fd, buffer, sizeof(buffer) - 1)) <= 0) {\n\t\tclose(fd);\n\t\treturn NULL;\n\t}\n\tbuffer[len] = '\\0';\n\tclose(fd);\n\n\t// clean data\n\tint i;\n\tfor (i = 0; i < len; i++) {\n\t\tif (buffer[i] == '\\0')\n\t\t\tbuffer[i] = ' ';\n\t}\n\n\t// return a malloc copy of the command line\n\tchar *rv = strdup((char *) buffer);\n\tif (strlen(rv) == 0) {\n\t\tfree(rv);\n\t\treturn NULL;\n\t}\n\treturn rv;\n}\n\n\n// recursivity!!!\nvoid pid_get_cpu_sandbox(unsigned pid, unsigned *utime, unsigned *stime) {\n//printf(\"call %d, last %d\\n\", pid, pids_last);\n\tif (pids[pid].level == 1) {\n\t\t*utime = 0;\n\t\t*stime = 0;\n\t}\n\n\tunsigned utmp = 0;\n\tunsigned stmp = 0;\n\tpid_get_cpu_time(pid, &utmp, &stmp);\n\t*utime += utmp;\n\t*stime += stmp;\n\n\tint i;\n\tfor (i = pid + 1; i < (pids_last + 1); i++) {\n\t\tif (pids_data[i].parent == (int) pid)\n\t\t\tpid_get_cpu_sandbox(i, utime, stime);\n\t}\n}\n\nvoid pid_get_mem_sandbox(unsigned pid, unsigned *rss, unsigned *shared) {\n\tif (pids[pid].level == 1) {\n\t\t*rss = 0;\n\t\t*shared = 0;\n\t}\n\n\tpid_getmem(pid, rss, shared);\n\n\tint i;\n\tfor (i = pid + 1; i < (pids_last + 1); i++) {\n\t\tif (pids_data[i].parent == (int) pid)\n\t\t\tpid_get_mem_sandbox(i, rss, shared);\n\t}\n}\n\n#define MAXBUF PIDS_BUFLEN\nvoid pid_get_netstats_sandbox(int parent, unsigned long long *rx, unsigned long long *tx) {\n\t*rx = 0;\n\t*tx = 0;\n\n\t// find the first child\n\tint child = -1;\n\tif (parent == 1)\n\t\tchild = 1;\n\telse {\n\t\tfor (child = parent + 1; child < (pids_last + 1); child++) {\n\t\t\tif (pids_data[child].parent == parent)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tif (child == -1)\n\t\treturn;\n\n\t// open /proc/child/net/dev file and read rx and tx\n\tchar *fname;\n\tif (asprintf(&fname, \"/proc/%d/net/dev\", child) == -1)\n\t\terrExit(\"asprintf\");\n\n\tFILE *fp = fopen(fname, \"r\");\n\tif (!fp) {\n\t\tfree(fname);\n\t\treturn;\n\t}\n\n\tchar buf[MAXBUF];\n\twhile (fgets(buf, MAXBUF, fp)) {\n\t\tif (strncmp(buf, \"Inter\", 5) == 0)\n\t\t\tcontinue;\n\t\tif (strncmp(buf, \" face\", 5) == 0)\n\t\t\tcontinue;\n\n\t\tchar *ptr = buf;\n\t\twhile (*ptr != '\\0' && *ptr != ':') {\n\t\t\tptr++;\n\t\t}\n\n\t\tif (*ptr == '\\0') {\n\t\t\tfclose(fp);\n\t\t\tfree(fname);\n\t\t\treturn;\n\t\t}\n\t\tptr++;\n\n\t\tlong long unsigned rxval;\n\t\tlong long unsigned txval;\n\t\tunsigned a, b, c, d, e, f, g;\n\t\tint rv = sscanf(ptr, \"%llu %u %u %u %u %u %u %u %llu\",\n\t\t\t&rxval, &a, &b, &c, &d, &e, &f, &g, &txval);\n\t\tif (rv == 9) {\n\t\t\t*rx += rxval;\n\t\t\t*tx += txval;\n\t\t}\n\t}\n\n\tfree(fname);\n\tfclose(fp);\n\treturn;\n}\n\n// return 1 if firejail --x11 on command line\nstatic int pid_proc_cmdline_x11_xpra_xephyr(const pid_t pid) {\n\t// if comm is not firejail return 0\n\tchar *comm = pid_proc_comm(pid);\n\tif (strcmp(comm, \"firejail\") != 0) {\n\t\tfree(comm);\n\t\treturn 0;\n\t}\n\tfree(comm);\n\n\t// open /proc/pid/cmdline file\n\tchar *fname;\n\tint fd;\n\tif (asprintf(&fname, \"/proc/%d/cmdline\", pid) == -1)\n\t\treturn 0;\n\tif ((fd = open(fname, O_RDONLY)) < 0) {\n\t\tfree(fname);\n\t\treturn 0;\n\t}\n\tfree(fname);\n\n\t// read file\n\tunsigned char buffer[BUFLEN];\n\tssize_t len;\n\tif ((len = read(fd, buffer, sizeof(buffer) - 1)) <= 0) {\n\t\tclose(fd);\n\t\treturn 0;\n\t}\n\tbuffer[len] = '\\0';\n\tclose(fd);\n\n\t// skip the first argument\n\tint i;\n\tfor (i = 0; buffer[i] != '\\0'; i++);\n\n\t// parse remaining command line options\n\twhile (1) {\n\t\t// extract argument\n\t\ti++;\n\t\tif (i >= len)\n\t\t\tbreak;\n\t\tchar *arg = (char *)buffer + i;\n\n\t\t// detect the last command line option\n\t\tif (strcmp(arg, \"--\") == 0)\n\t\t\tbreak;\n\t\tif (strncmp(arg, \"--\", 2) != 0)\n\t\t\tbreak;\n\n\t\tif (strcmp(arg, \"--x11=xorg\") == 0)\n\t\t\treturn 0;\n\n\t\t// check x11\n\t\tif (strncmp(arg, \"--x11\", 5) == 0)\n\t\t\treturn 1;\n\t\ti += strlen(arg);\n\t}\n\treturn 0;\n}\n\n\n// dbus proxy path used by firejail and firemon\n#define XDG_DBUS_PROXY_PATH \"/usr/bin/xdg-dbus-proxy\"\nint pid_find_child(int id) {\n\tint i;\n\tint first_child = -1;\n\t// find the first child\n\tfor (i = 0; i < max_pids && first_child == -1; i++) {\n\t\tif (pids[i].level == 2 && pids_data[i].parent == id) {\n\t\t\t// skip /usr/bin/xdg-dbus-proxy (started by firejail for dbus filtering)\n\t\t\tchar *cmdline = pid_proc_cmdline(i);\n\t\t\tif (strncmp(cmdline, XDG_DBUS_PROXY_PATH, strlen(XDG_DBUS_PROXY_PATH)) == 0) {\n\t\t\t\tfree(cmdline);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfree(cmdline);\n\t\t\tfirst_child = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (first_child == -1)\n\t\treturn -1;\n\n\t// find the second-level child\n\tfor (i = 0; i < max_pids; i++) {\n\t\tif (pids[i].level == 3 && pids_data[i].parent == first_child)\n\t\t\treturn i;\n\t}\n\n\t// if a second child is not found, return the first child pid\n\t// this happens for processes sandboxed with --join\n\treturn first_child;\n}\n\n"
  },
  {
    "path": "src/common/pid.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef PID_H\n#define PID_H\n#include \"common.h\"\n\ntypedef struct {\n\tunsigned char level;\n\t\t // 0 not a process, not firejail, or zombie process\n\t\t // 1 main firejail process\n\t\t // > 1 firejail child\n} Process;\n\ntypedef struct {\n\tpid_t parent;\n\tuid_t uid;\n\tunsigned utime;\n\tunsigned stime;\n\tunsigned rss;\n\tunsigned shared;\n\tunsigned long long rx;\t// network rx, bytes\n\tunsigned long long tx;\t// networking tx, bytes\n} ProcessData;\n\nextern int max_pids;\nextern Process *pids;\nextern ProcessData *pids_data;\nextern int pids_first;\nextern int pids_last;\n\n// pid self-contained functions\nvoid pid_getmem(unsigned pid, unsigned *rss, unsigned *shared);\nvoid pid_get_cpu_time(unsigned pid, unsigned *utime, unsigned *stime);\nunsigned long long pid_get_start_time(unsigned pid);\nuid_t pid_get_uid(pid_t pid);\nchar *pid_get_user_name(uid_t uid);\nint name2pid(const char *name, pid_t *pid);\nchar *pid_proc_comm(const pid_t pid);\nchar *pid_proc_cmdline(const pid_t pid);\nint pid_find_child(int id);\n\n// read all processes in pids array\nvoid pid_read(pid_t mon_pid);\n\nvoid pid_get_cpu_sandbox(unsigned pid, unsigned *utime, unsigned *stime);\nvoid pid_get_mem_sandbox(unsigned pid, unsigned *rss, unsigned *shared);\nvoid pid_get_netstats_sandbox(int pid, unsigned long long *rx, unsigned long long *tx);\n\n#endif\n"
  },
  {
    "path": "src/common/utils.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <unistd.h>\n#include <pwd.h>\n#include \"common.h\"\n#include \"utils.h\"\n#include <time.h>\n\n#define MAXBUF (1024 * 1024) // 1MB output buffer\nstatic char outbuf[MAXBUF + 1];\n\n// run a user program using popen; returns static memory\nchar *run_program(const char *prog) {\n\t// open pipe\n\tFILE *fp;\n\tfp = popen(prog, \"r\");\n\tif (fp == NULL)\n\t\treturn NULL;\n\n\t// read pipe\n\tint len;\n\tchar *ptr = outbuf;\n\tsize_t size = MAXBUF;\n\twhile ((len = fread(ptr, 1, size, fp)) > 0) {\n\t\tsize -= len;\n\t\tptr += len;\n\t\tif (size < 80)\t// probably not enough room to read a new full line\n\t\t\tbreak;\n\t}\n\t*ptr = '\\0';\n\n\tpclose(fp);\n\treturn outbuf;\n}\n\n// returns true or false if the program was found using \"which\" shell command\nbool which(const char *prog) {\n\t// build command\n\tchar *cmd;\n\tif (asprintf(&cmd, \"which %s\", prog) == -1) {\n\t\tperror(\"asprintf\");\n\t\texit(1);\n\t}\n\n\t// run command\n\tchar *res = run_program(cmd);\n\tif (strstr(res, prog))\n\t\treturn true;\n\treturn false;\n}\n\n// check if a name.desktop file exists in config home directory\nbool have_config_file(const char *name) {\n\tassert(name);\n\n\t// build the full path\n\tchar *path = get_config_file_name(name);\n\tif (!path)\n\t\treturn false;\n\n\t// check file\n\tstruct stat s;\n\tbool rv = true;\n\tif (stat(path, &s) == -1)\n\t\trv = false;\n\telse if (!S_ISREG(s.st_mode))\n\t\trv = false;\n\n\tfree(path);\n\treturn rv;\n}\n\n// get a coniguration file path based on the name; returns allocated memory\nchar *get_config_file_name(const char *name) {\n\tassert(name);\n\n\t// build the full path\n\tchar *path;\n\tchar *homedir = get_home_directory();\n\tif (asprintf(&path, \"%s/.config/firetools/%s.desktop\", homedir, name) == -1)\n\t\terrExit(\"asprintf\");\n\tfree(homedir);\n\treturn path;\n}\n\n// get the full path of the home directory; returns allocated memory\nchar *get_home_directory() {\n\t// access account information\n\tstruct passwd *pw = getpwuid(getuid());\n\tif (!pw)\n\t\terrExit(\"getpwuid\");\n\n\t// extract home directory\n\tif (pw->pw_dir != NULL) {\n\t\tchar *homedir = strdup(pw->pw_dir);\n\t\tif (!homedir)\n\t\t\terrExit(\"strdup\");\n\t\treturn homedir;\n\t}\n\n\treturn 0;\n}\n\n// get config directory name; returns allocated memory\nchar *get_config_directory() {\n\tchar *homedir = get_home_directory();\n\tif (!homedir)\n\t\treturn 0;\n\n\tchar *rv;\n\tif (asprintf(&rv, \"%s/.config/firetools\", homedir) == -1)\n\t\terrExit(\"asprintf\");\n\tfree(homedir);\n\treturn rv;\n}\n\n// create firetools directory if it doesn't exist\nvoid create_config_directory() {\n\tstruct stat s;\n\tchar *path;\n\tchar *homedir = get_home_directory();\n\tif (asprintf(&path, \"%s/.config/firetools\", homedir) == -1)\n\t\terrExit(\"asprintf\");\n\tfree(homedir);\n\tif (stat(path, &s) == -1) {\n\t\t/* coverity[toctou] */\n\t\tint rv = mkdir(path, 0755);\n\t\tif (rv == -1) {\n\t\t\tfprintf(stderr, \"Error: cannot create %s directory\\n\", path);\n\t\t\texit(1);\n\t\t}\n\t}\n\tfree(path);\n}\n\nint sargc;\nchar *sargv[SARG_MAX];\n\nvoid split_command(char *cmd) {\n\tint i;\n\tchar *ptr = cmd;\n\n\tsargc = 0;\n\tmemset(sargv, 0, sizeof(sargv));\n\n\tif (!ptr || *ptr == '\\0')\n\t\treturn;\n\n\tfor (i = 0; i < SARG_MAX; i++) {\n\t\tchar *start;\n\n\t\t// skip space\n\t\twhile (*ptr == ' ' || *ptr == '\\t')\n\t\t\tptr++;\n\t\tif (*ptr == '\\n' || *ptr == '\\r' || *ptr == '\\0')\n\t\t\tbreak;\n\t\tstart = ptr;\n\n\t\t// advance\n\t\twhile (*ptr != '\\0' && *ptr != ' ' && *ptr != '\\t' && *ptr != '\\n' && *ptr != '\\r')\n\t\t\tptr++;\n\t\tif (*ptr == '\\0') {\n\t\t\tsargv[sargc++] = start;\n\t\t\tbreak;\n\t\t}\n\t\t*ptr++ = '\\0';\n\t\tsargv[sargc++] = start;\n\t}\n}\n\n//**************************\n// time trace based on getticks function\n//**************************\ntypedef struct list_entry_t {\n\tstruct list_entry_t *next;\n\tstruct timespec ts;\n} ListEntry;\n\nstatic ListEntry *ts_list = NULL;\n\nstatic inline float msdelta(struct timespec *start, struct timespec *end) {\n\tunsigned sec = end->tv_sec - start->tv_sec;\n\tlong nsec = end->tv_nsec - start->tv_nsec;\n\treturn (float) sec * 1000 + (float) nsec / 1000000;\n}\n\nvoid timetrace_start(void) {\n\tListEntry *t = (ListEntry *) malloc(sizeof(ListEntry));\n\tif (!t)\n\t\terrExit(\"malloc\");\n\tmemset(t, 0, sizeof(ListEntry));\n\tclock_gettime(CLOCK_MONOTONIC, &t->ts);\n\n\t// add it to the list\n\tt->next = ts_list;\n\tts_list = t;\n}\n\nfloat timetrace_end(void) {\n\tif (!ts_list)\n\t\treturn 0;\n\n\t// remove start time  from the list\n\tListEntry *t = ts_list;\n\tts_list = t->next;\n\n\tstruct timespec end;\n\tclock_gettime(CLOCK_MONOTONIC, &end);\n\tfloat rv = msdelta(&t->ts, &end);\n\tfree(t);\n\treturn rv;\n}\n"
  },
  {
    "path": "src/common/utils.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef UTILS_H\n#define UTILS_H\n\n// run a user program using popen; returns static memory\nchar *run_program(const char *prog);\n\n// returns true or false if the program was found using \"which\" shell command\nbool which(const char *prog);\n\n// check if a name.desktop file exists in config home directory\nbool have_config_file(const char *name);\n\n// get a coniguration file path based on the name; returns allocated memory\nchar *get_config_file_name(const char *name);\n\n// get the full path of the home directory; returns allocated memory\nchar *get_home_directory();\n\n// get config directory name; returns allocated memory\nchar *get_config_directory();\n\n// create ~/.config/firetools directory if it doesn't exist\nvoid create_config_directory();\n\n// split a line into words\n#define SARG_MAX 128\nextern int sargc;\nextern char *sargv[SARG_MAX];\nvoid split_command(char *cmd);\n\n// timetrace\nvoid timetrace_start(void);\nfloat timetrace_end(void);\n\n\n#endif\n"
  },
  {
    "path": "src/firejail-ui/appdb.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n\n#if QT_VERSION >= 0x050000\n\t#include <QtWidgets>\n#else\n\t#include <QtGui>\n#endif\n\n#include \"appdb.h\"\n#include \"../../firetools_config_extras.h\"\n#include <QListWidget>\n#include <QLineEdit>\n#define MAXBUF 4096\n\nstatic bool check_executable(const char *exec) {\n\tstruct stat s;\n\tif (stat(exec, &s) == 0)\n\t\treturn true;\n\t\n\t// check well-known paths\n\tconst char *path[] = {\n\t\t\"/usr/bin/\",\n\t\t\"/bin/\",\n\t\t\"/usr/games/\",\n\t\t\"/usr/local/bin/\",\n\t\t\"/sbin/\",\n\t\t\"/usr/sbin/\",\n\t\tNULL\n\t};\n\t\n\tint i = 0;\n\twhile (path[i] != NULL) {\n\t\tbool found = false;\n\t\t\n\t\tchar *name;\n\t\tif (asprintf(&name, \"%s%s\", path[i], exec) == -1)\n\t\t\terrExit(\"asprintf\");\n\t\tif (stat(name, &s) == 0)\n\t\t\tfound = true;\n\t\tfree(name);\n\t\tif (found)\n\t\t\treturn true;\n\t\ti++;\n\t}\n\treturn false;\n}\n\n\nAppEntry::AppEntry(char *line) {\n\tassert(line);\n\tif (arg_debug)\n\t\tprintf(\"processing \\\"%s\\\"\\n\", line);\n\tgroup_ = QString(\"\");\n\tapp_ = QString(\"\");\n\tcommand_ = QString(\"\");\n\tnext_ = 0;\n\n\tchar *ptr = strtok(line, \";\");\n\tif (ptr) {\n\t\tgroup_ = QString(ptr);\n\t\tptr = strtok(NULL, \";\");\n\t\tif (ptr) {\n\t\t\tapp_ = QString(ptr);\n\t\t\tptr = strtok(NULL, \";\");\n\t\t\tif (ptr) {\n\t\t\t\tcommand_ = QString(ptr);\n\t\t\t\tif (command_.endsWith(\"*\")) {\n\t\t\t\t\tcommand_ = \"\";\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// try to find the executable\n\t\t\t\tchar *str = strdup(command_.toUtf8().data());\n\t\t\t\tif (!str)\n\t\t\t\t\terrExit(\"strdup\");\n\t\t\t\t\n\t\t\t\t// skip executables ending in *\n\t\t\t\t\n\t\t\t\tchar *ptr = strchr(str, ' ');\n\t\t\t\tif (ptr)\n\t\t\t\t\t*ptr = '\\0';\n\n\t\t\t\tif (check_executable(str) == false) {\t\t\t\t\n\t\t\t\t\tif (arg_debug)\n\t\t\t\t\t\tprintf(\"executable %s not found\\n\", str);\n\t\t\t\t\tcommand_ = QString(\"\");\n\t\t\t\t}\n\t\t\t\tfree(str);\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n\n// return the list of applications\nAppEntry* appdb_load_file(void) {\n\tconst char *fname = PACKAGE_LIBDIR \"/uimenus\";\n\tFILE *fp = fopen(fname, \"r\");\n\tif (!fp) {\n\t\tfprintf(stderr, \"Error: cannot find uimenus file in %s\\n\", fname);\n\t\treturn 0;\n\t}\n\tAppEntry *retval = 0;\n\tAppEntry *last = 0;\n\t\n\tchar buf[MAXBUF];\n\twhile (fgets(buf, MAXBUF, fp)) {\n\t\tchar *ptr1 = buf;\n\t\twhile (*ptr1 == ' ' || *ptr1 == '\\t')\n\t\t\tptr1++;\n\t\tchar *ptr2 = strchr(ptr1, '\\n');\n\t\tif (ptr2)\n\t\t\t*ptr2 = '\\0';\n\n\t\tAppEntry *entry = new AppEntry(ptr1);\n\t\tif (entry->group_.isEmpty() || entry->app_.isEmpty() || entry->command_.isEmpty()) {\n\t\t\tif (arg_debug)\n\t\t\t\tprintf(\"line not accepted\\n\");\n\t\t\tdelete entry;\n\t\t\tcontinue;\n\t\t}\n\t\t\n\t\t// add the app to the list\n\t\tif (!retval) {\n\t\t\tretval = entry;\n\t\t\tlast = entry;\n\t\t}\n\t\telse {\n\t\t\tlast->next_ = entry;\n\t\t\tlast = entry;\n\t\t}\n\t}\n\t\n\tfclose(fp);\n\tif (arg_debug)\n\t\tprintf(\"menus loaded\\n\");\t\n\treturn retval;\n}\n\n// print database\nvoid appdb_print_list(AppEntry *ptr) {\n\twhile (ptr) {\n\t\tptr->print();\n\t\tptr = ptr->next_;\n\t}\n}\n\n// add all groups to the widget\nvoid appdb_load_group(AppEntry *ptr, QListWidget *group) {\n\tQString last;\n\n\twhile (ptr) {\n\t\tif (last != ptr->group_) {\n\t\t\tnew QListWidgetItem(ptr->group_, group);\n\t\t}\n\t\tlast = ptr->group_;\n\t\tptr = ptr->next_;\n\t}\n\n}\n\n// add all groups to the widget\nvoid appdb_load_app(AppEntry *ptr, QListWidget *app, QString group) {\n\tapp->clear();\n\t\n\twhile (ptr) {\n\t\tif (group == ptr->group_) {\n\t\t\tnew QListWidgetItem(ptr->app_, app);\n\t\t}\n\t\tptr = ptr->next_;\n\t}\n}\n\nvoid appdb_set_command(AppEntry *ptr, QLineEdit *command, QString app) {\n\twhile (ptr) {\n\t\tif (app == ptr->app_) {\n\t\t\tcommand->setText(ptr->command_);\n\t\t\tbreak;\n\t\t}\n\t\tptr = ptr->next_;\n\t}\n}\n"
  },
  {
    "path": "src/firejail-ui/appdb.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n#ifndef APPDB_H\n#define APPDB_H\n\n#include \"firejail_ui.h\"\n#include <QString>\nclass QListWidget;\nclass QLineEdit;\n\nstruct AppEntry {\n\tQString group_;\n\tQString app_;\n\tQString command_;\n\tAppEntry *next_;\n\t\n\tAppEntry(char *line);\n\tvoid print() {\n\t\tprintf(\"%s;%s;%s\\n\", group_.toUtf8().data(), app_.toUtf8().data(), command_.toUtf8().data());\n\t}\n\n};\n\nAppEntry *appdb_load_file(void);\nvoid appdb_print_list(AppEntry *ptr);\nvoid appdb_load_group(AppEntry *ptr, QListWidget *group);\nvoid appdb_load_app(AppEntry *ptr, QListWidget *app, QString group);\nvoid appdb_set_command(AppEntry *ptr, QLineEdit *command, QString app);\n\n#endif\n"
  },
  {
    "path": "src/firejail-ui/firejail-ui.desktop",
    "content": "[Desktop Entry]\nName=Firejail Configuration Wizard\nComment=Firejail configuration wizard\nExec=firejail-ui\nIcon=firejail-ui\nTerminal=false\nType=Application\nCategories=Qt;Utility;Security;\nKeywords=jail;security;seccomp;\n"
  },
  {
    "path": "src/firejail-ui/firejail-ui.pro",
    "content": "QMAKE_CXXFLAGS += $$(CXXFLAGS) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security\nQMAKE_CFLAGS += $$(CFLAGS) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security\nQMAKE_LFLAGS += $$(LDFLAGS) -Wl,-z,relro -Wl,-z,now\nQT += widgets\n HEADERS       = ../common/utils.h ../common/pid.h ../common/common.h \\\n \t\tfirejail_ui.h wizard.h home_widget.h help_widget.h appdb.h\n SOURCES       = main.cpp \\\n \t\twizard.cpp \\\n \t\thome_widget.cpp \\\n \t\thelp_widget.cpp \\\n \t\tappdb.cpp \\\n \t\tnetwork.cpp \\\n\t\t../common/utils.cpp \\\n\t\t../common/pid.cpp\nRESOURCES = firejail-ui.qrc\nTARGET=../../build/firejail-ui\n"
  },
  {
    "path": "src/firejail-ui/firejail-ui.qrc",
    "content": "<!DOCTYPE RCC><RCC version=\"1.0\">\n<qresource prefix=\"/\">\n   <file>resources/background.png</file>\n   <file>resources/firetools.png</file>\n   <file>resources/firetools-minimal.png</file>\n   <file>resources/firejail-ui.png</file>\n   <file>resources/gnome-fs-directory.png</file>\n</qresource>\n</RCC>\n"
  },
  {
    "path": "src/firejail-ui/firejail_ui.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef FIREJAIL_UI_H\n#define FIREJAIL_UI_H\n#include \"../common/common.h\"\n\nextern int arg_debug;\nextern int kernel_major;\nextern int kernel_minor;\n\n// network.cpp\nconst char *detect_network();\n\n#endif\n"
  },
  {
    "path": "src/firejail-ui/help_widget.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n \n#if QT_VERSION >= 0x050000\n\t#include <QtWidgets>\n#else\n\t#include <QtGui>\n#endif\n#include <QTextBrowser>\n#include <QVBoxLayout>\n#include <QDialogButtonBox>\n#include <QPushButton>\n#include \"help_widget.h\"\n#include \"../../firetools_config_extras.h\"\n\n#define MAXBUF 4096\n\nHelpWidget::HelpWidget(QWidget * parent): QDialog(parent) {\n\tQString message;\n\tconst char *fname = PACKAGE_LIBDIR \"/uihelp\";\n//todo error recovery\n\tFILE *fp = fopen(fname, \"r\");\n\tif (!fp) {\n\t\tfprintf(stderr, \"Error: cannot find uihelp file in %s\\n\", fname);\n\t\treturn;\n\t}\n\tchar buf[MAXBUF];\n\twhile (fgets(buf, MAXBUF, fp))\n\t\tmessage += QString(buf);\n\tfclose(fp);\n\n\tQTextBrowser *browser = new QTextBrowser;\n\tbrowser->setHtml(message);\n\n\tQDialogButtonBox *box = new QDialogButtonBox( Qt::Horizontal );\n\tQPushButton *button = new QPushButton( \"Ok\" );\n\tconnect( button, SIGNAL(clicked()), this, SLOT(okClicked()) );\n\tbox->addButton( button, QDialogButtonBox::AcceptRole );\n\n\n\tQVBoxLayout *layout = new QVBoxLayout;\n\tlayout->addWidget(browser);\n\tlayout->addWidget(box);\n\tsetLayout(layout);\n\tsetMinimumWidth(600);\n\tsetMinimumHeight(400);\n}\n\nvoid HelpWidget::okClicked() {\n\taccept();\n}\n"
  },
  {
    "path": "src/firejail-ui/help_widget.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n#ifndef HELP_WIDGET_H\n#define HELP_WIDGET_H\n\n#include \"firejail_ui.h\"\n#include <QDialog>\n\nclass HelpWidget: public QDialog {\n\tQ_OBJECT\n\npublic:\n\tHelpWidget(QWidget * parent = 0);\nprivate slots:\n\tvoid okClicked();\n\n};\n\n#endif\n\n"
  },
  {
    "path": "src/firejail-ui/home_widget.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n\n#if QT_VERSION >= 0x050000\n\t#include <QtWidgets>\n#else\n\t#include <QtGui>\n#endif\n\n#include <QCheckBox>\n#include \"firejail_ui.h\"\n#include \"home_widget.h\"\n#include \"../common/utils.h\"\n#include <dirent.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <unistd.h>\n\n\nHomeWidget::HomeWidget(QWidget * parent): QListWidget(parent) {\n\treadFiles();\n}\n\nvoid HomeWidget::readFiles() {\n\tchar *homedir = get_home_directory();\n\tDIR *dir = opendir(homedir);\n\tif (!dir)\n\t\terrExit(\"opendir\");\n\t\n\tstruct dirent *entry;\n\twhile ((entry = readdir(dir))) {\n\t\t// with a few exceptions, reject all dot files\n\t\tbool accept = false;\n\t\tif (strcmp(entry->d_name, \".config\") == 0 ||\n\t\t    strcmp(entry->d_name, \".mozilla\") == 0)\n\t\t    \taccept = true;\n\t\tif (!accept && *entry->d_name == '.')\n\t\t\tcontinue;\n\t\t\n\t\t// allow only directorries \n\t\tstruct stat s;\n\t\tchar *name;\n\t\tif (asprintf(&name, \"%s/%s\", homedir, entry->d_name) == -1)\n\t\t\terrExit(\"asprintf\");\n\t\tif (stat(name, &s) == -1) {\n\t\t\tfree(name);\n\t\t\tcontinue;\n\t\t}\n\t\tfree(name);\n\t\tif (!S_ISDIR(s.st_mode))\n\t\t\tcontinue;\n\n\t\tif (arg_debug)\n\t\t\tprintf(\"configuring homewidget entry %s\\n\", entry->d_name);\n\n\t\tQCheckBox *box = new QCheckBox(entry->d_name);\n\t\tQListWidgetItem *item = new QListWidgetItem();\n\t\taddItem(item);\n\t\tsetItemWidget(item, box);\n\t}\n\t\n\tclosedir(dir);\n}\n\nQString HomeWidget::getContent() {\n\tQString retval = QString(\"\");\n\n\tfor(int i = 0; i < count(); ++i) {\n\t\tQListWidgetItem* ptr = item(i);\n\t\t\n\t\tQCheckBox *box = (QCheckBox *) itemWidget(ptr);\n\t\tif (box->isChecked()) {\n\t\t\tQString name = box->text();\n\t\t\tretval += \"whitelist ~/\" + box->text() + \"\\n\";\n\t\t}\t\n\t}\n\n\treturn retval;\n\n}\n"
  },
  {
    "path": "src/firejail-ui/home_widget.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n#ifndef HOME_WIDGET_H\n#define HOME_WIDGET_H\n\n#include \"firejail_ui.h\"\n#include <QListWidget>\n\n\nclass HomeWidget : public QListWidget {\n\tQ_OBJECT\n\npublic:\n\tHomeWidget(QWidget * parent = 0);\n\tQString getContent();\n\nprivate:\n\tvoid readFiles();\n};\n\n#endif\n\n"
  },
  {
    "path": "src/firejail-ui/main.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n#include <QApplication>\n#include <QMenu>\n#include <QSystemTrayIcon>\n#include <QLibraryInfo>\n#include <QWizard>\n#include <sys/utsname.h>\n\n#include \"firejail_ui.h\"\n#include \"wizard.h\"\n#include \"../common/utils.h\"\n#include \"../../firetools_config.h\"\n\nint arg_debug = 0;\nint kernel_major;\nint kernel_minor;\n\nstatic void usage() {\n\tprintf(\"Firejail-ui - Firejail sandbox configuration wizard\\n\\n\");\n\tprintf(\"Usage: firejail-ui [options]\\n\\n\");\n\tprintf(\"Options:\\n\");\n\tprintf(\"\\t--debug - debug mode\\n\\n\");\n\tprintf(\"\\t--help - this help screen\\n\\n\");\n\tprintf(\"\\t--version - print software version and exit\\n\\n\");\n}\n\n\nint main(int argc, char *argv[]) {\n\t// parse arguments\n\tfor (int i = 1; i < argc; i++) {\n\t\tif (strcmp(argv[i], \"--debug\") == 0)\n\t\t\targ_debug = 1;\n\t\telse if (strcmp(argv[i], \"--help\") == 0 || strcmp(argv[i], \"-?\") == 0) {\n\t\t\tusage();\n\t\t\treturn 0;\n\t\t}\n\t\telse if (strcmp(argv[i], \"--version\") == 0) {\n\t\t\tprintf(\"Firejail-ui version \" PACKAGE_VERSION \"\\n\");\n\t\t\treturn 0;\n\t\t}\n\t\telse {\n\t\t\tfprintf(stderr, \"Error: invalid option\\n\");\n\t\t\tusage();\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\t// test run time dependencies - exit\n\tif (!which(\"firejail\")) {\n\t\tfprintf(stderr, \"Error: firejail package not found, please install it!\\n\");\n\t\texit(1);\n\t}\n\n\t// create firetools directory if it doesn't exist\n\tcreate_config_directory();\n\n\t// read kernel version\n\tstruct utsname u;\n\tint rv = uname(&u);\n\tif (rv != 0)\n\t\terrExit(\"uname\");\n\tif (2 != sscanf(u.release, \"%d.%d\", &kernel_major, &kernel_minor)) {\n\t\tfprintf(stderr, \"***********************************\\n\");\n\t\tfprintf(stderr, \"Warning: cannot extract a sane Linux kernel version: %s.\\n\", u.version);\n\t\tfprintf(stderr, \"         Assuming a default version of 3.2. Quite a number of sandboxing\\n\");\n\t\tfprintf(stderr, \"         features are disabled.\\n\");\n\t\tfprintf(stderr, \"***********************************\\n\");\n\t}\n\tif (kernel_major < 3) {\n\t\tfprintf(stderr, \"Error: a Linux kernel 3.x or newer is required in order to run Firejail\\n\");\n\t\texit(1);\n\t}\n\n\tif (arg_debug)\n\t\tprintf(\"Linux kernel version %d.%d\\n\", kernel_major, kernel_minor);\n\n\t// initialize resources\n\t//Q_INIT_RESOURCE(firejail-ui);\n\n\tQApplication app(argc, argv);\n\tWizard wizard;\n\twizard.show();\n\treturn app.exec();\n}\n"
  },
  {
    "path": "src/firejail-ui/network.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n\n#include \"firejail_ui.h\"\n#ifndef _GNU_SOURCE\n#define _GNU_SOURCE\n#endif\n#include <arpa/inet.h>\n#include <sys/socket.h>\n#include <netdb.h>\n#include <ifaddrs.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <linux/if.h>\n#include <linux/if_link.h>\n#include <linux/wireless.h>\n#include <sys/ioctl.h>\n\n#define BUFSIZE 1024\n\n// return default gateway for the system in host format\nuint32_t network_get_defaultgw() {\n\tFILE *fp = fopen(\"/proc/self/net/route\", \"r\");\n\tif (!fp)\n\t\t// probably we are dealing with a GrSecurity system\n\t\treturn 0; // attempt error recovery\n\n\tchar buf[BUFSIZE];\n\tuint32_t retval = 0;\n\twhile (fgets(buf, BUFSIZE, fp)) {\n\t\tif (strncmp(buf, \"Iface\", 5) == 0)\n\t\t\tcontinue;\n\n\t\tchar *ptr = buf;\n\t\twhile (*ptr != ' ' && *ptr != '\\t')\n\t\t\tptr++;\n\t\twhile (*ptr == ' ' || *ptr == '\\t')\n\t\t\tptr++;\n\n\t\tunsigned dest;\n\t\tunsigned gw;\n\t\tint rv = sscanf(ptr, \"%x %x\", &dest, &gw);\n\t\tif (rv == 2 && dest == 0) {\n\t\t\tretval = ntohl(gw);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tfclose(fp);\n\treturn retval;\n}\n\n\n\n// return 1 if the interface is a wireless interface\nint check_wireless(const char* ifname, char* protocol) {\n\tint sock = -1;\n\tstruct iwreq pwrq;\n\tmemset(&pwrq, 0, sizeof(pwrq));\n\tint len = strlen(ifname);\n\tif (len > IFNAMSIZ)\n\t\tlen = IFNAMSIZ;\n\tmemcpy(pwrq.ifr_name, ifname, len);\n\n\tif ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {\n\t\tperror(\"sockqet\");\n\t\treturn 0;\n\t}\n\n\tif (ioctl(sock, SIOCGIWNAME, &pwrq) != -1) {\n\t\tif (protocol)\n\t\t\tstrncpy(protocol, pwrq.u.name, IFNAMSIZ);\n\t\tclose(sock);\n\t\treturn 1;\n\t}\n\n\tclose(sock);\n\treturn 0;\n}\n\n// detect network\nconst char *detect_network() {\n\tstruct ifaddrs *ifaddr, *ifa;\n\n\tif (getifaddrs(&ifaddr) == -1)\n\t\terrExit(\"getifaddrs\");\n\n\t// find the default gateway\n\tuint32_t gw = network_get_defaultgw();\n\tprintf(\"default gateway detected: %d.%d.%d.%d\\n\", PRINT_IP(gw));\n\tif (gw == 0) {\n\t\tfprintf(stderr, \"Warning: cannot find the default gateway. Networking namespace is disabled.\\n\");\n\t\treturn \"\";\n\t}\n\n\t// Walk through linked list, maintaining head pointer so we can free list later\n\tfor (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {\n\t\tif (ifa->ifa_addr == NULL)\n\t\t\tcontinue;\n\n\t\tint family = ifa->ifa_addr->sa_family;\n\t\tif (family != AF_INET)\n\t\t\tcontinue;\n\n\t\t// no loopback\n\t\tif (ifa->ifa_flags & IFF_LOOPBACK)\n\t\t\tcontinue;\n\n\t\t// interface not running\n\t\tif ((ifa->ifa_flags & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING))\n\t\t\tcontinue;\n\n\t\t// no wireless\n\t\tif (check_wireless(ifa->ifa_name, NULL))\n\t\t\tcontinue;\n\n\t\tuint32_t if_addr = ntohl(((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr);\n\t\tuint32_t if_mask = ntohl(((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr.s_addr);\n\t\tprintf(\"network interface: %s %d.%d.%d.%d %d.%d.%d.%d\\n\",\n\t\t\tifa->ifa_name, PRINT_IP(if_addr), PRINT_IP(if_mask));\n\n\t\t// check default gateway is resolved on this interface\n\t\tif (in_netrange(gw, if_addr, if_mask) == NULL) {\n\t\t\tchar *ifname = strdup(ifa->ifa_name);\n\t\t\tif (!ifname)\n\t\t\t\terrExit(\"strdup\");\n\t\t\tfreeifaddrs(ifaddr);\n\t\t\treturn ifname;\n\t\t}\n\t}\n\tfprintf(stderr, \"Warning: no suitable interface detected for network namespace.\\n\");\n\tfreeifaddrs(ifaddr);\n\treturn \"\";\n}\n"
  },
  {
    "path": "src/firejail-ui/restrictions",
    "content": "Sandbox feature dependencies:\n\n- seccomp, nonewprivs, protocol - kernel 3.5 (done)\n- noroot - kernel 3.8 (done)\n- overlayfs - kernel 3.18\n- nox11 only with a network namespace (done)\n- net= doesn't work on wireless interfaces\n"
  },
  {
    "path": "src/firejail-ui/uihelp",
    "content": "<br/><center><b>Sandbox Configuration</b></center><br/><br/><br/>\nAlthough hundreds of user-space applications are already supported by Firejail,\nsometimes is necessary to customize the sandbox environment. This configuration\nwizard was built in order to make this task easier.<br/><br/>\nStart with the filesystem configuration, move to the network and\nmultimedia subsystems, and finish with the kernel. In the end you can fine tune\nyour profile in the editor window.<br/>\n<br/><b>Filesystem</b><br/><br/>\nPersonal user files are located in home directory.\nBy default Firejail denies access to some of the most sensitive files there,\nsuch as password and encryption keys.\nTo enhance your privacy, these are some of the options available:<br>\n<blockquote>\n<i><b>Restrict home directory:</b> Choose private user directories visible inside the sandbox.\nBy default, with the exception of some well-known password and encryption files,\nall private user files are visible inside the sandbox.</i><br/><br/>\n<i><b>Restrict /dev directory:</b> A small number of very basic devices are visible inside the sandbox.\nSound and 3D acceleration should also be available if this checkbox is set.<br/><br/>\n<b>Restrict /tmp directory:</b> Start with a clean /tmp directory.<br/><br/>\n<b>Restrict /mnt and /media:</b> Blacklist /mnt and /media directories.</i><br/><br/>\n</blockquote>\n<b>Networking</b><br/><br/>\nA network namespace is a separate copy of TCP/IP networking stack.\nInitially, all processes share the same networking stack created by the init process.\nFirejail allows users to create a new network namespace, therefore isolating\nthe sandbox traffic.\n\n<blockquote>\n<i><b>System network:</b></i> Use the default networking stack provided by the system.<br/><br/>\n<i><b>Network namespace:</b></i> Install a separate networking stack and connect it to the\nmain Ethernet interface. A new IP address is assigned, and a new network filter is installed\nusing <i>iptables</i> command.<br/><br/>\n<i><b>Disable networking:</b></i> Use an unconnected network stack. There will be no traffic\ncoming in or going out of the sandbox.<br/><br/>\n<i><b>DNS:</b></i> Specify two DNS nameservers to use inside the sandbox. If none is specified,\nthe sandbox will use the system DNS server.<br/><br/>\n<i><b>Protocol:</b></i> Select what networking protocols are allowed: unix (regular\nUnix inter-process communication), inet (IPv4), inet6 (IPv6), netlink (socket communication with Linux\nkernel), packet (Ethernet-level protocols), and bluetooth.\n</blockquote>\n<br/><b>Multimedia</b><br/><br/>\nIf the application is not using sound or 3D acceleration, it is always a good idea to drop the support\ninside the sandbox. Disabling X11 graphic interface is recommended when running servers and console programs.\n<blockquote>\n<i><b>Disable sound:</b></i> No sound subsystem access inside the sandbox.<br/><br/>\n<i><b>Disable video camera devices:</b></i> No video camera access.<br/><br/>\n<i><b>Disable CD-ROM/DVD devices:</b></i> No access to CD-ROM device.<br/><br/>\n<i><b>Disable TV/DVB devices:</b></i> TV cards are disabled.<br/><br/>\n<i><b>Disable 3D acceleration:</b></i> Hardware acceleration drivers are disabled.<br/><br/>\n<i><b>Disable X11:</b></i> X11 graphical user interface subsystem is disabled.\n<br/><br/>\n</blockquote>\n<b>Kernel</b><br/><br/>\nThese are some of the most powerful sandboxing features implemented by the Linux kernel:\n<blockquote>\n<i><b>Enable seccomp-bpf:</b></i> This security facility allows filtering out the most dangerous system calls\ninside the kernel, therefore reducing the attack surface.\nA Linux Kernel version 3.5 is required for this option to work.<br/><br/>\n<i><b>Disable all Linux capabilities:</b></i> Capabilities (POSIX 1003.1e) are designed to split up the root privilege\ninto a set of distinct privileges which can be independently enabled or disabled. For regular user-space programs,\nall these privileges should be disabled.<br/><br/>\n<i><b>Restricted user namespace (noroot):</b></i> This option installs a user namespace with a single\nuser, the current  user. <i>root</i> user  does  not  exist  in  the new namespace.\nA Linux Kernel version 3.8 is required for this option to work.<br/><br/>\n<i><b>AppArmor</b></i> This option enables Firejail's default AppArmor profile for your program.<br/><br/>\n</blockquote>\n"
  },
  {
    "path": "src/firejail-ui/uimenus",
    "content": "Accessibility;Florence virtual keyboard;/usr/bin/florence\nAccessibility;Xmag;xmag\nEditors;GEdit;/usr/bin/gedit\nEditors;Abiword Word Processor;/usr/bin/abiword\nEditors;Bluefish;/usr/bin/bluefish\nEditors;CherryTree Note Taking Application;/usr/bin/cherrytree\nEditors;Focuswriter;/usr/bin/focuswriter\nEditors;FTE;/usr/bin/xfte\nEditors;GNU Emacs Editor;/usr/bin/emacs\nEditors;jEdit;/usr/bin/jedit\nEditors;JuffEd;/usr/bin/juffed\nEditors;KWrite;/usr/bin/kwrite\nEditors;LeafPad;/usr/bin/leafpad\nEditors;LyX;/usr/bin/lyx\nEditors;medit;/usr/bin/medit\nEditors;Monkey Studio;/usr/bin/monkeystudio\nEditors;Mousepad;/usr/bin/mousepad\nEditors;NEdit;/usr/bin/nedit\nEditors;nobleNote;/usr/bin/noblenote\nEditors;Plume Creator;/usr/bin/plume-creator\nEditors;PyRoom;/usr/bin/pyroom\nEditors;Quanta Plus;/usr/bin/quanta\nEditors;ReText;/usr/bin/retext\nEditors;SciTE;/usr/bin/scite\nEditors;Sigil;/usr/bin/sigil\nEditors;TEA;/usr/bin/tea\nEditors;TeXstudio;/usr/bin/texstudio\nEditors;TeXworks;/usr/bin/texworks\nEditors;X2;/usr/bin/x2\nEditors;Xedit;xedit\nEditors;xJed;/usr/bin/xjed\nEditors;Notes;/usr/bin/xfce4-notes\nEditors;Pluma;/usr/bin/pluma\nEditors;Xed;/usr/bin/xed\nEmulators;VirtualBox;/usr/bin/virtualbox\nFile Management;File Roller Archive Manager;/usr/bin/file-roller\nFile Management;Engrampa;/usr/bin/engrampa\nFile Management;Brasero CD/DVD Burning Application;/usr/bin/brasero\nFile Management;Caja File Manager;/usr/bin/caja\nFile Management;Dolphin File Manager;/usr/bin/dolphin\nFile Management;gentoo File Manager;/usr/bin/gentoo\nFile Management;GNOME Commander File Manager;/usr/bin/gnome-commander\nFile Management;Konqueror File Manager;/usr/bin/konqueror\nFile Management;Krusader File Manager;/usr/bin/krusader\nFile Management;Launchy;/usr/bin/launchy\nFile Management;Nautilus File Manager;/usr/bin/nautilus\nFile Management;Nemo File Manager;/usr/bin/nemo\nFile Management;PCManFM File Manager;pcmanfm\nFile Management;ROX-Filer File Manager;/usr/bin/rox-filer\nFile Management;SpaceFM File Manager;/usr/bin/spacefm\nFile Management;Thunar File Manager;/usr/bin/thunar\nFile Management;Worker File Manager;/usr/bin/worker\nFile Management;Xarchiver;/usr/bin/xarchiver\nFile Management;Xfe File Manager;/usr/bin/xfe\nFile Management;Desktop Search;/usr/bin/tracker-needle\nGames;0 A.D.;/usr/games/0ad\nGames;2048 puzzle;/usr/games/2048-qt\nGames;3dchess;/usr/games/3Dc\nGames;4digits;/usr/games/4digits\nGames;ALIEN ARENA;/usr/games/alien-arena\nGames;AssaultCube;/usr/games/assaultcube\nGames;Blobwars;/usr/games/blobwars\nGames;Bomber;/usr/games/bomber\nGames;Extreme Tux Racer;/usr/games/etr\nGames;Flight Gear;/usr/games/fgfs\nGames;Freeciv;/usr/games/freeciv\nGames;Frozen-Bubble;/usr/games/frozen-bubble\nGames;Hedgewars;/usr/games/hedgewars\nGames;Micropolis;/usr/games/micropolis\nGames;Nexuiz Classic;/usr/games/nexuiz\nGames;Oclock;oclock\nGames;Open Transport Tycoon Deluxe;/usr/games/openttd\nGames;Penguin Command;/usr/games/penguin-command\nGames;Quake 4;/usr/games/quake4\nGames;Quake III Arena;/usr/games/quake3\nGames;Quake II;/usr/games/quake2\nGames;Quake;/usr/games/quake\nGames;Return to Castle Wolfenstein;/usr/games/wolfsp\nGames;Scorched3D;/usr/games/scorched3d\nGames;Seven Kingdoms;/usr/games/7kaa\nGames;Simutrans;/usr/games/simutrans\nGames;Starfighter;/usr/games/starfighter\nGames;SuperTuxKart;/usr/games/supertuxkart\nGames;SuperTux;/usr/games/supertux2\nGames;TORCS;/usr/games/torcs\nGames;UFO: Alien Invasion;/usr/games/ufoai\nGames;Unknown Horizons;/usr/games/unknown-horizons\nGames;Warzone 2100;/usr/games/warzone2100\nGames;Wolfenstein 3D;/usr/games/wolf4sdl\nGames;Xclock (analog);xclock -analog\nGames;Xclock (digital);xclock -digital -update 1\nGames;Xeyes;xeyes\nGames;Xlogo;xlogo\nGraphics;Allegro Sprite Editor;/usr/bin/aseprite\nGraphics;Blender;/usr/bin/blender\nGraphics;Darktable;/usr/bin/darktable\nGraphics;Diagram editor;/usr/bin/dia\nGraphics;digiKam;/usr/bin/digikam\nGraphics;gnome-paint;/usr/bin/gnome-paint\nGraphics;ImageMagick;/usr/bin/display.im6 logo:*\nGraphics;Inkscape;/usr/bin/inkscape\nGraphics;Ipe;/usr/bin/ipe\nGraphics;K-3D;/usr/bin/k3d\nGraphics;Karbon;/usr/bin/karbon\nGraphics;Krita;/usr/bin/krita\nGraphics;luminance-hdr;/usr/bin/luminance-hdr\nGraphics;mtPaint;/usr/bin/mtpaint\nGraphics;MyPaint;/usr/bin/mypaint\nGraphics;Ocamlgraph;/usr/bin/ocamlgraph-editor\nGraphics;Pencil2D;/usr/bin/pencil2d\nGraphics;PhotoCollage;/usr/bin/photocollage\nGraphics;Pinta;/usr/bin/pinta\nGraphics;rgbPaint;/usr/bin/rgbpaint\nGraphics;showFoto;/usr/bin/showfoto\nGraphics;Synfig Studio;/usr/bin/synfigstudio\nGraphics;Tgif;/usr/bin/tgif\nGraphics;The GIMP;/usr/bin/gimp\nGraphics;Trimage;/usr/bin/trimage\nGraphics;tupi - 2D Animation design and authoring tool;/usr/bin/tupi\nGraphics;Tux Paint;/usr/bin/tuxpaint\nGraphics;Whitedune;/usr/bin/whitedune\nGraphics;XPaint;/usr/bin/xpaint\nGraphics;X Window Snapshot;xwd | xwud*\nGraphics;Shotwell Photo Manager;/usr/bin/shotwell\nGraphics;Screenshot;/usr/bin/xfce4-screenshooter\nGraphics;Gnome Screenshot;/usr/bin/gnome-screenshot\nGraphics;Mate Screenshot;/usr/bin/mate-screenshot\nGraphics;Ristretto Image Viewer;/usr/bin/ristretto\nGraphics;Simple Scan;/usr/bin/simple-scan\nHelp;Xman;xman\nHelp;yelp;/usr/bin/yelp\nNetwork;Chromium;/usr/bin/chromium\nNetwork;Chromium;/usr/bin/chromium-browser\nNetwork;Deluge BitTorrent Client;/usr/bin/deluge\nNetwork;Dillo;/usr/bin/dillo\nNetwork;dwb;/usr/bin/dwb\nNetwork;FileZilla;/usr/bin/filezilla\nNetwork;Firefox-ESR;/usr/bin/firefox-esr\nNetwork;Firefox;/usr/bin/firefox\nNetwork;HexChat;/usr/bin/hexchat\nNetwork;Hv3;/usr/bin/hv3\nNetwork;Icedove Mail;icedove\nNetwork;Iceweasel;/usr/bin/iceweasel\nNetwork;Konqueror;/usr/bin/konqueror\nNetwork;Liferea;/usr/bin/liferea\nNetwork;Netsurf Web Browser;/usr/bin/netsurf-gtk\nNetwork;qBittorrent;/usr/bin/qbittorrent\nNetwork;QuiteRSS;/usr/bin/quiterss\nNetwork;Transmission BitTorrent Client (GTK);/usr/bin/transmission-gtk\nNetwork;Transmission BitTorrent Client (Qt);/usr/bin/transmission-qt\nNetwork;Uget;/usr/bin/uget-gtk\nNetwork;Wireshark;/usr/bin/wireshark\nNetwork;Xbiff;xbiff\nNetwork;X Chat;/usr/bin/xchat\nNetwork;xtightvncviewer;/usr/bin/xtightvncviewer\nNetwork;Thunderbird;/usr/bin/thunderbird\nNetwork;Pidgin;/usr/bin/pidgin\nNetwork;Remmina Remote Desktop Client;/usr/bin/remmina\nOffice;Calibre eBook reader;/usr/bin/calibre\nOffice;LibreOffice Base;/usr/bin/lobase\nOffice;LibreOffice Calc;/usr/bin/localc\nOffice;LibreOffice Charts;/usr/bin/locharts\nOffice;LibreOffice Draw;/usr/bin/lodraw\nOffice;LibreOffice Impress;/usr/bin/loimpress\nOffice;LibreOffice Math;/usr/bin/lomath\nOffice;LibreOffice;/usr/bin/libreoffice\nOffice;LibreOffice Writer;/usr/bin/lowriter\nOffice;Scribus;/usr/bin/scribus\nOffice;zathura;/usr/bin/zathura\nOffice;Dictionary;/usr/bin/xfce4-dict\nOffice;Orage Calendar;/usr/bin/orage\nProgramming;Geany;/usr/bin/geany\nProgramming;TkWish8.6;x-terminal-emulator -e /usr/bin/wish8.6\nScience;galculator;/usr/bin/galculator\nScience;Xcalc;xcalc\nScience;Gnome Calculator;/usr/bin/gnome-calculator\nScience;Calculator;/usr/bin/mate-calc\nSound;Alsamixergui;/usr/bin/alsamixergui\nSound;Amarok;/usr/bin/amarok\nSound;AScd;/usr/bin/ascd\nSound;Asunder;/usr/bin/asunder\nSound;Audacious;/usr/bin/audacious\nSound;Audacity;/usr/bin/audacity\nSound;Banshee;/usr/bin/banshee\nSound;cccd;/usr/bin/cccd\nSound;Clementine;/usr/bin/clementine\nSound;Echomixer;/usr/bin/echomixer\nSound;Envy24 control;/usr/bin/envy24control\nSound;HDAJackRetask;/usr/bin/hdajackretask\nSound;HDSPConf;/usr/bin/hdspconf\nSound;HDSPMixer;/usr/bin/hdspmixer\nSound;KMix;/usr/bin/kmix\nSound;Kowthelist;/usr/bin/knowthelist\nSound;KRadio;/usr/bin/kradio4\nSound;KsCD;/usr/bin/kscd\nSound;Linux Multimedia Studio;/usr/bin/lmms\nSound;LXMusic;/usr/bin/lxmusic\nSound;MusE MIDI/audio sequencer;/usr/bin/muse\nSound;MuseScore;/usr/bin/musescore\nSound;Musique;/usr/bin/musique\nSound;paman;/usr/bin/paman\nSound;pavucontrol;/usr/bin/pavucontrol\nSound;pavumeter;/usr/bin/pavumeter\nSound;PulseAudio Volume Control;/usr/bin/pavucontrol\nSound;PulseAudio Volume Meter;/usr/bin/pavumeter\nSound;Rmedigicontrol;/usr/bin/rmedigicontrol\nSound;Rhythmbox;/usr/bin/rhythmbox\nSound;Sound Juicer;/usr/bin/sound-juicer\nSystem;About Myself;/usr/bin/userinfo\nSystem;Disk Management;/usr/bin/usermount\nSystem;Editres;editres\nSystem;GNOME partition editor;su-to-root -X -c /usr/sbin/gparted\nSystem;Network Admin;/usr/bin/network-admin\nSystem;Openbox Configuration Manager;/usr/bin/obconf\nSystem;Password;/usr/bin/userpasswd\nSystem;Reportbug (GTK+);/usr/bin/reportbug --exit-prompt --ui gtk2\nSystem;Services Admin;/usr/bin/services-admin\nSystem;Shares Admin;/usr/bin/shares-admin\nSystem;Time Admin;/usr/bin/time-admin\nSystem;User accounts Admin;/usr/bin/users-admin\nSystem;Xclipboard;xclipboard\nSystem;Xconsole;xconsole -file /dev/xconsole\nSystem;Xev;x-terminal-emulator -e xev\nSystem;Xfontsel;xfontsel\nSystem;Xkill;xkill\nSystem;Xload;xload\nSystem;Xrefresh;xrefresh\nSystem;Xvidtune;xvidtune\nSystem;Orage Globaltime;/usr/bin/globaltime\nTerminal Emulators;Gnome Terminal;/usr/bin/gnome-terminal\nTerminal Emulators;LXTerminal;/usr/bin/lxterminal\nTerminal Emulators;Rxvt-Unicode (Black, Xft);urxvt\nTerminal Emulators;Xfce Terminal;/usr/bin/xfce4-terminal\nTerminal Emulators;X-Terminal as root (GKsu);/usr/bin/gksu -u root /usr/bin/x-terminal-emulator\nTerminal Emulators;XTerm (Unicode);uxterm\nTerminal Emulators;XTerm;xterm\nText;Character map;/usr/bin/gucharmap\nVideo;Bino;/usr/bin/bino\nVideo;DeVeDe;/usr/bin/devede\nVideo;Dragon Player;/usr/bin/dragon\nVideo;DvdAuthor;/usr/bin/dvdauthor\nVideo;DVD slide show maker;/usr/bin/imagination\nVideo;Flowblade Movie Editor;/usr/bin/flowblade\nVideo;Flowblade;/usr/bin/flowblade\nVideo;FreetuxTV;/usr/bin/freetuxtv\nVideo;gnome-mplayer;/usr/bin/gnome-mplayer\nVideo;gnome-mpv;/usr/bin/gnome-mpv\nVideo;gxine;/usr/bin/gxine\nVideo;HandBrake;/usr/bin/handbrake\nVideo;Kaffeine;/usr/bin/kaffeine\nVideo;Kazam;/usr/bin/kazam\nVideo;Kdenlive;/usr/bin/kdenlive\nVideo;Kino;/usr/bin/kino\nVideo;KMPlayer;/usr/bin/kmplayer\nVideo;KPlayer;/usr/bin/kplayer\nVideo;LiVES;/usr/bin/lives\nVideo;Minitube;/usr/bin/minitube\nVideo;MKV Creator;/usr/bin/mmg\nVideo;MPlayer GUI;/usr/bin/gmplayer\nVideo;MPlayer;/usr/bin/mplayer\nVideo;mpv Media Player;/usr/bin/mpv\nVideo;OpenShot Video Editor;/usr/bin/openshot\nVideo;qStopMotion;/usr/bin/qstopmotion\nVideo;Simple Screen Recorder;/usr/bin/simplescreenrecorder\nVideo;SMPlayer;/usr/bin/smplayer\nVideo;SMTube;/usr/bin/smtube\nVideo;Snappy;/usr/bin/snappy\nVideo;Totem;/usr/bin/totem\nVideo;Xplayer;/usr/bin/xplayer\nVideo;tvtime;/usr/bin/tvtime\nVideo;VLC media player;/usr/bin/qvlc\nVideo;Voctomix;/usr/bin/voctogui\nVideo;vokoscreen;/usr/bin/vokoscreen\nVideo;Xine;/usr/bin/xine\nViewers;Evince;/usr/bin/evince\nViewers;Atril;/usr/bin/atril\nViewers;Xreader;/usr/bin/xreader\nViewers;Eye of MATE;/usr/bin/eom\nViewers;Eye of Gnome;/usr/bin/eog\nViewers;Xviewer;/usr/bin/xviewer\nViewers;Geeqie;/usr/bin/geeqie\nViewers;GPicView;/usr/bin/gpicview\nViewers;gThumb Image Viewer;/usr/bin/gthumb\nViewers;Pix Image Viewer;/usr/bin/pix\n\nViewers;Gwenview;/usr/bin/gwenview\nViewers;Mirage;/usr/bin/mirage\nViewers;nomacs;/usr/bin/nomacs\nViewers;Okular;/usr/bin/okular\nViewers;Phototonic;/usr/bin/phototonic\nViewers;QComicBook;/usr/bin/qcomicbook\nViewers;qPDFview;qpdfview\nViewers;Quick Image Viewer;/usr/bin/qiv\nViewers;sxiv;/usr/bin/sxiv\nViewers;Xditview;xditview\nViewers;Xpdf;/usr/bin/xpdf\n"
  },
  {
    "path": "src/firejail-ui/wizard.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n\n#if QT_VERSION >= 0x050000\n\t#include <QtWidgets>\n#else\n\t#include <QtGui>\n#endif\n\n#include <QCheckBox>\n#include <QGroupBox>\n#include <QVBoxLayout>\n#include <QMessageBox>\n#include <QRadioButton>\n#include <QLabel>\n#include <QLineEdit>\n#include <QListWidgetItem>\n#include <QProcess>\n#include <QPushButton>\n#include <QFileDialog>\n#include <QTextEdit>\n#include \"../../firetools_config_extras.h\"\n#include \"wizard.h\"\n#include \"home_widget.h\"\n#include \"help_widget.h\"\n#include \"appdb.h\"\n#include <unistd.h>\n\n//QString global_title(\"Firejail Configuration Wizard\");\nQString global_title(\"\");\nQTextEdit *global_profile;\n\nQString global_subtitle(\n\t\"<b>Firejail</b> is a SUID program that reduces the  risk  of  security \"\n\t\"breaches  by  restricting the running environment of untrusted \"\n\t\"applications using the latest Linux kernel sandboxing technologies. \"\n\t\"It allows a process and all its descendants to have their own private \"\n\t\"view of the globally shared kernel resources, such as the network stack, \"\n\t\"process table, and mount table.\"\n);\nHomeWidget *global_home_widget;\nQString global_ifname = \"\";\nbool global_dns_enabled = false;\nbool global_protocol_enabled = false;\n\nWizard::Wizard(QWidget *parent): QWizard(parent) {\n\tsetPage(Page_Application, new ApplicationPage);\n\tsetPage(Page_Config, new ConfigPage);\n\tsetPage(Page_Config2, new ConfigPage2);\n\tsetPage(Page_StartSandbox, new StartSandboxPage);\n\tsetStartId(Page_Application);\n\n\tsetOption(HaveHelpButton, true);\n\n\tconnect(this, SIGNAL(helpRequested()), this, SLOT(showHelp()));\n\n\tsetWindowTitle(tr(\"Firetools Config\"));\n\n\tsetWizardStyle(QWizard::MacStyle);\n\tsetPixmap(QWizard::BackgroundPixmap, QPixmap(\":/resources/background.png\"));\n\t//resize( QSize(600, 400).expandedTo(minimumSizeHint()) );\n\n}\n\nvoid Wizard::showHelp() {\n\tHelpWidget hw;\n\thw.exec();\n}\nusing namespace std;\nvoid Wizard::accept() {\n\tif (arg_debug)\n\t\tprintf(\"Wizard::accept\\n\");\n\tQStringList arguments;\n\n\t// build the profile in a termporary file\n\tchar profname[] = \"/tmp/firejail-ui-XXXXXX\";\n\tint fd = mkstemp(profname);\n\tif (fd == -1)\n\t\terrExit(\"mkstemp\");\n\tQString profarg = QString(\"--profile=\") + QString(profname);\n\targuments << profarg;\n\n\tassert(global_profile);\n \tQString profile = global_profile->toPlainText();\n\tdprintf(fd, \"%s\\n\", qPrintable(profile));\n\t::close(fd);\n\t\n\t// split command into arguments\n\tQString cmd = field(\"command\").toString();\n\tQStringList cmds = cmd.split( \" \" );\n\targuments += cmds;\n\n\t// start a new process,\n\tQProcess *process = new QProcess();\n\tprocess->startDetached(QString(\"firejail\"), arguments);\n\tsleep(1);\n\tprintf(\"Sandbox started, exiting firejail-ui...\\n\");\n\n\t// force a program exit\n\texit(0);\n}\n\nApplicationPage::ApplicationPage(QWidget *parent): QWizardPage(parent) {\n\tsetTitle(global_title);\n\tsetSubTitle(global_subtitle);\n\n\t// fonts\n\tQFont bold;\n\tbold.setBold(true);\n\tQFont oldFont;\n\toldFont.setBold(false);\n\n\tQGroupBox *app_box = new QGroupBox(tr(\"Step 1: Choose an application\"));\n\tapp_box->setFont(bold);\n//\tapp_box->setStyleSheet(\"QGroupBox { color : black; }\");\n\n\tQLabel *label1 = new QLabel(tr(\"Choose an application from the menus below\"));\n\tlabel1->setFont(oldFont);\n//\tlabel1->setStyleSheet(\"QLabel { color : black; }\");\n\n\tQGridLayout *app_box_layout = new QGridLayout;\n\tgroup_ = new QListWidget;\n\tgroup_->setFont(oldFont);\n//\tgroup_->setStyleSheet(\"QGridLayout { color : black; }\");\n\tcommand_ = new QLineEdit;\n\tcommand_->setFont(oldFont);\n//\tgroup_->setStyleSheet(\"QLineEdit { color : black; }\");\n\n\tbrowse_ = new QPushButton(\"browse filesystem\");\n\tQIcon icon(\":resources/gnome-fs-directory.png\");\n\tbrowse_->setIcon(icon);\n\tconnect(browse_, SIGNAL(clicked()), this, SLOT(browseClicked()));\n\n\tQLabel *label2 = new QLabel(\"or type in the program name:\");\n\tlabel2->setFont(oldFont);\n//\tlabel2->setStyleSheet(\"QLabel { color : black; }\");\n\tapp_ = new QListWidget;\n\tapp_->setFont(oldFont);\n//\tapp_->setStyleSheet(\"QListWidget { color : black; }\");\n\tapp_->setMinimumWidth(300);\n\tapp_box_layout->addWidget(label1, 0, 0, 1, 2);\n\tapp_box_layout->addWidget(group_, 1, 0);\n\tapp_box_layout->addWidget(app_, 1, 1);\n\tapp_box_layout->addWidget(browse_, 2, 0);\n\tapp_box_layout->addWidget(label2, 2, 1);\n\tapp_box_layout->addWidget(command_, 3, 0, 1, 2);\n\tapp_box->setLayout(app_box_layout);\n\n\tQGroupBox *profile_box = new QGroupBox(tr(\"Step 2: Choose a security profile\"));\n\tprofile_box->setFont(bold);\n//\tprofile_box->setStyleSheet(\"QGroupBox { color : black; }\");\n\tuse_default_ = new QRadioButton(\"Build a default security profile\");\n\tuse_default_->setFont(oldFont);\n//\tuse_default_->setStyleSheet(\"QRadioButton { color : black; }\");\n\tuse_default_->setChecked(true);\n\tuse_custom_ = new QRadioButton(\"Build a custom security profile\");\n\tuse_custom_->setFont(oldFont);\n//\tuse_custom_->setStyleSheet(\"QRadioButton { color : black; }\");\n\tQVBoxLayout *profile_box_layout = new QVBoxLayout;\n\tprofile_box_layout->addWidget(use_default_);\n\tprofile_box_layout->addWidget(use_custom_);\n\tprofile_box->setLayout(profile_box_layout);\n\n\tQGridLayout *layout = new QGridLayout;\n\tlayout->addWidget(app_box, 0, 0);\n\tlayout->addWidget(profile_box, 1, 0);\n\tsetLayout(layout);\n\n\t// load database\n\tappdb_ = appdb_load_file();\n\tif (arg_debug)\n\t\tappdb_print_list(appdb_);\n\tappdb_load_group(appdb_, group_);\n\n\t// connect widgets\n\tconnect(group_, SIGNAL(itemClicked(QListWidgetItem*)),\n\t            this, SLOT(groupClicked(QListWidgetItem*)));\n\tconnect(group_, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),\n\t            this, SLOT(groupChanged(QListWidgetItem*,QListWidgetItem*)));\n\tconnect(app_, SIGNAL(itemClicked(QListWidgetItem*)),\n\t            this, SLOT(appClicked(QListWidgetItem*)));\n\n\tregisterField(\"command*\", command_);\n\tregisterField(\"use_custom\", use_custom_);\n\n//\tsetFocusPolicy(Qt::StrongFocus);\n}\n\nvoid ApplicationPage::groupChanged(QListWidgetItem * current, QListWidgetItem * previous) {\n\t(void) previous;\n\tgroupClicked(current);\n}\n\n\n\nvoid ApplicationPage::keyPressEvent(QKeyEvent *event) {\n\tswitch (event->key()) {\n\t\tcase Qt::Key_Return:\n\t\t\tprintf(\"Return pressed\\n\");\n\t\t\tif (group_->hasFocus()) {\n\t\t\t\tprintf(\"group focus\\n'\");\n\t\t\t\tgroupClicked(group_->currentItem());\n\t\t\t}\n\t\t\telse if (app_->hasFocus()) {\n\t\t\t\tprintf(\"app focus\\n'\");\n\t\t\t\tappClicked(app_->currentItem());\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tQWizardPage::keyPressEvent(event);\n\t}\n}\n\nvoid ApplicationPage::browseClicked() {\n\tQString fname = QFileDialog::getOpenFileName(this, tr(\"Choose Application\"));\n\tif (fname.isNull())\n\t\treturn;\n\n\t// check the file is an executable\n\tconst char *cmd = fname.toUtf8().data();\n\tif (arg_debug)\n\t\tprintf(\"Command: %s\\n\", cmd);\n\tif (access(cmd, X_OK))\n\t\tQMessageBox::warning(this, \"Error\", \"The file is not an executable program\" );\n\telse\n\t\tcommand_->setText(fname);\n}\n\nvoid ApplicationPage::groupClicked(QListWidgetItem *item) {\n\tQString group = item->text();\n\tif (arg_debug)\n\t\tprintf(\"ApplicationPage::groupClicked %s\\n\", group.toLatin1().data());\n\n\n\tappdb_load_app(appdb_, app_, group);\n\tapp_->repaint();\n}\n\nvoid ApplicationPage::appClicked(QListWidgetItem *item) {\n\tQString app = item->text();\n\tif (arg_debug)\n\t\tprintf(\"ApplicationPage::appClicked %s\\n\", app.toLatin1().data());\n\n\n\tappdb_set_command(appdb_, command_, app);\n}\n\nint ApplicationPage::nextId() const {\n\tif (use_custom_->isChecked())\n\t\treturn Wizard::Page_Config;\n\telse\n\t\treturn Wizard::Page_StartSandbox;\n}\n\n\n\nConfigPage::ConfigPage(QWidget *parent): QWizardPage(parent) {\n\tsetTitle(global_title);\n//\tsetSubTitle(global_subtitle);\n\n\tQLabel *label1 = new QLabel(tr(\"<b>Step 3: Configure the sandbox</b>\"));\n//\tlabel1->setStyleSheet(\"QLabel { color : black; }\");\n\n\twhitelisted_home_ = new QCheckBox(\"Restrict /home directory\");\n//\twhitelisted_home_->setStyleSheet(\"QCheckBox { color : black; }\");\n\tregisterField(\"restricted_home\", whitelisted_home_);\n\tprivate_dev_ = new QCheckBox(\"Restrict /dev directory\");\n\tprivate_dev_->setChecked(true);\n//\tprivate_dev_->setStyleSheet(\"QCheckBox { color : black; }\");\n\tregisterField(\"private_dev\", private_dev_);\n\n\tprivate_tmp_ = new QCheckBox(\"Restrict /tmp directory\");\n\tprivate_tmp_->setChecked(true);\n//\tprivate_tmp_->setStyleSheet(\"QCheckBox { color : black; }\");\n\tregisterField(\"private_tmp\", private_tmp_);\n\n\tmnt_media_ = new QCheckBox(\"Restrict /mnt and /media\");\n\tmnt_media_->setChecked(true);\n//\tmnt_media_->setStyleSheet(\"QCheckBox { color : black; }\");\n\tregisterField(\"mnt_media\", mnt_media_);\n\n\tQGroupBox *fs_box = new QGroupBox(tr(\"File System\"));\n//\tfs_box->setStyleSheet(\"QGroupBox { color : black; }\");\n\tQVBoxLayout *fs_box_layout = new QVBoxLayout;\n\tfs_box_layout->addWidget(whitelisted_home_);\n\tfs_box_layout->addWidget(private_dev_);\n\tfs_box_layout->addWidget(private_tmp_);\n\tfs_box_layout->addWidget(mnt_media_);\n\tfs_box->setLayout(fs_box_layout);\n//\tfs_box->setFlat(false);\n//\tfs_box->setCheckable(true);\n\n\n\t// networking\n\tglobal_ifname = detect_network();\n\tsysnetwork_ = new QRadioButton(\"System network\");\n\tsysnetwork_->setChecked(true);\n//\tsysnetwork_->setStyleSheet(\"QRadioButton { color : black; }\");\n\tregisterField(\"sysnetwork\", sysnetwork_);\n\n\tnonetwork_ = new QRadioButton(\"Disable networking\");\n//\tnonetwork_->setStyleSheet(\"QRadioButton { color : black; }\");\n\tregisterField(\"nonetwork\", nonetwork_);\n\n\tif (global_ifname.isEmpty()) {\n\t\tnetnamespace_ = new QRadioButton(\"Namespace\");\n\t\tnetnamespace_->setEnabled(false);\n\t}\n\telse\n\t\tnetnamespace_ = new QRadioButton(QString(\"Namespace (\") + global_ifname + \")\");\n//\tnetnamespace_->setStyleSheet(\"QRadioButton { color : black; }\");\n\tregisterField(\"netnamespace\", netnamespace_);\n\tQGroupBox *net_box = new QGroupBox(tr(\"Networking\"));\n//\tnet_box->setStyleSheet(\"QGroupBox { color : black; }\");\n\tQVBoxLayout *net_box_layout = new QVBoxLayout;\n\tnet_box_layout->addWidget(sysnetwork_);\n\tnet_box_layout->addWidget(netnamespace_);\n\tnet_box_layout->addWidget(nonetwork_);\n\tnet_box->setLayout(net_box_layout);\n\n\thome_ = new HomeWidget;\n\tQGroupBox *home_box = new QGroupBox(tr(\"Home Directory\"));\n//\thome_box->setStyleSheet(\"QGroupBox { color : black; }\");\n\tQVBoxLayout *home_box_layout = new QVBoxLayout;\n\thome_box_layout->addWidget(home_);\n\thome_box->setLayout(home_box_layout);\n\thome_->setEnabled(false);\n\tconnect(whitelisted_home_, SIGNAL(toggled(bool)), this, SLOT(setHome(bool)));\n\tglobal_home_widget = home_;\n\n\n\t// DNS\n\tdns1_ = new QLineEdit;\n\tdns1_->setText(\"9.9.9.9\");\n\tdns1_->setMaximumWidth(150);\n\tdns1_->setFixedWidth(170);\n\tregisterField(\"dns1\", dns1_);\n\n\tdns2_ = new QLineEdit;\n\tdns2_->setText(\"1.1.1.1\");\n\tdns2_->setMaximumWidth(150);\n\tdns2_->setFixedWidth(170);\n\tregisterField(\"dns2\", dns2_);\n\n\tQGroupBox *dns_box = new QGroupBox(tr(\"DNS\"));\n\tdns_box->setCheckable(true);\n\tdns_box->setChecked(false);\n//\tdns_box->setStyleSheet(\"QGroupBox { color : black; }\");\n\tconnect(dns_box, SIGNAL(toggled(bool)), this, SLOT(setDns(bool)));\n\tQVBoxLayout *dns_box_layout = new QVBoxLayout;\n\tdns_box_layout->addWidget(dns1_);\n\tdns_box_layout->addWidget(dns2_);\n\tdns_box->setLayout(dns_box_layout);\n\n\t// protocol\n\tprotocol_unix_ = new QCheckBox(\"unix\");\n\tprotocol_unix_->setChecked(true);\n\tregisterField(\"protocol_unix\", protocol_unix_);\n\tprotocol_inet_ = new QCheckBox(\"inet\");\n\tprotocol_inet_->setChecked(true);\n\tregisterField(\"protocol_inet\", protocol_inet_);\n\tprotocol_inet6_ = new QCheckBox(\"inet6\");\n\tprotocol_inet6_->setChecked(true);\n\tregisterField(\"protocol_inet6\", protocol_inet6_);\n\tprotocol_netlink_ = new QCheckBox(\"netlink\");\n\tprotocol_netlink_->setChecked(false);\n\tregisterField(\"protocol_netlink\", protocol_netlink_);\n\tprotocol_packet_ = new QCheckBox(\"packet\");\n\tprotocol_packet_->setChecked(false);\n\tregisterField(\"protocol_packet\", protocol_packet_);\n\tprotocol_bluetooth_ = new QCheckBox(\"bluetooth\");\n\tprotocol_bluetooth_->setChecked(false);\n\tregisterField(\"protocol_bluetooth\", protocol_bluetooth_);\n\n\tQGroupBox *protocol_box = new QGroupBox(tr(\"Network Protocol\"));\n\tprotocol_box->setCheckable(true);\n\tprotocol_box->setChecked(false);\n//\tprotocol_box->setStyleSheet(\"QGroupBox { color : black; }\");\n\tconnect(protocol_box, SIGNAL(toggled(bool)), this, SLOT(setProtocol(bool)));\n\tQGridLayout *protocol_box_layout = new QGridLayout;\n\tprotocol_box_layout->addWidget(protocol_unix_, 0, 0);\n\tprotocol_box_layout->addWidget(protocol_inet_, 0, 1);\n\tprotocol_box_layout->addWidget(protocol_inet6_, 1, 0);\n\tprotocol_box_layout->addWidget(protocol_netlink_, 1, 1);\n\tprotocol_box_layout->addWidget(protocol_packet_, 2, 0);\n\tprotocol_box_layout->addWidget(protocol_bluetooth_, 2, 1);\n\tprotocol_box->setLayout(protocol_box_layout);\n\tif (kernel_major == 3 && kernel_minor < 5) {\n\t   \tif (arg_debug)\n\t   \t\tprintf(\"disabling protocol\\n\");\n\t\tprotocol_box->setEnabled(false);\n\t}\n\n\tQWidget *w = new QWidget;\n\tw->setMinimumHeight(8);\n\tQGridLayout *layout = new QGridLayout;\n\tlayout->addWidget(label1, 0, 0);\n\tlayout->addWidget(w, 1, 0);\n\tlayout->addWidget(fs_box, 2, 0);\n\tlayout->addWidget(home_box, 2, 1, 2, 1);\n\tlayout->addWidget(net_box, 3, 0);\n\tlayout->addWidget(dns_box, 4, 0);\n\tlayout->addWidget(protocol_box, 4, 1);\n\tsetLayout(layout);\n}\n\nbool ConfigPage::validatePage() {\n\tif (global_dns_enabled) {\n\t\tuint32_t addr;\n\n\t\tQString ip = dns1_->text();\n\t\tif (!ip.isEmpty()) {\n\t\t\tconst char *str = ip.toUtf8().data();\n\t\t\tif (atoip(str, &addr)) {\n\t\t\t\tQMessageBox::warning(this, \"Error\", QString(\"Invalid IP address \") + ip);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tip = dns2_->text();\n\t\tif (!ip.isEmpty()) {\n\t\t\tconst char *str = ip.toUtf8().data();\n\t\t\tif (atoip(str, &addr)) {\n\t\t\t\tQMessageBox::warning(this, \"Error\", QString(\"Invalid IP address \") + ip);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\telse\n\t\treturn true;\n}\n\nvoid ConfigPage::setDns(bool on) {\n\tglobal_dns_enabled = on;\n}\n\nvoid ConfigPage::setProtocol(bool on) {\n\tglobal_protocol_enabled = on;\n}\n\nvoid ConfigPage::setHome(bool active) {\n\thome_->setEnabled(active);\n}\n\nint ConfigPage::nextId() const {\n\treturn Wizard::Page_Config2;\n}\n\n\nConfigPage2::ConfigPage2(QWidget *parent): QWizardPage(parent) {\n\tsetTitle(global_title);\n//\tsetSubTitle(global_subtitle);\n\n\tQLabel *label1 = new QLabel(tr(\"<b>Step 3: Configure the sandbox... continued...</b>\"));\n//\tlabel1->setStyleSheet(\"QLabel { color : black; }\");\n\tnosound_ = new QCheckBox(\"Disable sound\");\n//\tnosound_->setStyleSheet(\"QCheckBox { color : black; }\");\n\tregisterField(\"nosound\", nosound_);\n\n\tnodvd_ = new QCheckBox(\"Disable CD-ROM/DVD devices\");\n//\tnodvd_->setStyleSheet(\"QCheckBox { color : black; }\");\n\tregisterField(\"nodvd\", nodvd_);\n\n\tnovideo_ = new QCheckBox(\"Disable video camera devices\");\n//\tnovideo_->setStyleSheet(\"QCheckBox { color : black; }\");\n\tregisterField(\"novideo\", novideo_);\n\n\tnotv_ = new QCheckBox(\"Disable TV/DVB devices\");\n//\tnotv_->setStyleSheet(\"QCheckBox { color : black; }\");\n\tregisterField(\"notv\", notv_);\n\n\tno3d_ = new QCheckBox(\"Disable 3D acceleration\");\n//\tno3d_->setStyleSheet(\"QCheckBox { color : black; }\");\n\tregisterField(\"no3d\", no3d_);\n\n\tnox11_ = new QCheckBox(\"Disable X11 support\");\n\tregisterField(\"nox11\", nox11_);\n\n\tQGroupBox *multimed_box = new QGroupBox(tr(\"Multimedia\"));\n//\tmultimed_box->setStyleSheet(\"QGroupBox { color : black; }\");\n\tQVBoxLayout *multimed_box_layout = new QVBoxLayout;\n\tmultimed_box_layout->addWidget(nosound_);\n\tmultimed_box_layout->addWidget(novideo_);\n\tmultimed_box_layout->addWidget(nodvd_);\n\tmultimed_box_layout->addWidget(notv_);\n\tmultimed_box_layout->addWidget(no3d_);\n\tmultimed_box_layout->addWidget(nox11_);\n\tmultimed_box->setLayout(multimed_box_layout);\n//\tmultimed_box->setFlat(false);\n//\tmultimed_box->setCheckable(true);\n\n\tseccomp_ = new QCheckBox(\"Enable seccomp-bpf\");\n\tif (kernel_major == 3 && kernel_minor < 5) {\n\t   \tif (arg_debug)\n\t   \t\tprintf(\"disabling seccomp-bpf\\n\");\n\t\tseccomp_->setEnabled(false);\n\t}\n\telse\n\t\tseccomp_->setChecked(true);\n\tregisterField(\"seccomp\", seccomp_);\n\n\tcaps_ = new QCheckBox(\"Disable all Linux capabilities\");\n\tcaps_->setChecked(true);\n//\tcaps_->setStyleSheet(\"QCheckBox { color : black; }\");\n\tregisterField(\"caps\", caps_);\n\n\tnoroot_ = new QCheckBox(\"Restricted  user namespace (noroot)\");\n\tif (kernel_major == 3 && kernel_minor < 8) {\n\t   \tif (arg_debug)\n\t   \t\tprintf(\"disabling noroot\\n\");\n\t\tnoroot_->setEnabled(false);\n\t}\n\telse\n\t\tnoroot_->setChecked(true);\n//\tnoroot_->setStyleSheet(\"QCheckBox { color : black; }\");\n\tregisterField(\"noroot\", noroot_);\n\n\tapparmor_ = new QCheckBox(\"Enable AppArmor\");\n\tapparmor_->setChecked(true);\n\tregisterField(\"apparmor\", apparmor_);\n\n\tQGroupBox *kernel_box = new QGroupBox(tr(\"Kernel\"));\n//\tkernel_box->setStyleSheet(\"QGroupBox { color : black; }\");\n\tQVBoxLayout *kernel_box_layout = new QVBoxLayout;\n\tkernel_box_layout->addWidget(seccomp_);\n\tkernel_box_layout->addWidget(caps_);\n\tkernel_box_layout->addWidget(noroot_);\n\tkernel_box_layout->addWidget(apparmor_);\n\tkernel_box->setLayout(kernel_box_layout);\n\n\tQWidget *w = new QWidget;\n\tw->setMinimumHeight(8);\n\tQGridLayout *layout = new QGridLayout;\n\tlayout->addWidget(label1, 0, 0);\n\tlayout->addWidget(w, 1, 0);\n\tlayout->addWidget(multimed_box, 2, 0);\n\tlayout->addWidget(kernel_box, 3, 0);\n\tsetLayout(layout);\n}\n\nint ConfigPage2::nextId() const {\n\treturn Wizard::Page_StartSandbox;\n}\n\n\nvoid ConfigPage2::initializePage() {\n\tif (field(\"sysnetwork\").toBool())\n\t\tnox11_->setEnabled(false);\n\telse\n\t\tnox11_->setEnabled(true);\n}\n\n\nStartSandboxPage::StartSandboxPage(QWidget *parent): QWizardPage(parent) {\n\tsetTitle(global_title);\n//\tsetSubTitle(global_subtitle);\n\n\t// fonts\n\tQFont bold;\n\tbold.setBold(true);\n\tQFont oldFont;\n\toldFont.setBold(false);\n\n\tglobal_profile = new QTextEdit();\n\n\tQLabel *label1 = new QLabel(tr(\"This is the configuration we created for your sandbox. \"\n\t\t\"You can modify it in the text box below.<br/><br/>\"\n\t\t\"For more information, visit us at <b>http://firejail.wordpress.com</b>.\"));\n\tQLabel *label2 = new QLabel(tr(\"Press <b>Done</b> to start the sandbox.<br/><br/>\"));\n\tQWidget *empty1 = new QWidget;\n\tempty1->setMinimumHeight(12);\n\tQWidget *empty2 = new QWidget;\n\tempty2->setMinimumHeight(25);\n\tQGridLayout *layout = new QGridLayout;\n\tlayout->addWidget(empty1, 0, 0);\n\tlayout->addWidget(label1, 1, 0);\n\tlayout->addWidget(global_profile, 2, 0);\n\tlayout->addWidget(label2, 3, 0);\n\tsetLayout(layout);\n\n}\n\nvoid StartSandboxPage::initializePage() {\n\tQString txt = \"# Custom profile for \" + field(\"command\").toString() + \"\\n\";\n\n\t// include\n\ttxt += \"\\n# file system\\n\";\n\ttxt += \"include /etc/firejail/disable-common.inc\\n\";\n\n\t// home directory\n\tif (field(\"restricted_home\").toBool()) {\n\t\tQString whitelist = global_home_widget->getContent();\n\t\tif (whitelist.isEmpty())\n\t\t\twhitelist = QString(\"private\\n\");\n\t\telse\n\t\t\twhitelist += QString(\"include /etc/firejail/whitelist-common.inc\\n\");\n\n\t\ttxt += whitelist;\n\t}\n\n\t// filesystem\n\tif (field(\"private_tmp\").toBool())\n\t\ttxt += \"private-tmp\\n\";\n\tif (field(\"private_dev\").toBool())\n\t\ttxt += \"private-dev\\n\";\n\tif (field(\"mnt_media\").toBool()) {\n\t\ttxt += \"blacklist /mnt\\n\";\n\t\ttxt += \"blacklist /media\\n\";\n\t}\n\n\t// network\n\ttxt += \"\\n# network\\n\";\n\tif (field(\"sysnetwork\").toBool())\n\t\t;\n\telse if (field(\"nonetwork\").toBool())\n\t\ttxt += \"net none\\n\";\n\telse if (field(\"netnamespace\").toBool())\n\t\ttxt += \"net \" + global_ifname + \"\\n\";\n\n\t// dns\n\tif (global_dns_enabled) {\n\t\tQString dns1 = field(\"dns1\").toString();\n\t\tif (!dns1.isEmpty())\n\t\t\ttxt += \"dns \" + dns1 + \"\\n\";\n\n\t\tQString dns2 = field(\"dns2\").toString();\n\t\tif (!dns2.isEmpty())\n\t\t\ttxt += \"dns \" + dns2 + \"\\n\";\n\t}\n\n\t// network protocol\n\tif (global_protocol_enabled) {\n\t\tif (field(\"protocol_unix\").toBool() ||\n\t\t    field(\"protocol_inet\").toBool() ||\n\t\t    field(\"protocol_inet6\").toBool() ||\n\t\t    field(\"protocol_netlink\").toBool() ||\n\t\t    field(\"protocol_bluetooth\").toBool() ||\n\t\t    field(\"protocol_packet\").toBool()) {\n\t\t\tQString protocol = QString(\"protocol \");\n\t\t\tif (field(\"protocol_unix\").toBool())\n\t\t\t\tprotocol += QString(\"unix,\");\n\t\t\tif (field(\"protocol_inet\").toBool())\n\t\t\t\tprotocol += QString(\"inet,\");\n\t\t\tif (field(\"protocol_inet6\").toBool())\n\t\t\t\tprotocol += QString(\"inet6,\");\n\t\t\tif (field(\"protocol_netlink\").toBool())\n\t\t\t\tprotocol += QString(\"netlink,\");\n\t\t\tif (field(\"protocol_packet\").toBool())\n\t\t\t\tprotocol += QString(\"packet\");\n\t\t\tif (field(\"protocol_bluetooth\").toBool())\n\t\t\t\tprotocol += QString(\"bluetooth\");\n\t\t\ttxt += protocol + \"\\n\";\n\t\t}\n\t}\n\n\t// multimedia\n\ttxt += \"\\n# multimedia\\n\";\n\tif (field(\"nosound\").toBool())\n\t\ttxt += \"nosound\\n\";\n\tif (field(\"no3d\").toBool())\n\t\ttxt += \"no3d\\n\";\n\tif (field(\"nox11\").toBool())\n\t\ttxt += \"x11 none\\n\";\n\tif (field(\"nodvd\").toBool())\n\t\ttxt += \"nodvd\\n\";\n\tif (field(\"novideo\").toBool())\n\t\ttxt += \"novideo\\n\";\n\tif (field(\"notv\").toBool())\n\t\ttxt += \"notv\\n\";\n\n\n\t// kernel\n\ttxt += \"\\n# kernel\\n\";\n\tif (field(\"seccomp\").toBool()) {\n\t\ttxt += \"seccomp\\n\";\n\t\ttxt += \"nonewprivs\\n\";\n\t}\n\tif (field(\"caps\").toBool())\n\t\ttxt += \"caps.drop all\\n\";\n\tif (field(\"noroot\").toBool())\n\t\ttxt += \"noroot\\n\";\n\tif (field(\"apparmor\").toBool())\n\t\ttxt += \"apparmor\\n\";\n\n\tglobal_profile->setText(txt);\n}\n\nint StartSandboxPage::nextId() const {\n\treturn -1;\n}\n"
  },
  {
    "path": "src/firejail-ui/wizard.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n */\n#ifndef LICENSEWIZARD_H\n#define LICENSEWIZARD_H\n\n#include \"firejail_ui.h\"\n#include <QWizard>\n\nclass QCheckBox;\nclass QLabel;\nclass QLineEdit;\nclass QRadioButton;\nclass QPushButton;\nclass HomeWidget;\nclass QListWidget;\nclass QListWidgetItem;\nclass QTextEdit;\nstruct AppEntry;\n\nclass Wizard : public QWizard {\n\tQ_OBJECT\n\npublic:\n\tenum { Page_Application, Page_Config, Page_Config2, Page_StartSandbox };\n\n\tWizard(QWidget *parent = 0);\n\tvoid accept();\n\nprivate slots:\n\tvoid showHelp();\n};\n\nclass ApplicationPage : public QWizardPage {\n\tQ_OBJECT\n\npublic:\n\tApplicationPage(QWidget *parent = 0);\n\n\tint nextId() const;\n\nprotected:\n\tvoid keyPressEvent(QKeyEvent *event);\n\nprivate slots:\n\tvoid groupChanged(QListWidgetItem * current, QListWidgetItem * previous);\n\tvoid groupClicked(QListWidgetItem*);\n\tvoid appClicked(QListWidgetItem*);\n\tvoid browseClicked();\n\nprivate:\n\tAppEntry *appdb_;\n\tQListWidget *app_;\n\tQListWidget *group_;\n\tQLineEdit *command_;\n\tQRadioButton *use_default_;\n\tQRadioButton *use_custom_;\n\tQPushButton *browse_;\n};\n\nclass ConfigPage : public QWizardPage {\n\tQ_OBJECT\n\npublic:\n\tConfigPage(QWidget *parent = 0);\n\tbool validatePage();\n\n\tint nextId() const;\n\n\npublic slots:\n\tvoid setHome(bool);\n\tvoid setDns(bool);\n\tvoid setProtocol(bool);\n\nprivate:\n\t// filesystem\n\tQCheckBox *whitelisted_home_;\n\tQCheckBox *private_dev_;\n\tQCheckBox *private_tmp_;\n\tQCheckBox *mnt_media_;\n\tHomeWidget *home_;\n\n\t// networking\n\tQRadioButton *sysnetwork_;\n\tQRadioButton *nonetwork_;\n\tQRadioButton *netnamespace_;\n\n\t// DNS\n\tQLineEdit *dns1_;\n\tQLineEdit *dns2_;\n\tQCheckBox *dns1check_;\n\tQCheckBox *dns2check_;\n\n\t// protocol\n\tQCheckBox *protocol_unix_;\n\tQCheckBox *protocol_inet_;\n\tQCheckBox *protocol_inet6_;\n\tQCheckBox *protocol_netlink_;\n\tQCheckBox *protocol_packet_;\n\tQCheckBox *protocol_bluetooth_;\n};\n\nclass ConfigPage2 : public QWizardPage {\n\tQ_OBJECT\n\npublic:\n\tConfigPage2(QWidget *parent = 0);\n\n\tint nextId() const;\n\tvoid initializePage();\n\npublic slots:\n\nprivate:\n\t// multimedia\n\tQCheckBox *nosound_;\n\tQCheckBox *no3d_;\n\tQCheckBox *nodvd_;\n\tQCheckBox *novideo_;\n\tQCheckBox *notv_;\n\tQCheckBox *nox11_;\n\n\t// kernel\n\tQCheckBox *seccomp_;\n\tQCheckBox *caps_;\n\tQCheckBox *noroot_;\n\tQCheckBox *apparmor_;\n};\n\nclass StartSandboxPage : public QWizardPage {\n\tQ_OBJECT\n\npublic:\n\tStartSandboxPage(QWidget *parent = 0);\n\tvoid initializePage();\n\tint nextId() const;\n\n\nprivate slots:\n\nprivate:\n};\n#endif\n"
  },
  {
    "path": "src/firetools/applications.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include <stdio.h>\n#include <string.h>\n#include <dirent.h>\n#include <sys/types.h>\n#include <pwd.h>\n#include \"firetools.h\"\n#include \"applications.h\"\n#include \"../common/utils.h\"\n#include \"../../firetools_config_extras.h\"\n#include <QDirIterator>\n#include <QPainter>\n\nQList<Application> applist;\n\n/*\nFrom: http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html\n\nIcons and themes are looked for in a set of directories. By default, apps should look\nin $HOME/.icons (for backwards compatibility), in $XDG_DATA_DIRS/icons and in /\nusr/share/pixmaps (in that order). Applications may further add their own icon\ndirectories to this list, and users may extend or change the list (in application/desktop\nspecific ways).In each of these directories themes are stored as subdirectories.\nA theme can be spread across several base directories by having subdirectories of\nthe same name. This way users can extend and override system themes.\n\nIn order to have a place for third party applications to install their icons there\nshould always exist a theme called \"hicolor\" [1]. The data for the hicolor theme is\navailable for download at: http://www.freedesktop.org/software/icon-theme/. I\nmplementations are required to look in the \"hicolor\" theme if an icon was not found\nin the current theme.\n*/\n\n// compare strings\nstatic inline bool compare_ignore_case(QString q1, QString q2) {\n\tq1 = q1.toLower();\n\tq2 = q2.toLower();\n\treturn q1 == q2;\n}\n\nstatic QString walk(QString path, QString name) {\n\tQDirIterator it(path, QDirIterator::Subdirectories);\n\twhile (it.hasNext()) {\n\t\tit.next();\n\t\tQFileInfo fi = it.fileInfo();\n\t\tif (fi.isFile() && compare_ignore_case(fi.baseName(), name)) {\n\t\t\tif (arg_debug)\n\t\t\t\tprintf(\"\\t- %s\\n\", fi.canonicalFilePath().toUtf8().data());\n\t\t\treturn fi.canonicalFilePath();\n\t\t}\n\t}\n\treturn QString(\"\");\n}\n\nstatic QIcon resize48x48(QIcon icon) {\n\tQSize sz = icon.actualSize(QSize(64, 64));\n\tif (arg_debug)\n\t\tprintf(\"\\t- input pixmap: w %d, h %d\\n\", sz.width(), sz.height());\n\n\tQPixmap pix = icon.pixmap(sz.height(), sz.width());\n\tQPixmap pixin;\n\tint delta = 0;\n\n\tif (sz.height() ==  sz.width() && sz.height() <= 40) {\n\t\tpixin = pix.scaled(40, 40);\n\t\tdelta = 12;\n\t}\n\telse {\n\t\tpixin = pix.scaled(48, 48);\n\t\tdelta = 8;\n\t}\n\n\n\tQPixmap pixout(64, 64);\n\tpixout.fill(QColor(0, 0, 0, 0));\n\tQPainter *paint = new QPainter(&pixout);\n\tpaint->drawPixmap(delta, delta, pixin);\n\tif (arg_debug)\n\t\tprintf(\"\\t- output pixmap: w %d, h %d\\n\", pixout.width(), pixout.height());\n\tpaint->end();\n\treturn QIcon(pixout);\n}\n\nQIcon loadIcon(QString name) {\n\tif (arg_debug)\n\t\tprintf(\"searching icon %s\\n\", name.toLocal8Bit().data());\n\n\tif (name == \":resources/fstats\" || name == \":resources/firejail-ui\") {\n\t\tif (arg_debug)\n\t\t\tprintf(\"\\t- resource\\n\");\n\t\treturn QIcon(name); // not resized, using the real 64x64 size\n\t}\n\n\tif (name.startsWith(\":resources\")) {\n\t\tif (arg_debug)\n\t\t\tprintf(\"\\t- resource\\n\");\n\t\treturn resize48x48(QIcon(name));\n\t}\n\n\tif (name.startsWith('/')) {\n\t\tif (arg_debug)\n\t\t\tprintf(\"\\t- full path\\n\");\n\t\treturn resize48x48(QIcon(name));\n\t}\n\n\n\n\t// Look for the file in Firejail config directory under /home/user\n\tQString conf = QDir::homePath() + \"/.config/firetools/\" + name + \".png\";\n\tQFileInfo checkFile1(conf);\n\tif (checkFile1.exists() && checkFile1.isFile()) {\n\t\tif (arg_debug)\n\t\t\tprintf(\"\\t- local config dir, png file\\n\");\n\t\treturn QIcon(conf);\n\t}\n\tconf = QDir::homePath() + \"/.config/firetools/\" + name + \".jpg\";\n\tQFileInfo checkFile2(conf);\n\tif (checkFile2.exists() && checkFile2.isFile()) {\n\t\tif (arg_debug)\n\t\t\tprintf(\"\\t- local config dir, jpg file\\n\");\n\t\treturn QIcon(conf);\n\t}\n\n\tif (!svg_not_found) {\n\t\tconf = QDir::homePath() + \"/.config/firetools/\" + name + \".svg\";\n\t\tQFileInfo checkFile3(conf);\n\t\tif (checkFile3.exists() && checkFile3.isFile()) {\n\t\t\tif (arg_debug)\n\t\t\t\tprintf(\"\\t- local config dir, svg file\\n\");\n\t\t\treturn QIcon(conf);\n\t\t}\n\t}\n\n\tif (QIcon::hasThemeIcon(name)) {\n\t\tif (arg_debug)\n\t\t\tprintf(\"\\t- fromTheme\\n\");\n\t\treturn resize48x48(QIcon::fromTheme(name));\n\t}\n\n\t{\n\t\tQString qstr = walk(\"/usr/share/icons\", name);\n\t\tif (!qstr.isEmpty()) {\n\t\t\treturn resize48x48(QIcon(qstr));\n\t\t}\n\t}\n\n\t{\n\t\tQDirIterator it(\"/usr/share/pixmaps\", QDirIterator::Subdirectories);\n\t\twhile (it.hasNext()) {\n\t\t\tit.next();\n\t\t\tQFileInfo fi = it.fileInfo();\n\t\t\tif (fi.isFile() && compare_ignore_case(fi.baseName(), name)) {\n\t\t\t\tif (arg_debug)\n\t\t\t\t\tprintf(\"\\t- /usr/share/pixmaps\\n\");\n\t\t\t\tQIcon icon = QIcon(fi.canonicalFilePath());\n\t\t\t\treturn resize48x48(icon);\n\t\t\t}\n\t\t}\n\t}\n\n\n\treturn QIcon();\n}\n\n\n\nbool applist_check(QString name) {\n\tQList<Application>::iterator it;\n\tfor (it = applist.begin(); it != applist.end(); ++it) {\n\t\tif (it->name_ == name)\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n\nvoid applist_print() {\n\tQList<Application>::iterator it;\n\tfor (it = applist.begin(); it != applist.end(); ++it)\n\t\tprintf(\"\\t%s\\n\", it->name_.toLocal8Bit().constData());\n}\n\n\nint applications_init(const char *fname) {\n\tassert(fname);\n\n\t// load default apps\n\tif (arg_debug)\n\t\tprintf(\"Loading applications from %s\\n\", fname);\n\n\tchar *newfname = NULL;\n\tif (strncmp(fname, \"~/\", 2) == 0) {\n\t\t struct passwd *pw = getpwuid(getuid());\n\t\t if (!pw)\n\t\t \terrExit(\"getpwuid\");\n\t\t if (asprintf(&newfname, \"%s/%s\", pw->pw_dir, fname + 2) == -1)\n\t\t \terrExit(\"asprintf\");\n\t}\n\n\tFILE *fp = fopen((newfname)? newfname: fname, \"r\");\n\tif (!fp)\n\t\treturn 0;\n\n\tchar buf[1024];\n\tint line = 0;\n\tint cnt = 0;\n\twhile (fgets(buf, sizeof(buf), fp)) {\n\t\tline++;\n\n\t\t// comment\n\t\tif (*buf == '#')\n\t\t\tcontinue;\n\t\tchar *ptr = strchr(buf, '\\n');\n\t\tif (ptr)\n\t\t\t*ptr = '\\0';\n\t\tchar *name = buf;\n\t\twhile (*name == ' ' || *name == '\\t')\n\t\t\tname++;\n\t\tif (*name == '\\0')\n\t\t\tcontinue;\n\t\tptr = strchr(name, ';');\n\t\tif (!ptr) {\n\t\t\tfprintf(stderr, \"Error: invalid line %d in %s\\n\", line, PACKAGE_LIBDIR \"/uiapps\");\n\t\t\texit(1);\n\t\t}\n\t\t*ptr++ = '\\0';\n\t\tchar *description = ptr;\n\t\tptr = strchr(description, ';');\n\t\tif (!ptr) {\n\t\t\tfprintf(stderr, \"Error: invalid line %d in %s\\n\", line, PACKAGE_LIBDIR \"/uiapps\");\n\t\t\texit(1);\n\t\t}\n\t\t*ptr++ = '\\0';\n\t\tchar *icon = ptr;\n\t\tchar *command = NULL;\n\t\tptr = strchr(icon, ';');\n\t\tif (ptr) {\n\t\t\t*ptr++ = '\\0';\n\t\t\tcommand = ptr;\n\t\t}\n\t\tif (arg_debug) {\n\t\t\tprintf(\"checking #%s#%s#%s#%s\\n\",\n\t\t\t\tname, description, icon, (command)? command: \"\");\n\t\t}\n\n\t\t// do we have the program?\n\t\tif (which(name) == false)\n\t\t\tcontinue;\n\n\t\tif (command && strncmp(command, \"PACKAGE_LIBDIR\", 14) == 0) {\n\t\t\tchar *newcmd;\n\t\t\tif (asprintf(&newcmd, PACKAGE_LIBDIR \"%s\", command + 14) == -1)\n\t\t\t\terrExit(\"asprintf\");\n\t\t\tcommand = newcmd;\n\t\t}\n\n\t\tQIcon qi = loadIcon(icon);\n\t\tif (qi.isNull())\n\t\t\tcontinue;\n\t\tapplist.append(Application(name, description, command, qi));\n\t\tcnt++;\n\t}\n\tfclose(fp);\n\tif (arg_debug)\n\t\tprintf(\"%d applications added\\n\", cnt);\n\n\treturn cnt;\n}\n"
  },
  {
    "path": "src/firetools/applications.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef APPLICATIONS_H\n#define APPLICATIONS_H\n#include <QList>\n#include <QString>\n#include <QIcon>\n\n#define TOP 10\n#define MARGIN 2\n#define AFRAMES 6\t// animation frames\n#define ADELAY 20\t\t// animation delay\n#define ROWS 6\n\n// applications.cpp\nstruct Application {\n\tQString name_;\n\tQString description_;\n\tQString exec_;\n\tQIcon app_icon_;\n\t\n\tApplication(const char *name, const char *description, const char *exec, QIcon app_icon):\n\t\tname_(name), description_(description), exec_(exec), app_icon_(app_icon) {\n\t\t\n\t\tif (exec == NULL || strlen(exec) == 0)\n\t\t\texec_ = QString(\"firejail \") + name;\n\t}\t\n};\n\nextern QList<Application> applist;\nint applications_init(const char *fname);\nbool applist_check(QString name);\nvoid applications_print();\nvoid applist_print();\n\n#endif\n"
  },
  {
    "path": "src/firetools/firetools.desktop",
    "content": "[Desktop Entry]\nName=Firetools\nComment=Firejail Tools and Stats\nExec=firetools\nIcon=firetools\nTerminal=false\nType=Application\nCategories=Qt;System;Security;\nKeywords=jail;security;seccomp;\n"
  },
  {
    "path": "src/firetools/firetools.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef FIRETOOLS_H\n#define FIRETOOLS_H\n#include \"../common/common.h\"\n\ntypedef enum {\n\tGRAPH_4MIN = 0,\n\tGRAPH_1H,\n\tGRAPH_12H\n} GraphType;\n\t\n\nextern int arg_debug;\nextern int svg_not_found;\n\n#endif\n"
  },
  {
    "path": "src/firetools/firetools.pro",
    "content": "QMAKE_CXXFLAGS += $$(CXXFLAGS) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security\nQMAKE_CFLAGS += $$(CFLAGS) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security\nQMAKE_LFLAGS += $$(LDFLAGS) -Wl,-z,relro -Wl,-z,now\nQT += widgets\n HEADERS       = mainwindow.h ../common/utils.h ../common/common.h applications.h \\\n\t\t  firetools.h\n SOURCES       = mainwindow.cpp \\\n                 main.cpp \\\n                  ../common/utils.cpp \\\n                  ../common/pid.cpp \\\n                  applications.cpp\nRESOURCES = firetools.qrc\nTARGET=../../build/firetools\n"
  },
  {
    "path": "src/firetools/firetools.qrc",
    "content": "<!DOCTYPE RCC><RCC version=\"1.0\">\n<qresource prefix=\"/\">\n   <file>resources/firetools.png</file>\n   <file>resources/firetools-minimal.png</file>\n   <file>resources/fstats.png</file>\n   <file>resources/firejail-ui.png</file>\n   <file>resources/icedove.png</file>\n   <file>resources/firefox.png</file>\n   <file>resources/libreoffice-writer.png</file>\n   <file>resources/gnome-terminal.png</file>\n   <file>resources/signal-desktop.png</file>\n</qresource>\n</RCC>\n"
  },
  {
    "path": "src/firetools/main.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include <QApplication>\n#include <QMenu>\n#include <QSystemTrayIcon>\n#include <QLibraryInfo>\n\n#include \"firetools.h\"\n#include \"mainwindow.h\"\n#include \"../common/utils.h\"\n#include \"../../firetools_config.h\"\n\nint arg_debug = 0;\nint svg_not_found = 0;\n\n// desktop file content for autostart\nstatic const char *deskfile_minimize = \n\"[Desktop Entry]\\n\"\n\"Name=Firetools\\n\"\n\"Comment=Firejail tools & stats\\n\"\n\"Exec=firetools --minimize\\n\"\n\"Icon=firetools\\n\"\n\"Terminal=false\\n\"\n\"Type=Application\\n\"\n\"Categories=Qt;System;Security;\\n\";\n\n\n// Usage instructions for the command line output\nstatic void usage() {\n\tprintf(\"firetools - Firejail tools and stats utility\\n\\n\");\n\tprintf(\"Usage: firetools [options]\\n\\n\");\n\tprintf(\"Options:\\n\");\n\tprintf(\"\\t--autostart - configure firetools to run automatically in system tray\\n\");\n\tprintf(\"\\t\\twhen X11 session is started\\n\\n\");\n\tprintf(\"\\t--debug - debug mode\\n\\n\");\n\tprintf(\"\\t--help - this help screen\\n\\n\");\n\tprintf(\"\\t--minimize - start the program minimized in system tray\\n\\n\");\n\tprintf(\"\\t--version - print software version and exit\\n\\n\");\n}\n\nint main(int argc, char *argv[]) {\n\tint arg_minimize = 0;\n\n\t// Parse arguments\n\tfor (int i = 1; i < argc; i++) {\n\t\tif (strcmp(argv[i], \"--debug\") == 0)\n\t\t\targ_debug = 1;\n\t\telse if (strcmp(argv[i], \"--help\") == 0 || strcmp(argv[i], \"-?\") == 0) {\n\t\t\tusage();\n\t\t\treturn 0;\n\t\t}\n\t\telse if (strcmp(argv[i], \"--version\") == 0) {\n\t\t\tprintf(\"Firetools version \" PACKAGE_VERSION \"\\n\");\n\t\t\treturn 0;\n\t\t}\n\t\telse if (strcmp(argv[i], \"--autostart\") == 0) {\n\t\t\t// Find home directory\n\t\t\tchar *home = get_home_directory();\n\t\t\tif (!home) {\n\t\t\t\tfprintf(stderr, \"Error: cannot find user home directory\");\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\t\n\t\t\t// Create a .config/autostart directory if it doesn't exist\n\t\t\tchar *autodir;\n\t\t\tif (asprintf(&autodir, \"%s/.config/autostart\", home) == -1)\n\t\t\t\terrExit(\"asprintf\");\n\t\t\tint rv = mkdir(autodir, 0755);\n\t\t\t(void) rv;\n\t\t\t\n\t\t\t// Create desktop file\n\t\t\tchar *autofile;\n\t\t\tif (asprintf(&autofile, \"%s/.config/autostart/firetools.desktop\", home) == -1)\n\t\t\t\terrExit(\"asprintf\");\n\t\t\tFILE *fp = fopen(autofile, \"w\");\n\t\t\tif (!fp) {\n\t\t\t\tfprintf(stderr, \"Error: cannot open %s\\n\", autofile);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tfprintf(fp, \"%s\\n\", deskfile_minimize);\n\t\t\tfclose(fp);\n\t\t\tprintf(\"firetools autostart configured\\n\");\n\t\t\treturn 0;\n\t\t}\n\t\telse if (strcmp(argv[i], \"--minimize\") == 0)\n\t\t\targ_minimize = 1;\n\t\telse {\n\t\t\tfprintf(stderr, \"Error: invalid option\\n\");\n\t\t\tusage();\n\t\t\treturn 1;\n\t\t}\t\t\n\t}\n\n#if QT_VERSION >= 0x050000\n\tstruct stat s;\t\n\t// Test run time dependencies - print warning and continue program\n\tQString ppath = QLibraryInfo::location(QLibraryInfo::PluginsPath);\n\tppath += \"/imageformats/libqsvg.so\";\n\tif (stat(ppath.toUtf8().constData(), &s) == -1) {\n\t\tfprintf(stderr, \"Warning: QT5 SVG support not installed, please install libqt5svg5 package\\n\");\n\t\tsvg_not_found = 1;\n\t}\n#endif\n\t\n\t// Test run time dependencies - exit\n\tif (!which(\"firejail\")) {\n\t\tfprintf(stderr, \"Error: firejail package not found, please install it!\\n\");\n\t\texit(1);\n\t}\n\t\n\t// Create firetools directory if it doesn't exist\n\tcreate_config_directory();\n\t\n\t// Initialize resources\n\tQ_INIT_RESOURCE(firetools);\n\n\tQApplication app(argc, argv);\n\tMainWindow fc;\n\tif (!arg_minimize)\n\t\tfc.show();\n\n\t// Configure system tray\n\tQSystemTrayIcon icon(QIcon(\":resources/firetools-minimal.png\"));\n\ticon.show();\t\n\ticon.setToolTip(\"Firetools (click to open)\");\n\tQMenu *trayIconMenu = new QMenu(&fc);\n\ttrayIconMenu->addAction(fc.minimizeAction);\n\ttrayIconMenu->addAction(fc.restoreAction);\n\ttrayIconMenu->addSeparator();\n\ttrayIconMenu->addAction(fc.quitAction);\n\ticon.setContextMenu(trayIconMenu);\n\ticon.connect(&icon, SIGNAL(activated(QSystemTrayIcon: :ActivationReason)), &fc, SLOT(trayActivated(QSystemTrayIcon: :ActivationReason)));\n\t\n\t// Direct all errror to /dev/null to work around this qt bug:\n\t//      https://bugreports.qt.io/browse/QTBUG-43270\n\tFILE *rv = NULL;\n\tif (!arg_debug) {\n\t\trv = freopen( \"/dev/null\", \"w\", stderr );\n\t\t(void) rv;\n\t}\n\t\n\t// Start application\n\tint tmp = app.exec();\n\t(void) tmp;\n\t\n\tif (rv)\n\t\tfclose(rv);\n}\n\n"
  },
  {
    "path": "src/firetools/mainwindow.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include \"firetools.h\"\n#include <QtGlobal>\n#if QT_VERSION >= 0x050000\n\t#include <QtWidgets>\n#else\n\t#include <QtGui>\n#endif\n\n#include \"../../firetools_config_extras.h\"\n#include \"../../firetools_config.h\"\n#include \"mainwindow.h\"\n#include \"../common/utils.h\"\n#include \"applications.h\"\n\nMainWindow::MainWindow(QWidget *parent): QWidget(parent, Qt::FramelessWindowHint | Qt::WindowSystemMenuHint) {\n\tactive_index_ = -1;\n\tanimation_id_ = 0;\n\tapp_cnt_ = 0;\n\tcols_ = 0;\n\n\t// check firejail\n\tif (!which(\"firejail\")) {\n\t\tQMessageBox::warning(this, tr(\"Firetools\"),\n\t\t\ttr(\"<br/><b>Firejail</b> software not found. Please install it.<br/><br/><br/>\"));\n\t\texit(1);\n\t}\n\n\t// check if we have permission to run firejail\n\tchar *testrun = run_program(\"firejail /bin/true 2>&1\");\n\tif (!testrun || strstr(testrun, \"Error\")) {\n\t\tQMessageBox::warning(this, tr(\"Firetools\"),\n\t\t\ttr(\"<br/>Cannot run <b>Firejail</b> sandbox, you may not have<br/>the correct permissions to access this program.<br/><br/><br/>\"));\n\t\texit(1);\n\t}\n\n\t// check svg support\n#if QT_VERSION >= 0x050000\n\tQList<QByteArray> flist = QImageReader::supportedImageFormats();\n\tbool svgfound = false;\n\tfor (int i = 0; i < flist.size(); i++) {\n\t\tQByteArray a = flist.at(i);\n\t\tconst char *str = a.constData();\n\t\tif (strcmp(str, \"svg\") == 0)\n\t\t\tsvgfound = true;\n\t}\n\tif (!svgfound) {\n\t\tQMessageBox::warning(this, tr(\"Firetools\"),\n\t\t\ttr(\"<br/>Qt5 SVG icon library not found. Please install it:<br/>\"\n\t\t\t    \"sudo apt-get install libqt5svg5<br/><br/>\"));\n\t}\n#endif\n\n\tapp_cnt_ = applications_init(PACKAGE_LIBDIR \"/uiapps\");\n\tapp_cnt_ += applications_init(\"~/.config/firetools/uiapps\");\n\tcols_ = app_cnt_  / ROWS;\n\tif (app_cnt_ % ROWS)\n\t\tcols_++;\n\n\tcreateTrayActions();\n\tcreateLocalActions();\n\n\tsetContextMenuPolicy(Qt::ActionsContextMenu);\n\tsetToolTip(tr(\"Double click on an icon to open an application.\\n\"\n\t\t\"Drag the launcher with the left mouse button.\\n\"\n\t\t\"Use the right mouse button to open a context menu.\"));\n\tsetWindowTitle(tr(\"Firetools\"));\n\n}\n\n// Run statistics tools\nvoid MainWindow::runTools() {\n\t// start fstats as a separate process\n\tint rv = system(PACKAGE_LIBDIR \"/fstats &\");\n\t(void) rv;\n}\n\n// Start firejail-ui\nvoid MainWindow::newSandbox() {\n\t// start firejail-ui as a separate process\n\tint rv = system(\"firejail-ui &\");\n\t(void) rv;\n}\n\n// About window\nvoid MainWindow::runAbout() {\n\tQString msg = \"<table cellpadding=\\\"10\\\"><tr><td><img src=\\\":/resources/firetools.png\\\"></td>\";\n\tmsg += \"<td>\" + tr(\n\n\t\t\"Firetools is a GUI application for Firejail. \"\n\t\t\"It offers a system tray launcher for sandboxed apps, \"\n\t\t\"sandbox editing, management, and statistics. \"\n\t\t\"The software package also includes a sandbox configuration wizard, firejail-ui.<br/>\"\n\t\t\"<br/>\"\n\t\t\"Firejail  is  a  SUID sandbox program that reduces the risk of security \"\n\t\t\"breaches by restricting the running environment of  untrusted  applications \"\n\t\t\"using Linux namespaces, Linux capabilities and seccomp-bpf.<br/><br/>\") +\n\t\ttr(\"Firetools version:\") + \" \" + PACKAGE_VERSION + \"<br/>\" +\n\t\ttr(\"QT version: \") + \" \" + QT_VERSION_STR + \"<br/>\" +\n\t\ttr(\"License:\") + \" GPL v2<br/>\" +\n\t\ttr(\"Homepage:\") + \" \" + QString(PACKAGE_URL) + \"</td></tr></table><br/><br/>\";\n\n\tQMessageBox::about(this, tr(\"About\"), msg);\n}\n\n// Mouse events: mouse release\nvoid MainWindow::mouseReleaseEvent(QMouseEvent *event) {\n\tif (event->button() == Qt::LeftButton) {\n\t\tint x = event->pos().x();\n\t\tint y = event->pos().y();\n\n\t\tif (x >= MARGIN * 2 + cols_ * 64 - 16 && x <= MARGIN * 2 + cols_ * 64 + 4 &&\n\t\t\t   y >= 4 && y <= 15) {\n\n\t\t\tshowMinimized();\n\t\t}\n\t\tevent->accept();\n\t\tactive_index_ = -1;\n\t}\n}\n\n// Mouse events: mouse press\nvoid MainWindow::mousePressEvent(QMouseEvent *event) {\n\tif (event->button() == Qt::LeftButton) {\n\t\tdragPosition_ = event->globalPos() - frameGeometry().topLeft();\n\t\tevent->accept();\n\t\tactive_index_ = -1;\n\t}\n}\n\n\n// Mouse events\nvoid MainWindow::mouseMoveEvent(QMouseEvent *event) {\n\tif (event->buttons() & Qt::LeftButton) {\n\t\tmove(event->globalPos() - dragPosition_);\n\t\tevent->accept();\n\t}\n}\n\n// Mouse events: double-click\nvoid MainWindow::mouseDoubleClickEvent(QMouseEvent *event) {\n\tif (event->button() == Qt::LeftButton) {\n\t\tQPoint pos = event->pos();\n\t\tint index = app_get_index(pos);\n\t\tif (index != -1) {\n\t\t\tQString exec = applist[index].exec_ + \" &\";\n\t\t\tint rv = system(exec.toStdString().c_str());\n\t\t\t(void) rv;\n\t\t\tevent->accept();\n\t\t\tanimation_id_ = AFRAMES;\n\t\t\tactive_index_ = index;\n\t\t\tQTimer::singleShot(0, this, SLOT(update()));\n\t\t}\n\t}\n}\n\n// Main window visual design\nvoid MainWindow::paintEvent(QPaintEvent *) {\n\t// Start painting\n\tQPainter painter(this);\n\tpainter.setRenderHint(QPainter::Antialiasing);\n\n\t// Window size hint\n\tQSize sz = sizeHint();\n\n\t// Window rectangle size coordinates\n\tQRect windowRectSize(0, 0, sz.width(), sz.height());\n\n\t// Background color for the main window\n\t// (dark gray)\n\tQBrush windowBackgroundColor(QColor(68, 68, 68));\n\n\t// Fills the given rectangle with the specified color values.\n\t// https://doc.qt.io/qt-5.10/qpainter.html#drawRect\n\tpainter.fillRect(windowRectSize, windowBackgroundColor);\n\n\t// Loop icons to rows\n\tint i = 0;\n\tint j = 0;\n\tfor (; i < app_cnt_; i++, j++) {\n\t\tif (j >= ROWS)\n\t\t\tj = 0;\n\n\t\t// Select icon from the looped items\n\t\tQIcon icon = applist[i].app_icon_;\n\n\t\tint sz = 64 ;\n\t\tif (active_index_ == i)\n\t\t\tsz -= animation_id_ * 3;\n\n\n\t\t// More details and examples:\n\t\t// - https://doc.qt.io/qt-5.10/qpainter.html#drawPixmap\n\n\t\t// Target\n\t\tint pixmapTargetXposition = MARGIN * 2 + (64 - sz) / 2 + (i / ROWS) * 64;\n\t\tint pixmapTargetYposition = MARGIN *2 + j * 64 + TOP + (64 - sz) / 2;\n\n\t\tQPoint pixmapTarget(pixmapTargetXposition, pixmapTargetYposition);\n\n\t\t// Source\n\t\tint pixmapWidth = sz;\n\t\tint pixmapHeight = sz;\n\n\t\tQSize pixmapSize(pixmapWidth, pixmapHeight);\n\n\t\t// \"The QPixmap class is an off-screen image representation that can be used as a paint device.\"\n\t\t// - https://doc.qt.io/qt-5.10/qpixmap.html\n\t\t// \"Returns a pixmap with the requested size, mode, and state,\"\n\t\t// - https://doc.qt.io/qt-5.10/qicon.html#pixmap\n\t\tQPixmap pixmap = icon.pixmap(pixmapSize, QIcon::Normal, QIcon::On);\n\n\n\t\t// Paint pixmap items\n\t\tpainter.drawPixmap(pixmapTarget, pixmap);\n\t}\n\n\n\t// Close button\n\t// Rectangle size & coordinates for the close button\n//\tQRect closeButtonRectSize(MARGIN * 2 + cols * 64 - 8, 8, 12, 3);\n\tQRect closeButtonRectSize(MARGIN * 2 + cols_ * 64 - 14,6, 12, 3);\n\n\t// Color for the close button\n\tQBrush closeButtonRectColor(Qt::white);\n\n\t// Fills the given rectangle with the color\n\tpainter.fillRect(closeButtonRectSize, closeButtonRectColor);\n\n\n\t// Default font\n\tpainter.setFont(QFont(\"Sans\", TOP, QFont::Normal));\n\n\t// Animation timer detay if animations are enabled\n\tif (animation_id_ > 0) {\n\t\tanimation_id_--;\n\t\tQTimer::singleShot(ADELAY, this, SLOT(update()));\n\t}\n}\n\n\n// Window resize\nvoid MainWindow::resizeEvent(QResizeEvent * /* event */) {\n\t// margins\n\tQRegion m1(0, 0, cols_ * 64 + MARGIN * 4, TOP + ROWS * 64 + MARGIN * 4);\n\tQRegion m2(MARGIN, MARGIN + TOP, cols_ * 64 + MARGIN * 2, ROWS * 64 + MARGIN * 2);\n\tQRegion m3(MARGIN * 2, MARGIN * 2 + TOP, cols_ * 64, ROWS * 64);\n\n\tQRegion all = m1.subtracted(m2);\n\tall = all.united(m3);\n\n\tsetMask(all);\n}\n\n\n// Window size hint\nQSize MainWindow::sizeHint() const {\n\treturn QSize(64 * cols_ + MARGIN * 4, ROWS * 64 + MARGIN * 4 + TOP);\n}\n\n\nbool MainWindow::event(QEvent *event) {\n\tif (event->type() == QEvent::ToolTip) {\n\t\tQHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);\n\n\t\tint index = app_get_index(helpEvent->pos());\n\t\tif (index == -1) {\n\t\t\tint x = helpEvent->pos().x();\n\t\t\tint y = helpEvent->pos().y();\n\n\t\t\tif (x >= MARGIN * 2 + cols_ * 64 - 8 && x <= MARGIN * 2 + cols_ * 64 + 4 &&\n\t\t\t   y >= 4 && y <= 15) {\n\t\t\t   \tQToolTip::showText(helpEvent->globalPos(), QString(\"Minimize\"));\n\t\t\t   \treturn true;\n\t\t\t}\n\t\t\telse if (x >= 0 && x < 64 &&\n\t\t\t\t   y >= 4 && y <= 15) {\n\t\t\t   \tQToolTip::showText(helpEvent->globalPos(), QString(\"Run tools\"));\n\t\t\t   \treturn true;\n\t\t\t}\n\n\t\t\telse\n\t\t\t\tQToolTip::hideText();\n\t\t}\n\t\telse {\n\t\t\tQToolTip::showText(helpEvent->globalPos(), applist[index].description_);\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn QWidget::event(event);\n}\n\nvoid MainWindow::trayActivated(QSystemTrayIcon::ActivationReason reason) {\n\tif (reason == QSystemTrayIcon::Context)\n\t\treturn;\n\tif (reason == QSystemTrayIcon::DoubleClick)\n\t\treturn;\n\tif (reason == QSystemTrayIcon::MiddleClick)\n\t\treturn;\n\n\tif (isVisible())\n\t\thide();\n\telse\n\t\tshowNormal();\n}\n\n\nvoid MainWindow::createTrayActions() {\n\tminimizeAction = new QAction(tr(\"Mi&nimize\"), this);\n\tconnect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));\n\n\trestoreAction = new QAction(tr(\"&Restore\"), this);\n\tconnect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));\n\n\tquitAction = new QAction(tr(\"&Quit\"), this);\n\tconnect(quitAction, SIGNAL(triggered()), this, SLOT(main_quit()));\n}\n\nvoid MainWindow::createLocalActions() {\n\tQAction *newsandbox = new QAction(tr(\"&Configuration\"), this);\n\tconnect(newsandbox, SIGNAL(triggered()), this, SLOT(newSandbox()));\n\taddAction(newsandbox);\n\n\tQAction *runtools = new QAction(tr(\"&Statistics\"), this);\n\tconnect(runtools, SIGNAL(triggered()), this, SLOT(runTools()));\n\taddAction(runtools);\n\n\tQAction *separator1 = new QAction(this);\n\tseparator1->setSeparator(true);\n\taddAction(separator1);\n\n\tQAction *about = new QAction(tr(\"&About\"), this);\n\tconnect(about, SIGNAL(triggered()), this, SLOT(runAbout()));\n\taddAction(about);\n\n\tqhelp_ = new QAction(tr(\"&Help\"), this);\n\tconnect(qhelp_, SIGNAL(triggered()), this, SLOT(help()));\n\taddAction(qhelp_);\n\n\tQAction *separator2 = new QAction(this);\n\tseparator2->setSeparator(true);\n\taddAction(separator2);\n\n\tQAction *qminimize = new QAction(tr(\"&Minimize\"), this);\n\tconnect(qminimize, SIGNAL(triggered()), this, SLOT(showMinimized()));\n\taddAction(qminimize);\n\n\tQAction *qquit = new QAction(tr(\"&Quit\"), this);\n\tconnect(qquit, SIGNAL(triggered()), this, SLOT(main_quit()));\n\taddAction(qquit);\n}\n\n// Help dialog\nvoid MainWindow::help() {\n\tQMessageBox msgBox;\n\n\tQString txt;\n\ttxt += \"<br/>\";\n\ttxt += \"Double click on an icon to sandbox the application. \";\n\ttxt += \"Click on \\\"-\\\" in the right top corner to minimize the program in the system tray. \";\n\ttxt += \"Drag the launcher with the left mouse button.<br/><br/>\\n\";\n\ttxt += \"Use the right mouse button to open the <b>context menu</b>.<br/><br/>\\n\";\n\ttxt += \"<b>&nbsp;&nbsp;&nbsp;Configuration:</b> run the configuration wizard.<br/>\\n\";\n\ttxt += \"<b>&nbsp;&nbsp;&nbsp;Statistics:</b> open the stats window.<br/>\\n\";\n\ttxt += \"<b>&nbsp;&nbsp;&nbsp;About:</b> program version.<br/>\\n\";\n\ttxt += \"<b>&nbsp;&nbsp;&nbsp;Help:</b> this help window.<br/>\\n\";\n\ttxt += \"<b>&nbsp;&nbsp;&nbsp;Minimize:</b> minimize the launcher<br/>\\n\";\n\ttxt += \"<b>&nbsp;&nbsp;&nbsp;Quit:</b> shut down the lprogram.<br/><br/>\\n\";\n\ttxt += \"The list of applications recognized automatically by Firetools is stored in <b>/usr/lib/firetools/applist</b>. \";\n\ttxt += \"To add more applications to the list drop a similar file in your home directory in <b>~/.config/firetools/uiapps</b>.</br></br>\";\n\n\tQMessageBox::about(this, tr(\"Firetools\"), txt);\n}\n\n// Shutdown sequence\nvoid MainWindow::main_quit() {\n\tprintf(\"exiting...\\n\");\n\n\t// delete application list\n\tQList<Application>::iterator it = applist.begin();\n\twhile (it !=applist.end())\n\t\tit = applist.erase(it);\n\n\tqApp->quit();\n}\n\nint MainWindow::app_get_index(QPoint pos) {\n\tif (pos.y() < (MARGIN * 2 + TOP))\n\t\treturn -1;\n\n\tif (pos.x() > (MARGIN * 2) && pos.x() < (MARGIN * 2 + cols_ * 64)) {\n\t\tint index_y = (pos.y() - 2 * MARGIN - TOP) / 64;\n\t\tint index_x = (pos.x() - 2 * MARGIN) / 64;\n\t\tint index = index_y + index_x * ROWS;\n\n\t\tif (index < app_cnt_)\n\t\t\treturn index;\n\t}\n\treturn -1;\n}\n\n"
  },
  {
    "path": "src/firetools/mainwindow.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef MAINWINDOW_H\n#define MAINWINDOW_H\n#include <QWidget>\n#include <QAction>\n#include <QSystemTrayIcon>\n\nclass MainWindow : public QWidget {\nQ_OBJECT\n\npublic:\n\tMainWindow(QWidget *parent = 0);\n\tQSize sizeHint() const;\n\nprotected:\n\tvoid mouseMoveEvent(QMouseEvent *event);\n\tvoid mousePressEvent(QMouseEvent *event);\n\tvoid mouseReleaseEvent(QMouseEvent *event);\n\tvoid mouseDoubleClickEvent(QMouseEvent *event);\n\tvoid paintEvent(QPaintEvent *event);\n\tvoid resizeEvent(QResizeEvent *event);\n\tbool event(QEvent *event);\n\npublic slots:\n\tvoid trayActivated(QSystemTrayIcon::ActivationReason);\n\t\nprivate slots:\n\tvoid runTools();\n\tvoid help();\n\tvoid main_quit();\n\tvoid newSandbox();\n\tvoid runAbout();\n\nprivate:\n    \tvoid createTrayActions();\n   \tvoid createLocalActions();\n\tint app_get_index(QPoint pos);\n\t\nprivate:\n\tQPoint dragPosition_;\n\tQAction *qhelp_;\n\tint active_index_;\n\tint animation_id_;\n\t\n\tint app_cnt_; // number of applications\n\tint cols_; // number of columns\n\t\npublic:\t\n\t// tray\n\tQAction *minimizeAction;\n\tQAction *restoreAction;\n\tQAction *quitAction;\n\t\n};\n#endif\n"
  },
  {
    "path": "src/firetools/uiapps",
    "content": "# Program list for Firetools\n#\n# Each line defines an application, with semicolons separated fields as follows:\n#\n#       executable; description; icon; (optional) command for starting Firejail\n#\n# Examples:\n#\n#       inkscape;Inkscape SVG Editor;inkscape\n#       calibre;Calibre eBook Reader;/usr/share/calibre/images/lt.png\n#\n# Lines starting in # are comments.\n#\n\n# default apps for Firetools\nfirejail-ui;Configuration;:resources/firejail-ui;firejail-ui\nfiretools;Statistics;:resources/fstats;PACKAGE_LIBDIR/fstats\n\n# Accessories\ncalibre;Calibre eBook Reader;/usr/share/calibre/images/lt.png\ncherrytree;CherryTree Note Taking Application;cherrytree\neog;Eye of Gnome Image Viewer;eog\neom;Eye of MATE Image Viewer;eom\nfbreader;eBook Reader;FBReader\ngalculator;Calculator;galculator\ngnome-calculator;Gnome Calculator;gnome-calculator\ngpicview;GPicView Image Viewer;gpicview\ngthumb;gThumb Image Viewer;gthumb\ngwenview;Gwenview Image Viewer;gwenview\nkcalc;KDE Calculator;kcalc\nkeepass;KeePass Pasword Manager;keepass\nkeepass2;KeePass2 Pasword Manager;keepass2\nkeepassx;KeePassX Pasword Manager;keepassx\nkeepassx2;KeePassX2 Pasword Manager;keepassx2\nkeepassxc;KeePassXC Pasword Manager;keepassxc\npix;Pix Image Management Application;pix\nurxvt;rxvt-unicode Terminal;urxvt\nxviewer;xviewer Image Viewer;xviewer\nxreader;Xreader Document Viewer;xreader\nxterm;xterm Terminal;:resources/gnome-terminal.png\n\n# Games\n0ad;0AD Game;0ad\n2048-qt;2048 Game;2048-qt\n3Dc;Play chess across 3 boards!;3dchess\netr;Extreme Tux Racer Game;etr\nfrozen-bubble;Frozen-Bubble Game;frozen-bubble\npingus;Pingus Game;pingus\nsupertux2;Super Tux Game;supertux\nwarzone2100;Warzone 2100 Game;warzone2100\n\n# Graphics\ndigikam;digiKam Photo Editor;digikam\ngimp;Gimp Graphic Editor;gimp\ninkscape;Inkscape SVG Editor;inkscape\nkolourpaint;KolourPaint Image Editor;kolourpaint\nkamoso;KDE Camera Utility;kamoso\nkrita;krita Graphic Editor;krita\nopenshot;OpenShot Video Editor;openshot\nshowfoto;showfoto Image Viewer and Editor;showfoto\n\n# Internet\nakregator;RSS/Atom Feed Aggregator;akregator\nchromium;Chromium Web Browser;chromium\nchromium-browser;Chromium Web Browser;chromium-browser\ndeluge;Deluge BitTorrent Client;deluge\nempathy;Empathy Messaging Client;empathy\nfalkon;Falkon Web Browser;falkon\nfilezilla;FileZilla File Transfer Application;filezilla\nfirefox;Mozilla Firefox;:resources/firefox\nhexchat;HexChat Messaging Client;hexchat\nicecat;GNU IceCat;:resources/firefox\nicedove;Debian Icedove Email Client;:resources/icedove\niceweasel;Debian Iceweasel;:resources/firefox\ngoogle-chrome;Google Chrome;google-chrome\nmidori;Midori Web Browser;midori\nnetsurf;Netsurf Web Browser;netsurf\nopera;Opera Web Browser;opera\npidgin;Pidgin Messaging Client;pidgin\nqbittorrent;qBittorrent Client;qbittorrent\nquassel;Quassel IRC Client;quassel\nsignal-desktop;Signal Messenger;:resources/signal-desktop.png\nthunderbird;Thunderbird Email Client;thunderbird\ntransmission-gtk;Transmission BitTorrent Client;transmission\ntransmission-qt;Transmission BitTorrent Client;transmission\nxchat;XChat Messaging Client;xchat\n\n# Office\nabiword;Abiword Word Processor;abiword\nemacs;GNU Emacs Text Editor;emacs\nevince;Evince PDF Viewer;evince\ngedit;GNOME Text Eeditor;org.gnome.gedit\njedit;jEdit Text Editor;jedit\nkate;Kate Text Editor;kate\nkile;Kile KDE Integrated LaTeX Environment;kile\nkwrite;KDE Text Editor;kwrite\nleafpad;leafpad Text Editor;leafpad\nlowriter;LibreOffice Writer;:resources/libreoffice-writer.png\nmousepad;Mousepad Text Editor;accessories-text-editor\nokular;Okular Universal Document Viewer;okular\nqpdfview;qPDFView PDF Viewer;qpdfview\nscribus;Scribus Page Layout Program;scribus\nxpdf;Xpdf PDF Viewer;xpdf\n\n# Sound and video\namarok;Amarok Media Player;amarok\naudacious;Audacious Media Player;audacious\naudacity;Audacity Sound Editor;audacity\naudex;Audio Ripper;audex\nclementine;Clementine Media Player;application-x-clementine\ndragon;Dragon Player;dragonplayer\nelisa;Simple KDE Music Player;elisa\nghb;HandBrake Media Convertor;hb-icon\ngnome-mplayer;GNOME Media Player;gnome-mplayer\nharuna;Haruna Video Player;haruna\nk3b;K3b CD/DVD Burning/Riping Application;k3b\nkaffeine;Kaffeine Media Player;kaffeine\nkdenlive;Kdenlive Video Editor;kdenlive\nkget;KDE Download Manager;kget\nkid3;KDE Audio Tagger;kid3\nkino;Kino Video Player;kino\nkmail;KMail Email Client;kmail\nkmix;KDE Sound Channel Mixer;kmix\nkmplayer;KDE Multimedia Player;kmplayer\nkonqueror;Konqueror Web Browser;konqueror\nkonversation;Konversation IRC Client;konversation\nkopete;Kopete Instant Messaging;kopete\nktorrent;Ktorrent BitTorrent Client;ktorrent\nkwave;KWave Sound Editor;kwave\nmpv;MPV Media Player;mpv;firejail mpv  --player-operation-mode=pseudo-gui\nrhythmbox;Rhythmbox Media Player;rhythmbox\nsmplayer;SMPlayer Media Player;smplayer\nsubtitlecomposer;KDE Subtitle Composer;subtitlecomposer\ntotem;Totem Media Player;totem\nvlc;VideoLAN Client;vlc\nxplayer;Xplayer Media Player;xplayer\n"
  },
  {
    "path": "src/fmgr/config.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include \"fmgr.h\"\n#include \"../common/utils.h\"\n\n#define DEFAULT_X_SIZE 500\n#define DEFAULT_Y_SIZE 500\n#define MINSIZE 500\n#define BUFSIZE 4096\n\nvoid config_read_screen_size(int *x, int *y) {\n\t// set defaults\n\t*x = DEFAULT_X_SIZE;\n\t*y = DEFAULT_X_SIZE;\n\n\t// open config file\n\tchar *cfgdir = get_config_directory();\n\tif (!cfgdir)\n\t\treturn;\n\tchar *fname;\n\tif (asprintf(&fname, \"%s/fmgr.config\", cfgdir) == -1)\n\t\terrExit(\"asprintf\");\n\tFILE *fp = fopen(fname, \"r\");\n\tfree(fname);\n\tif (!fp)\n\t\treturn;\n\t\n\t// read file and parse it\n\tchar buf[BUFSIZE];\n\twhile (fgets(buf, BUFSIZE, fp)) {\n\t\tchar *ptr = buf;\n\t\twhile (*ptr == ' ' || *ptr == '\\t')\n\t\t\tptr++;\n\t\tif (strncmp(ptr, \"x \", 2) == 0) {\n\t\t\tptr += 2;\n\t\t\tif (sscanf(ptr, \"%d\", x) != 1) {\n\t\t\t\tfprintf(stderr, \"Error: invalid X size in ~/.config/firetools/fmgr.config\\n\");\n\t\t\t\tfclose(fp);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\telse if (strncmp(ptr, \"y \", 2) == 0) {\n\t\t\tptr += 2;\n\t\t\tif (sscanf(ptr, \"%d\", y) != 1) {\n\t\t\t\tfprintf(stderr, \"Error: invalid Y size in ~/.config/firetools/fmgr.config\\n\");\n\t\t\t\tfclose(fp);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\tfclose(fp);\n}\n\nvoid config_write_screen_size(int x, int y) {\n\tx = (x < MINSIZE)? DEFAULT_X_SIZE: x;\n\ty = (y < MINSIZE)? DEFAULT_Y_SIZE: y;\n\t\n\t// open config file\n\tchar *cfgdir = get_config_directory();\n\tif (!cfgdir)\n\t\treturn;\n\tchar *fname;\n\tif (asprintf(&fname, \"%s/fmgr.config\", cfgdir) == -1)\n\t\terrExit(\"asprintf\");\n\tFILE *fp = fopen(fname, \"w\");\n\tfree(fname);\n\tif (!fp)\n\t\treturn;\n\n\t// write file\n\tfprintf(fp, \"x %d\\n\", x);\n\tfprintf(fp, \"y %d\\n\", y);\n\tfclose(fp);\n}\n"
  },
  {
    "path": "src/fmgr/fmgr.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef FIREFM_H\n#define FIREFM_H\n#include <stdio.h>\n#include <string.h>\n#include <assert.h>\n\n#include \"../common/common.h\"\n#include \"../common/utils.h\"\n\n// main.cpp\nextern int arg_debug;\n\n// config.cpp\nvoid config_read_screen_size(int *x, int *y);\nvoid config_write_screen_size(int x, int y);\n\n#endif\n"
  },
  {
    "path": "src/fmgr/fmgr.pro",
    "content": "QMAKE_CXXFLAGS += $$(CXXFLAGS) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security\nQMAKE_CFLAGS += $$(CFLAGS) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security\nQMAKE_LFLAGS += $$(LDFLAGS) -Wl,-z,relro -Wl,-z,now\nQT += widgets\n HEADERS       = fmgr.h mainwindow.h topwidget.h fs.h\n SOURCES       = mainwindow.cpp topwidget.cpp main.cpp \\\n\t\t  ../common/utils.cpp fs.cpp config.cpp\n\t\n                 \nRESOURCES = fmgr.qrc\nTARGET=../../build/fmgr\n"
  },
  {
    "path": "src/fmgr/fmgr.qrc",
    "content": "<!DOCTYPE RCC><RCC version=\"1.0\">\n<qresource prefix=\"/\">\n   <file>resources/firetools.png</file>\n   <file>resources/firetools-minimal.png</file>\n   <file>resources/go-top.png</file>\n   <file>resources/go-up.png</file>\n   <file>resources/user-home.png</file>\n   <file>resources/gnome-fs-directory.png</file>\n   <file>resources/empty.png</file>\n   <file>resources/emblem-symbolic-link.png</file>\n   <file>resources/refresh.png</file>\n</qresource>\n</RCC>\n"
  },
  {
    "path": "src/fmgr/fs.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include \"fs.h\"\n#include \"fmgr.h\"\n#include <string.h>\n\nFS::FS(pid_t pid): pid_(pid) {\n\tinitialize(pid);\n}\n\nvoid FS::initialize(pid_t pid) {\n\tchar *cmd;\n\tif (asprintf(&cmd, \"firejail --fs.print=%d\", (int) pid) == -1)\n\t\terrExit(\"asprintf\");\n\t\t\n\tchar *str = run_program(cmd);\n\tif (str == NULL)\n\t\treturn;\n\tchar *ptr = strtok(str, \"\\n\");\n\twhile (ptr) {\n\t\tif (arg_debug)\n\t\t\tprintf(\"fs.print: %s\\n\", ptr);\n\n\t\tif (strncmp(ptr, \"tmpfs \", 6) == 0) {\n\t\t\tpaths_.append(QString(ptr + 6));\n\t\t\tops_.append(QString(\"T\"));\n\t\t}\n\t\telse if (strncmp(ptr, \"blacklist \", 10) == 0 ) {\n\t\t\tpaths_.append(QString(ptr + 10));\n\t\t\tops_.append(QString(\"B\"));\n\t\t}\n\t\telse if (strncmp(ptr, \"blacklist-nolog \", 16) == 0 ) {\n\t\t\tpaths_.append(QString(ptr + 16));\n\t\t\tops_.append(QString(\"B\"));\n\t\t}\n\t\telse if (strncmp(ptr, \"read-only \", 10) == 0 ) {\n\t\t\tpaths_.append(QString(ptr + 10));\n\t\t\tops_.append(QString(\"R\"));\n\t\t}\n\t\telse if (strncmp(ptr, \"clone \", 6) == 0 ) {\n\t\t\tpaths_.append(QString(ptr + 6));\n\t\t\tops_.append(QString(\"C\"));\n\t\t}\n\t\telse if (strncmp(ptr, \"create \", 7) == 0 ) {\n\t\t\tpaths_.append(QString(ptr + 7));\n\t\t\tops_.append(QString(\"G\")); // generated\n\t\t}\n\n\t\tptr = strtok(NULL, \"\\n\");\n\t}\n\tpaths_.replaceInStrings(\" \", \"\\\\ \");\n}\n \nvoid FS::checkPath(QString path) {\n\tif (arg_debug)\n\t\tprintf(\"checkPath %s\\n\", path.toUtf8().constData());\n\tpath_ = path;\n}\n\nQString FS::checkFile(QString file) {\n\tfile = file.replace(\" \", \"\\\\ \");\n\tQString full_path = path_ + file;\n\tif (arg_debug) \n\t\tprintf(\"checkFile full path %s\\n\", full_path.toUtf8().constData());\n\n\tQString str = \"\";\n\tfor (int i = 0; i < paths_.size(); ++i) {\n\t\tif (full_path == paths_.at(i)) {\n\t\t\tstr += ops_.at(i);\n\t\t}\n\t}\n\n\tif (arg_debug) \n\t\tprintf(\"checkFile database %s, result %s\\n\", full_path.toUtf8().constData(), str.toUtf8().constData());\n\treturn str;\n}\n"
  },
  {
    "path": "src/fmgr/fs.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef FS_H\n#define FS_H\n#include <unistd.h>\n#include <sys/types.h>\n#include <QStringList>\n\nclass FS {\npublic:\n\tFS(pid_t pid);\n\tQString getType(QString path, QString file);\n\tvoid checkPath(QString path);\n\tQString checkFile(QString file);\n\t\nprivate:\n\tvoid initialize(pid_t pid);\n\n\tpid_t pid_;\n\tQStringList paths_;\n\tQStringList ops_;\n\t\n\tQString path_;\n};\n\n#endif\n"
  },
  {
    "path": "src/fmgr/main.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include <QApplication>\n#include <QMenu>\n#include <QSystemTrayIcon>\n\n#include \"fmgr.h\"\n#include \"mainwindow.h\"\n//#include \"../common/utils.h\"\n#include \"../../firetools_config.h\"\n\nint arg_debug = 0;\n\nstatic void usage() {\n\tprintf(\"firemgr - Firejail file manager\\n\\n\");\n\tprintf(\"Usage: firemgr [options] sandbox-pid\\n\\n\");\n\tprintf(\"Options:\\n\");\n\tprintf(\"\\t--debug - debug mode\\n\\n\");\n\tprintf(\"\\t--help - this help screen\\n\\n\");\n\tprintf(\"\\t--version - print software version and exit\\n\\n\");\n}\n\nstatic bool is_pid(const char *str) {\n\tassert(str != NULL);\n\tconst char *ptr = str;\n\t\n\twhile (*ptr != '\\0') {\n\t\tif (!isdigit(*ptr))\n\t\t\treturn false;\n\t\tptr++;\n\t}\n\t\n\tint pid = atoi(str);\n\tif (pid <= 0)\n\t\treturn false;\n\treturn true;\t\n}\n\n\nint main(int argc, char *argv[]) {\n\tint i;\n\t\n\t// parse arguments\n\tfor (i = 1; i < argc; i++) {\n\t\tif (strcmp(argv[i], \"--debug\") == 0)\n\t\t\targ_debug = 1;\n\t\telse if (strcmp(argv[i], \"--help\") == 0 || strcmp(argv[i], \"-?\") == 0) {\n\t\t\tusage();\n\t\t\treturn 0;\n\t\t}\n\t\telse if (strcmp(argv[i], \"--version\") == 0) {\n\t\t\tprintf(\"Firetools version \" PACKAGE_VERSION \"\\n\");\n\t\t\treturn 0;\n\t\t}\n\t\telse if (*argv[i] == '-') {\n\t\t\tfprintf(stderr, \"Error: invalid option\\n\");\n\t\t\tusage();\n\t\t\treturn 1;\n\t\t}\t\t\n\t\telse\n\t\t\tbreak;\n\t}\n\t\n\t// in this moment we should have a pid\n\tif (i == argc || i != (argc - 1) || !is_pid(argv[i])) {\n\t\tfprintf(stderr, \"Error: process ID expected\\n\");\n\t\tusage();\n\t\treturn 1;\n\t}\n\tpid_t pid = (pid_t) atoi(argv[i]);\n\n\t// initialize resources\n\tQ_INIT_RESOURCE(fmgr);\n\n\tQApplication app(argc, argv);\n\tMainWindow fm(pid);\n\tfm.show();\n\treturn app.exec();\n}\n\n"
  },
  {
    "path": "src/fmgr/mainwindow.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include \"fmgr.h\"\n#include \"fs.h\"\n\n#include <QtGlobal>\n#if QT_VERSION >= 0x050000\n\t#include <QtWidgets>\n#else\n\t#include <QtGui>\n#endif\n\n#include \"mainwindow.h\"\n#include \"topwidget.h\"\n#include <QtGui>\n#include <cstdlib>\n\nMainWindow::MainWindow(pid_t pid, QWidget *parent): QMainWindow(parent), pid_(pid) {\n\t// check firejail installed\n\tif (!which(\"firejail\")) {\n\t\tQMessageBox::warning(this, tr(\"Firejail File Manager\"),\n\t\t\ttr(\"<br/><b>Firejail</b> software not found. Please install it.<br/><br/><br/>\"));\n\t\texit(1);\n\t}\n\n\t// verify sandbox\n\t{\n\t\tchar *cmd;\n\t\tif (asprintf(&cmd, \"firejail --ls=%d / 2>&1\", pid_) == -1)\n\t\t\terrExit(\"asprintf\");\n\t\tchar *out = run_program(cmd);\n\t\tif (out == NULL || strncmp(out, \"Error\", 5) == 0) {\n\t\t\tchar *msg;\n\t\t\tif (asprintf(&msg, \"<br/><b>Sandbox %d not found.<br/><br/><br/>\", pid) == -1)\n\t\t\t\terrExit(\"asprintf\");\n\t\t\tQMessageBox::warning(this, tr(\"Firejail File Manager\"), tr(msg));\n\t\t\texit(1);\n\t\t}\n\t}\n\n\t// initialize FS\n\tfs_ = new FS(pid);\n\n\ttop_ = new TopWidget(this);\n\tconnect(top_, SIGNAL(upClicked()), this, SLOT(handleUp()));\n\tconnect(top_, SIGNAL(rootClicked()), this, SLOT(handleRoot()));\n\tconnect(top_, SIGNAL(refreshClicked()), this, SLOT(handleRefresh()));\n\tconnect(top_, SIGNAL(homeClicked()), this, SLOT(handleHome()));\n\n\tline_ = new QLineEdit(this);\n\tQString txt = build_line();\n\tline_->setText(txt);\n\tline_->setReadOnly(true);\n\n\ttable_ = new QTableWidget(0, 6, this);\n\tQStringList header;\n\theader.append(\" \");\n\theader.append(\" \");\n\theader.append(\"Mount\");\n\theader.append(\"Owner\");\n\theader.append(\"Size\");\n\theader.append(\"Name\");\n\ttable_->setHorizontalHeaderLabels(header);\n\ttable_->verticalHeader()->setVisible(false);\n\ttable_->setColumnWidth(0, 20);\n\ttable_->setColumnWidth(1, 26);\n\ttable_->setColumnWidth(2, 100);\n\ttable_->setColumnWidth(3, 100);\n\ttable_->setColumnWidth(4, 100);\n\ttable_->setColumnWidth(5, 500);\n\ttable_->horizontalHeader()->setStretchLastSection(true);\n\ttable_->setShowGrid(false);\n\ttable_->setColumnHidden(0, true);\n\tconnect(table_, SIGNAL(cellClicked(int, int)), this, SLOT (cellClicked(int, int)));\n\tprint_files(\"/\");\n\n\tQWidget *empty1 = new QWidget(this);\n\tempty1->setMinimumWidth(30);\n\tQWidget *empty2 = new QWidget(this);\n\tempty2->setMinimumWidth(10);\n\n\tQGridLayout *mainLayout = new QGridLayout;\n\tmainLayout->addWidget(top_, 0, 0);\n\tmainLayout->addWidget(empty1, 0, 1);\n\tmainLayout->addWidget(line_, 0, 2);\n\tmainLayout->addWidget(empty2, 0, 3);\n\tmainLayout->addWidget(table_, 1, 0, 1, 4);\n\tmainLayout->setColumnStretch(0, 1);\n\tmainLayout->setColumnStretch(1, 1);\n\tmainLayout->setColumnStretch(2, 200);\n\tmainLayout->setColumnStretch(3, 1);\n\tQWidget *mainWidget = new QWidget;\n\tmainWidget->setLayout(mainLayout);\n\n\tsetCentralWidget(mainWidget);\n\tsetMinimumWidth(500);\n\t// set screen size and title\n\tint x;\n\tint y;\n\tconfig_read_screen_size(&x, &y);\n \tresize(x, y);\n\tchar *title;\n\tif (asprintf(&title, \"Firejail Sandbox %d\", pid) == -1)\n\t\terrExit(\"asprintf\");\n\tsetWindowTitle(tr(title));\n\tfree(title);\n}\n\nMainWindow::~MainWindow() {\n\tif (!isMaximized())\n\t\tconfig_write_screen_size(width(), height());\n}\n\nvoid MainWindow::print_files(const char *path) {\n\t// replace ' ' with '\\ '\n\tQString qpath(path);\n\tif (strchr(path, ' ')) {\n\t\tqpath.replace(\" \", \"\\\\ \");\n\t\tpath =  qpath.toUtf8().constData();\n\t}\n\n\tif (arg_debug)\n\t\tprintf(\"print_files path %s\\n\", path);\n\n\tchar *cmd;\n\tif (asprintf(&cmd, \"firejail --quiet --ls=%d %s 2>&1\", pid_, path) == -1)\n\t\terrExit(\"asprintf\");\n\n\t// clear table\n\tint rows = table_->rowCount();\n\twhile (rows > 0) {\n\t\ttable_->removeRow(0);\n\t\trows--;\n\t}\n\n\tchar *out = run_program(cmd);\n\tif (out == NULL || strncmp(out, \"Error\", 5) == 0) {\n\t\tchar *msg;\n\t\tif (asprintf(&msg, \"<br/><b>Directory %s not found.<br/><br/><br/>\", path) == -1)\n\t\t\terrExit(\"asprintf\");\n\t\tQMessageBox::warning(this, tr(\"Firejail File Manager\"), tr(msg));\n\t\tfree(msg);\n\t\treturn;\n\t}\n\n\t// fs flags\n\tfs_->checkPath(QString(path));\n\n\tchar *ptr = strtok(out, \"\\n\");\n\trows = 0;\n\twhile (ptr) {\n\t\t// skip warnings and errors\n\t\tif (strncmp(ptr, \"Warning:\", 8) == 0 ||\n\t\t    strncmp(ptr, \"Error:\", 6) == 0) {\n\t\t\tptr = strtok(NULL, \"\\n\");\n\t\t\tcontinue;\n\t\t}\n\t\tsplit_command(ptr);\n\n\t\t// adjust the list in order to accept file names with spaces\n\t\tif (sargc > 5) {\n\t\t\tchar *ptr = sargv[4];\n\t\t\t// replace '\\0' with ' ' (sargc - 5) times\n\t\t\tfor (int i = sargc - 5; i > 0; i--) {\n\t\t\t\twhile (*ptr != '\\0')\n\t\t\t\t\tptr++;\n\t\t\t\t*ptr = ' ';\n\t\t\t}\n\t\t\tsargc = 5;\n\t\t}\n\n\t\tif (sargc == 5) {\n\t\t\tif (strcmp(sargv[4], \"..\") != 0 && strcmp(sargv[4], \".\") != 0) {\n\t\t\t\ttable_->setRowCount(rows + 1);\n\n\t\t\t\t// image\n\t\t\t\tif (*sargv[0] == 'd') {\n\t\t\t\t\ttable_->setItem(rows, 0, new QTableWidgetItem(\"D\"));\n\t\t\t\t\tQImage *img = new QImage(\":resources/gnome-fs-directory.png\");\n\t\t\t\t\tQTableWidgetItem *timage = new QTableWidgetItem;\n\t\t\t\t\ttimage->setData(Qt::DecorationRole, QPixmap::fromImage(*img));\n\t\t\t\t\ttable_->setItem(rows, 1, new QTableWidgetItem(*timage));\n\t\t\t\t}\n\t\t\t\telse if (*sargv[0] == 'l') {\n\t\t\t\t\ttable_->setItem(rows, 0, new QTableWidgetItem(\"L\"));\n\t\t\t\t\tQImage *img = new QImage(\":resources/emblem-symbolic-link.png\");\n\t\t\t\t\tQTableWidgetItem *timage = new QTableWidgetItem;\n\t\t\t\t\ttimage->setData(Qt::DecorationRole, QPixmap::fromImage(*img));\n\t\t\t\t\ttable_->setItem(rows, 1, new QTableWidgetItem(*timage));\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttable_->setItem(rows, 0, new QTableWidgetItem(\"F\"));\n\t\t\t\t\tQImage *img = new QImage(\":resources/empty.png\");\n\t\t\t\t\tQTableWidgetItem *timage = new QTableWidgetItem;\n\t\t\t\t\ttimage->setData(Qt::DecorationRole, QPixmap::fromImage(*img));\n\t\t\t\t\ttable_->setItem(rows, 1, new QTableWidgetItem(*timage));\n\t\t\t\t}\n\n\t\t\t\t// fs flags\n\t\t\t\tQString s = fs_->checkFile(QString(sargv[4]));\n\n\t\t\t\tif (s.contains(\"B\"))\n\t\t\t\t\ts = \"Blacklist\";\n\t\t\t\telse if (s.contains(\"T\") && s.contains(\"R\"))\n\t\t\t\t\ts = \"Temporary-RO\";\n\t\t\t\telse if (s.contains(\"T\"))\n\t\t\t\t\ts = \"Temporary\";\n\t\t\t\telse if (s.contains(\"G\")) {\n\t\t\t\t\tif (s.contains(\"R\"))\n\t\t\t\t\t\ts = \"Generated-RO\";\n\t\t\t\t\telse\n\t\t\t\t\t\ts = \"Generated\";\n\t\t\t\t}\n\t\t\t\telse if (s.contains(\"C\")) {\n\t\t\t\t\tif (s.contains(\"R\"))\n\t\t\t\t\t\ts = \"Clone-RO\";\n\t\t\t\t\telse\n\t\t\t\t\t\ts = \"Clone\";\n\t\t\t\t}\n\t\t\t\telse if (s.contains(\"R\"))\n\t\t\t\t\ts = \"Read-only\";\n\n\t\t\t\tQTableWidgetItem *item =  new QTableWidgetItem(s);\n\t\t\t\titem->setTextAlignment(Qt::AlignCenter);\n\t\t\t\ttable_->setItem(rows, 2, item);\n\n\t\t\t\titem =  new QTableWidgetItem(sargv[1]);\n\t\t\t\titem->setTextAlignment(Qt::AlignCenter);\n\t\t\t\ttable_->setItem(rows, 3, item);\n\n\t\t\t\titem =  new QTableWidgetItem(sargv[3]);\n\t\t\t\titem->setTextAlignment(Qt::AlignCenter);\n\t\t\t\ttable_->setItem(rows, 4, item);\n\n\t\t\t\titem =  new QTableWidgetItem(QString(\"  \") + QString(sargv[4]));\n//\t\t\t\titem->setTextAlignment(Qt::AlignHorizontal_Mask);\n\t\t\t\ttable_->setItem(rows, 5, item);\n\t\t\t\trows++;\n\t\t\t}\n\t\t}\n\n\t\tptr = strtok(NULL, \"\\n\");\n\t}\n}\n\nvoid MainWindow::handleUp() {\n\tif (path_.size() == 0)\n\t\treturn handleRefresh();\n\n\tpath_.takeLast();\n\tQString full_path = build_path();\n\tprint_files(full_path.toStdString().c_str());\n\tQString txt = build_line();\n\tline_->setText(txt);\n}\n\nvoid MainWindow::handleRefresh() {\n\tQString full_path = build_path();\n\tprint_files(full_path.toStdString().c_str());\n\tQString txt = build_line();\n\tline_->setText(txt);\n}\n\nvoid MainWindow::handleHome() {\n\tconst char* username = getenv(\"USER\");\n\tpath_.clear();\n\tpath_.append(QString(\"home\"));\n\tif (username)\n\t\tpath_.append(QString(username));\n\tQString full_path = build_path();\n\tprint_files(full_path.toStdString().c_str());\n\tQString txt = build_line();\n\tline_->setText(txt);\n}\n\nvoid MainWindow::handleRoot() {\n\tpath_.clear();\n\tprint_files(\"/\");\n\tQString txt = build_line();\n\tline_->setText(txt);\n}\n\nQString  MainWindow::build_path() {\n\tQString retval = QString(\"/\");\n\n\tfor (int i = 0; i < path_.size(); ++i) {\n\t\tretval += path_.at(i);\n\t\tretval += QString(\"/\");\n\t}\n\n\treturn retval;\n}\n\nQString  MainWindow::build_line() {\n\tQString retval = \"/\";\n//\tretval.sprintf(\"%d:///\", pid_);\n\n\tfor (int i = 0; i < path_.size(); ++i) {\n\t\tretval += path_.at(i);\n\t\tretval += QString(\"/\");\n\t}\n\n\treturn retval;\n}\n\nvoid MainWindow::cellClicked(int row, int column) {\n\t(void) column;\n\n\tQString type =  table_->item(row, 0)->text();\n\tif (type != \"D\")\n\t\treturn;\n\tQString dir =  table_->item(row, 5)->text();\n\tdir = dir.mid(2);\n\tpath_.append(dir);\n\n\tQString full_path = build_path();\n\tprint_files(full_path.toStdString().c_str());\n\tQString txt = build_line();\n\tline_->setText(txt);\n}\n"
  },
  {
    "path": "src/fmgr/mainwindow.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef MAINWINDOW_H\n#define MAINWINDOW_H\n#include <QMainWindow>\n\nclass QLineEdit;\nclass QTableWidget;\nclass TopWidget;\nclass FS;\n\nclass MainWindow : public QMainWindow {\nQ_OBJECT\n\npublic:\n\tMainWindow(pid_t pid, QWidget *parent = 0);\n\t~MainWindow();\n\nprivate slots:\n\tvoid handleUp();\n\tvoid handleHome();\n\tvoid handleRoot();\n\tvoid handleRefresh();\n\tvoid cellClicked(int row, int column);\n\nprivate:\n\tvoid print_files(const char *path);\n\tQString build_path();\n\tQString build_line();\n\nprivate:\n\tpid_t pid_;\n\tTopWidget *top_;\n\tQLineEdit *line_;\n\tQTableWidget *table_;\n\tQStringList path_;\n\tFS *fs_;\n};\n#endif\n"
  },
  {
    "path": "src/fmgr/topwidget.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include \"fmgr.h\"\n#include \"topwidget.h\"\n#include \"mainwindow.h\"\n\n#include <QtGlobal>\n#if QT_VERSION >= 0x050000\n\t#include <QtWidgets>\n#else\n\t#include <QtGui>\n#endif\n\nvoid TopWidget::paintEvent(QPaintEvent *event) {\n\t(void) event;\n\tQPainter painter(this);\n\n\t// draw\n\tpainter.drawImage(0, 0, QImage(\":resources/go-up.png\"));\n\tpainter.drawImage(34, 0, QImage(\":resources/refresh.png\"));\n\tpainter.drawImage(68, 0, QImage(\":resources/go-top.png\"));\n\tpainter.drawImage(102, 0, QImage(\":resources/user-home.png\"));\n}\n\nvoid TopWidget::mousePressEvent(QMouseEvent *event) {\n\tQPoint pos = event->pos();\n\tif (event->button() == Qt::LeftButton) {\n\t\tif (pos.x() <= 24)\n\t\t\temit upClicked();\n\t\telse if (pos.x() >= 34 && pos.x() < 58)\n\t\t\temit refreshClicked();\n\t\telse if (pos.x() >= 68 && pos.x() < 92)\n\t\t\temit rootClicked();\n\t\telse if (pos.x() >= 102 && pos.x() < 12692)\n\t\t\temit homeClicked();\n\t}\n\n\tevent->accept();\n}\n"
  },
  {
    "path": "src/fmgr/topwidget.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef TOPWIDGET_H\n#define TOPWIDGET_H\n#include <QWidget>\n#include <QSize>\n\nclass TopWidget: public QWidget {\n\tQ_OBJECT\npublic:\n\tTopWidget(QWidget *parent = 0): QWidget(parent) {}\n\tQSize minimumSizeHint() const {\n\t\treturn QSize(126, 24);\n\t}\n\t\n\tQSize sizeHint() const {\n\t\treturn QSize(126, 24);\n\t}\n\nsignals:\n\tvoid upClicked();\n\tvoid rootClicked();\n\tvoid refreshClicked();\n\tvoid homeClicked();\n\nprotected:\n\tvoid paintEvent(QPaintEvent *event);\n\tvoid mousePressEvent(QMouseEvent *event);\n\nprivate:\n//\tbool drag_;\n};\n#endif\n"
  },
  {
    "path": "src/fstats/config.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include \"fstats.h\"\n#include \"../common/utils.h\"\n\n#define DEFAULT_X_SIZE 650\n#define DEFAULT_Y_SIZE 650\n#define MINSIZE 400\n#define BUFSIZE 4096\n\nvoid config_read_screen_size(int *x, int *y) {\n\t// set defaults\n\t*x = DEFAULT_X_SIZE;\n\t*y = DEFAULT_X_SIZE;\n\n\t// open config file\n\tchar *cfgdir = get_config_directory();\n\tif (!cfgdir)\n\t\treturn;\n\tchar *fname;\n\tif (asprintf(&fname, \"%s/fstats.config\", cfgdir) == -1)\n\t\terrExit(\"asprintf\");\n\tFILE *fp = fopen(fname, \"r\");\n\tfree(fname);\n\tif (!fp)\n\t\treturn;\n\t\n\t// read file and parse it\n\tchar buf[BUFSIZE];\n\twhile (fgets(buf, BUFSIZE, fp)) {\n\t\tchar *ptr = buf;\n\t\twhile (*ptr == ' ' || *ptr == '\\t')\n\t\t\tptr++;\n\t\tif (strncmp(ptr, \"x \", 2) == 0) {\n\t\t\tptr += 2;\n\t\t\tif (sscanf(ptr, \"%d\", x) != 1) {\n\t\t\t\tfprintf(stderr, \"Error: invalid X size in ~/.config/firetools/fstats.config\\n\");\n\t\t\t\tfclose(fp);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\telse if (strncmp(ptr, \"y \", 2) == 0) {\n\t\t\tptr += 2;\n\t\t\tif (sscanf(ptr, \"%d\", y) != 1) {\n\t\t\t\tfprintf(stderr, \"Error: invalid Y size in ~/.config/firetools/fstats.config\\n\");\n\t\t\t\tfclose(fp);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\tfclose(fp);\n}\n\nvoid config_write_screen_size(int x, int y) {\n\tx = (x < MINSIZE)? DEFAULT_X_SIZE: x;\n\ty = (y < MINSIZE)? DEFAULT_Y_SIZE: y;\n\t\n\t// open config file\n\tchar *cfgdir = get_config_directory();\n\tif (!cfgdir)\n\t\treturn;\n\tchar *fname;\n\tif (asprintf(&fname, \"%s/fstats.config\", cfgdir) == -1)\n\t\terrExit(\"asprintf\");\n\tFILE *fp = fopen(fname, \"w\");\n\tfree(fname);\n\tif (!fp)\n\t\treturn;\n\n\t// write file\n\tfprintf(fp, \"x %d\\n\", x);\n\tfprintf(fp, \"y %d\\n\", y);\n\tfclose(fp);\n}\n"
  },
  {
    "path": "src/fstats/db.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include \"db.h\"\n\nDb::Db(): cycle_(DbPid::MAXCYCLE - 1), g1h_cycle_(DbPid::MAXCYCLE - 1), g1h_cycle_delta_(DbPid::G1HCYCLE_DELTA - 1), \n\tg12h_cycle_(DbPid::MAXCYCLE - 1), g12h_cycle_delta_(DbPid::G12HCYCLE_DELTA - 1), pidlist_(0) {}\n\nvoid Db::newCycle() {\n\tif (++cycle_ >= DbPid::MAXCYCLE)\n\t\tcycle_ = 0;\n\tif (++g1h_cycle_delta_ >= DbPid::G1HCYCLE_DELTA) {\n\t\tg1h_cycle_delta_ = 0;\n\t\tif (++g1h_cycle_ >= DbPid::MAXCYCLE)\n\t\t\tg1h_cycle_ = 0;\n\t\tif (++g12h_cycle_delta_ >= DbPid::G12HCYCLE_DELTA) {\n\t\t\tg12h_cycle_delta_ = 0;\n\t\t\tif (++g12h_cycle_ >= DbPid::MAXCYCLE)\n\t\t\t\tg12h_cycle_ = 0;\n\t\t}\n\t}\n}\n\n\nDbPid *Db::findPid(pid_t pid) {\n\tif (!pidlist_) {\n\t\treturn 0;\n\t}\n\t\n\treturn pidlist_->find(pid);\n}\n\nDbPid *Db::newPid(pid_t pid) {\n\tassert(findPid(pid) == 0);\n\t\n\tDbPid *newpid = new DbPid(pid);\n\tif (!pidlist_)\n\t\tpidlist_ = newpid;\n\telse\n\t\tpidlist_->add(newpid);\n\t\t\n\treturn newpid;\n}\n\nDbPid *Db::removePid(pid_t pid) {\n\t// find dbpid\n\tDbPid *dbpid = findPid(pid);\n\tif (!dbpid)\n\t\treturn 0;\n\t\n\t// remove first element\n\tif (dbpid == pidlist_)\n\t\tpidlist_ = dbpid->getNext();\n\telse\n\t\tpidlist_->remove(dbpid);\n\t\n\tdbpid->resetNext();\n\treturn dbpid;\n}\n\nvoid Db::dbgprint() {\n\tif (pidlist_)\n\t\tpidlist_->dbgprint();\n}\n\nvoid Db::dbgprintcycle() {\n\tprintf(\"4min cycle %d, 1h delta %d, 1h cycle %d, 12h delta %d, 12h cycle %d\\n\",\n\t\tcycle_, g1h_cycle_delta_, g1h_cycle_, g12h_cycle_delta_, g12h_cycle_);\n}\n\n"
  },
  {
    "path": "src/fstats/db.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef DB_H\n#define DB_H\n\n#include \"fstats.h\"\n#include \"dbpid.h\"\n\n\nclass Db {\npublic:\n\tstatic Db& instance() {\n\t\tstatic Db myinstance;\n\t\treturn myinstance;\n\t}\n\t\n\tvoid newCycle();\n\tint getCycle() {\n\t\treturn cycle_;\n\t}\n\tint getG1HCycle() {\n\t\treturn g1h_cycle_;\n\t}\n\tint getG1HCycleDelta() {\n\t\treturn g1h_cycle_delta_;\n\t}\n\tint getG12HCycle() {\n\t\treturn g12h_cycle_;\n\t}\n\tint getG12HCycleDelta() {\n\t\treturn g12h_cycle_delta_;\n\t}\n\tDbPid *firstPid() {\n\t\treturn pidlist_;\n\t}\n\tDbPid *newPid(pid_t pid);\n\tDbPid *findPid(pid_t pid);\n\tDbPid *removePid(pid_t pid);\n\n\tvoid dbgprint();\n\tvoid dbgprintcycle();\n\t\t\nprivate:\n\tDb();\n\tDb(Db const&);\n\tvoid operator=(Db const&);\n\nprivate:\n\tint cycle_;\n\tint g1h_cycle_;\n\tint g1h_cycle_delta_;\n\tint g12h_cycle_;\n\tint g12h_cycle_delta_;\n\tDbPid *pidlist_;\n};\n\n\n#endif\n"
  },
  {
    "path": "src/fstats/dbpid.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include \"dbpid.h\"\n\nDbPid::DbPid(pid_t pid): next_(0), pid_(pid), cmd_(0), netnamespace_(false), netnone_(false), uid_(0), configured_(false) {\n}\n\nDbPid::~DbPid() {\n\tif (cmd_)\n\t\tdelete cmd_;\n\n\tif (next_)\n\t\tdelete next_;\n}\n\nvoid DbPid::setCmd(const char *cmd) {\n\tif (cmd == 0) {\n\t\tif (cmd_)\n\t\t\tdelete cmd_;\n\t\tcmd_ = 0;\n\t}\n\telse {\n\t\tif (cmd_) {\n\t\t\tif (strcmp(cmd_, cmd)) {\n\t\t\t\tdelete cmd_;\n\t\t\t\tcmd_ = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (!cmd_) {\n\t\t\tcmd_ = new char[strlen(cmd) + 1];\n\t\t\tstrcpy(cmd_, cmd);\n\t\t}\n\t}\n}\n\nvoid DbPid::add(DbPid *dbpid) {\n\tassert(dbpid);\n\tif (!next_) {\n\t\tnext_ = dbpid;\n\t\treturn;\n\t}\n\n\tnext_->add(dbpid);\n}\n\nvoid DbPid::remove(DbPid *dbpid) {\n\tassert(dbpid);\n\tif (next_ == dbpid) {\n\t\tnext_ = dbpid->next_;\n\t\treturn;\n\t}\n\n\tif (next_)\n\t\tnext_->remove(dbpid);\n}\n\nDbPid *DbPid::find(pid_t pid) {\n\tif (pid_ == pid) {\n\t\treturn this;\n\t}\n\n\tif (next_) {\n\t\treturn next_->find(pid);\n\t}\n\n\treturn 0;\n}\n\nvoid DbPid::dbgprint() {\n\tprintf(\"***\\n\");\n\tprintf(\"*** PID %d, %s\\n\", pid_, cmd_);\n\tprintf(\"***\\n\");\n\n\tfor (int i = 0; i < MAXCYCLE; i++)\n\t\tdata_1min_[i].dbgprint(i);\n\n\tif (next_)\n\t\tnext_->dbgprint();\n}\n\n\n"
  },
  {
    "path": "src/fstats/dbpid.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef DBPID_H\n#define DBPID_H\n#include <sys/types.h>\n#include <unistd.h>\n#include \"fstats.h\"\n#include \"dbstorage.h\"\n\nclass DbPid {\npublic:\n\tstatic const int MAXCYCLE = 60;\n\tstatic const int G1HCYCLE_DELTA = 60;\t// transition from 1min to 1h\n\tstatic const int G12HCYCLE_DELTA = 12;\t// transition from 1h to 12h\n\tDbStorage data_1min_[MAXCYCLE];\n\tDbStorage data_1h_[MAXCYCLE];\n\tDbStorage data_12h_[MAXCYCLE];\n\n\tDbPid(pid_t pid);\n\t~DbPid();\n\tvoid setCmd(const char *cmd);\n\tconst char *getCmd() {\n\t\treturn cmd_;\n\t}\n\n\tvoid add(DbPid *dbpid);\n\tvoid remove(DbPid *dbpid);\n\tDbPid *find(pid_t pid);\n\tvoid dbgprint();\n\tDbPid *getNext() {\n\t\treturn next_;\n\t}\n\tvoid resetNext() {\n\t\tnext_ = 0;\n\t}\n\tpid_t getPid() {\n\t\treturn pid_;\n\t}\n\tbool netNamespace() {\n\t\treturn netnamespace_;\n\t}\n\tvoid setNetNamespace(bool val) {\n\t\tnetnamespace_ = val;\n\t}\n\tbool netNone() {\n\t\treturn netnone_;\n\t}\n\tvoid setNetNone(bool val) {\n\t\tnetnone_ = val;\n\t}\n\tuid_t getUid() {\n\t\treturn uid_;\n\t}\n\tvoid setUid(uid_t val) {\n\t\tuid_ = val;\n\t}\n\n\tbool isConfigured() {\n\t\treturn configured_;\n\t}\n\n\tvoid setConfigured() {\n\t\tconfigured_ = true;\n\t}\n\nprivate:\n\tDbPid *next_;\n\tpid_t pid_;\n\tchar *cmd_;\n\tbool netnamespace_;\n\tbool netnone_;\n\tuid_t uid_;\n\tbool configured_;\n};\n\n#endif\n"
  },
  {
    "path": "src/fstats/dbstorage.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef DBSTORAGE_H\n#define DBSTORAGE_H\n#include <stdio.h>\n#include <assert.h>\n\nstruct DbStorage {\n\tfloat cpu_;\n\tfloat rss_;\n\tfloat shared_;\n\tfloat rx_;\n\tfloat tx_;\n\t\n\tDbStorage(): cpu_(0), rss_(0), shared_(0), rx_(0), tx_(0) {}\n\t\n\tDbStorage& operator=(const DbStorage& val) {\n\t\tcpu_ = val.cpu_;\n\t\trss_ = val.rss_;\n\t\tshared_ = val.shared_;\n\t\trx_ = val.rx_;\n\t\ttx_ = val.tx_;\n\t\t\n\t\treturn *this;\n\t}\n\t\n\tDbStorage& operator+=(const DbStorage& val) {\n\t\tcpu_ += val.cpu_;\n\t\trss_ += val.rss_;\n\t\tshared_ += val.shared_;\n\t\trx_ += val.rx_;\n\t\ttx_ += val.tx_;\n\t\t\n\t\treturn *this;\n\t}\n\n\tDbStorage& operator/=(int val) {\n\t\tcpu_ /= val;\n\t\trss_ /= val;\n\t\tshared_ /= val;\n\t\trx_ /= val;\n\t\ttx_ /= val;\n\t\t\n\t\treturn *this;\n\t}\n\n\tvoid dbgprint(int cycle) {\n\t\tprintf(\"%d: %.2f, %.2f, %.2f, %.2f, %.2f\\n\",\n\t\t\tcycle, cpu_, rss_, shared_, rx_, tx_);\n\t}\n\t\n\tfloat get(int id) {\n\t\tswitch (id) {\n\t\t\tcase 0:\n\t\t\t\treturn cpu_;\n\t\t\tcase 1:\n\t\t\t\treturn rss_ + shared_;\n\t\t\tcase 2:\n\t\t\t\treturn rx_;\n\t\t\tcase 3:\n\t\t\t\treturn tx_;\n\t\t\tdefault:\n\t\t\t\tassert(0);\n\t\t}\n\n\t\treturn 0;\n\t}\n}; \n\n#endif\n"
  },
  {
    "path": "src/fstats/fstats.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef FSTATS_H\n#define FSTATS_H\n#include \"../common/common.h\"\n\ntypedef enum {\n\tGRAPH_1MIN = 0,\n\tGRAPH_1H,\n\tGRAPH_12H\n} GraphType;\n#define SYSTEM_PID 1\n\nextern int arg_debug;\nextern int svg_not_found;\n\n// config.cpp\nvoid config_read_screen_size(int *x, int *y);\nvoid config_write_screen_size(int x, int y);\n\n#endif\n"
  },
  {
    "path": "src/fstats/fstats.pro",
    "content": "QMAKE_CXXFLAGS += $$(CXXFLAGS) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security\nQMAKE_CFLAGS += $$(CFLAGS) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security\nQMAKE_LFLAGS += $$(LDFLAGS) -Wl,-z,relro -Wl,-z,now\nQMAKE_LIBS += $$(LIBS) -lrt\nQT += widgets\n HEADERS       = ../common/utils.h ../common/pid.h ../common/common.h \\\n \t\t  pid_thread.h db.h dbstorage.h dbpid.h stats_dialog.h graph.h fstats.h\n SOURCES       = main.cpp \\\n                  ../common/pid.cpp \\\n                  ../common/utils.cpp \\\n                 stats_dialog.cpp \\\n                pid_thread.cpp \\\n                db.cpp \\\n                dbpid.cpp \\\n                 graph.cpp \\\n                  config.cpp\nRESOURCES = fstats.qrc\nTARGET=../../build/fstats\n"
  },
  {
    "path": "src/fstats/fstats.qrc",
    "content": "<!DOCTYPE RCC><RCC version=\"1.0\">\n<qresource prefix=\"/\">\n   <file>resources/fstats.png</file>\n   <file>resources/fstats-minimal.png</file>\n </qresource>\n</RCC>\n"
  },
  {
    "path": "src/fstats/graph.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include <QtGui>\n#include <QUrl>\n#include \"graph.h\"\n#include \"dbpid.h\"\n#include \"db.h\"\n\nstatic QByteArray byteArray[4];\nstatic const char *id_label[4] = {\n\t\"CPU (%)\",\n\t\"Memory (KiB)\",\n\t\"RX (KB/s)\",\n\t\"TX (KB/s)\"\n};\n\nQString graph(int id, DbPid *dbpid, int cycle, GraphType gt) {\n\tassert(id < 4);\n\tassert(dbpid);\n\n\t// adjust cycle for 1H\n\tif (gt == GRAPH_1H)\n\t\tcycle =  Db::instance().getG1HCycle();\n\telse if (gt == GRAPH_12H)\n\t\tcycle =  Db::instance().getG12HCycle();\n\n\tassert(cycle < DbPid::MAXCYCLE);\n\tint maxcycle = DbPid::MAXCYCLE;\n\tint i;\n\tint j;\n\n\t// set pixmap\n#define TOPMARGIN 20\n#define RIGHTMARGIN 60\n\tQPixmap *pixmap = new QPixmap((maxcycle - 1) * 4 + RIGHTMARGIN, TOPMARGIN + 100 + 30);\n\tQPainter *paint = new QPainter(pixmap);\n\tpaint->fillRect(0, 0, (maxcycle - 1) * 4 + 100, TOPMARGIN + 100 + 30, Qt::white);\n\tpaint->setPen(Qt::black);\n\tpaint->drawRect(0, TOPMARGIN, (maxcycle - 1) * 4, 100);\n\tpaint->setPen(QColor(80, 80, 80, 128));\n\tpaint->drawLine(0, TOPMARGIN + 25, (maxcycle - 1) * 4, TOPMARGIN + 25);\n\tpaint->drawLine(0, TOPMARGIN + 50, (maxcycle - 1) * 4, TOPMARGIN + 50);\n\tpaint->drawLine(0, TOPMARGIN + 75, (maxcycle - 1) * 4, TOPMARGIN + 75);\n\tpaint->drawLine((maxcycle - 1) * 1, TOPMARGIN, (maxcycle - 1) * 1, TOPMARGIN + 100);\n\tpaint->drawLine((maxcycle - 1) * 2, TOPMARGIN, (maxcycle - 1) * 2, TOPMARGIN + 100);\n\tpaint->drawLine((maxcycle - 1) * 3, TOPMARGIN, (maxcycle - 1) * 3, TOPMARGIN + 100);\n\n\t// extract maximum value\n\tfloat maxval = 0;\n\tfor (i = 0; i < maxcycle; i++) {\n\t\tfloat val;\n\t\tif (gt == GRAPH_1MIN)\n\t\t\tval  = dbpid->data_1min_[i].get(id);\n\t\telse if (gt == GRAPH_1H)\n\t\t\tval  = dbpid->data_1h_[i].get(id);\n\t\telse if (gt == GRAPH_12H)\n\t\t\tval  = dbpid->data_12h_[i].get(id);\n\t\telse\n\t\t\tassert(0);\n\n\t\tif (val > maxval)\n\t\t\tmaxval = val;\n\t}\n\n\t// adjust maxval\n\tmaxval = qCeil(maxval);\n\tif (maxval < 2)\n\t\tmaxval = 2;\n\telse if (maxval < 5)\n\t\tmaxval = 5;\n\telse if (maxval < 10)\n\t\tmaxval = 10;\n\telse if (maxval < 20)\n\t\tmaxval = 20;\n\telse if (maxval < 50)\n\t\tmaxval = 50;\n\telse if (maxval < 100)\n\t\tmaxval = 100;\n\telse if (maxval < 200)\n\t\tmaxval = 200;\n\telse if (maxval < 500)\n\t\tmaxval = 500;\n\telse if (maxval < 1000)\n\t\tmaxval = 1000;\n\telse if (maxval < 2000)\n\t\tmaxval = 2000;\n\telse if (maxval < 5000)\n\t\tmaxval = 5000;\n\telse if (maxval < 10000)\n\t\tmaxval = 10000;\n\telse if (maxval < 20000)\n\t\tmaxval = 20000;\n\telse if (maxval < 50000)\n\t\tmaxval = 50000;\n\telse if (maxval < 100000)\n\t\tmaxval = 100000;\n\telse if (maxval < 200000)\n\t\tmaxval = 200000;\n\telse if (maxval < 500000)\n\t\tmaxval = 500000;\n\telse if (maxval < 1000000)\n\t\tmaxval = 1000000;\n\telse if (maxval < 2000000)\n\t\tmaxval = 2000000;\n\n\tpaint->setPen(Qt::red);\n\tfor (i = 0, j = cycle + 1; i < maxcycle - 1; i++) {\n\t\tfloat y1;\n\t\tif (gt == GRAPH_1MIN)\n\t\t\ty1 = dbpid->data_1min_[j].get(id);\n\t\telse if (gt == GRAPH_1H)\n\t\t\ty1 = dbpid->data_1h_[j].get(id);\n\t\telse if (gt == GRAPH_12H)\n\t\t\ty1 = dbpid->data_12h_[j].get(id);\n\t\telse\n\t\t\tassert(0);\n\n\t\ty1 = (y1 / maxval) * 100;\n\t\ty1 = 100 - y1 + TOPMARGIN;\n\t\tj++;\n\t\tif (j >= maxcycle)\n\t\t\tj = 0;\n\n\t\tfloat y2;\n\t\tif (gt == GRAPH_1MIN)\n\t\t\ty2 = dbpid->data_1min_[j].get(id);\n\t\telse if (gt == GRAPH_1H)\n\t\t\ty2 = dbpid->data_1h_[j].get(id);\n\t\telse if (gt == GRAPH_12H)\n\t\t\ty2 = dbpid->data_12h_[j].get(id);\n\t\telse\n\t\t\tassert(0);\n\n\t\ty2 = (y2 / maxval) * 100;\n\t\ty2 = 100 - y2 + TOPMARGIN;\n\t\tpaint->drawLine(i * 4, (int) y1, (i + 1) * 4, (int) y2);\n\t}\n\n\t// axis\n\tpaint->setPen(Qt::black);\n\tQString ymax = QString::number((int) maxval);\n\tpaint->drawText((maxcycle - 1) * 4 + 3, TOPMARGIN + 3, QString::number((int) maxval));\n\tif (qCeil(maxval / 2) == maxval / 2)\n\t\tpaint->drawText((maxcycle - 1) * 4 + 3, TOPMARGIN + 50 + 3, QString::number((int) maxval / 2));\n\telse\n\t\tpaint->drawText((maxcycle - 1) * 4 + 3, TOPMARGIN + 50 + 3, QString::number(maxval / 2, 'f', 1));\n\tpaint->drawText((maxcycle - 1) * 4 + 3, TOPMARGIN + 100 + 3, QString(\"0\"));\n\tif (gt == GRAPH_12H)\n\t\tpaint->drawText(0 + 2, TOPMARGIN + 100 + 15, QString(\"(hours)\"));\n\tif (gt == GRAPH_1H)\n\t\tpaint->drawText(0 + 2, TOPMARGIN + 100 + 15, QString(\"(minutes)\"));\n\telse\n\t\tpaint->drawText(0 + 2, TOPMARGIN + 100 + 15, QString(\"(seconds)\"));\n\tif (gt == GRAPH_1MIN) {\n\t\tpaint->drawText((maxcycle - 1) * 2 - 5, TOPMARGIN + 100 + 15, QString(\"-30\"));\n\t\tpaint->drawText((maxcycle - 1) * 3 - 5, TOPMARGIN + 100 + 15, QString(\"-15\"));\n\t}\n\telse if (gt == GRAPH_1H) {\n\t\tpaint->drawText((maxcycle - 1) * 2 - 5, TOPMARGIN + 100 + 15, QString(\"-30\"));\n\t\tpaint->drawText((maxcycle - 1) * 3 - 5, TOPMARGIN + 100 + 15, QString(\"-15\"));\n\t}\n\telse if (gt == GRAPH_12H) {\n\t\tpaint->drawText((maxcycle - 1) * 2 - 5, TOPMARGIN + 100 + 15, QString(\"-6\"));\n\t\tpaint->drawText((maxcycle - 1) * 3 - 5, TOPMARGIN + 100 + 15, QString(\"-3\"));\n\t}\n\telse\n\t\tassert(0);\n\n\n\t// title\n\tpaint->setPen(Qt::black);\n\tpaint->drawText(0 + 2, TOPMARGIN - 2, QString(id_label[id]));\n\n\t// generate image\n\tQBuffer buffer(&byteArray[id]);\n\tpixmap->save(&buffer, \"PNG\");\n//\tQString url = QString(\"<img src=\\\":resources/fjail.png\\\"  />\");\n\tQString url = QString(\"<img src=\\\"data:image/png;base64,\") + byteArray[id].toBase64() + \"\\\"  />\";\n\tdelete paint;\n\tdelete pixmap;\n\treturn url;\n}\n"
  },
  {
    "path": "src/fstats/graph.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef GRAPH_H\n#define GRAPH_H\n#include <QString>\n#include \"fstats.h\"\n\nclass DbPid;\nQString graph(int id, DbPid *dbpid, int cycle, GraphType gt);\n\n\n#endif\n"
  },
  {
    "path": "src/fstats/main.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include <QApplication>\n#include <QMenu>\n#include <QSystemTrayIcon>\n#include <QLibraryInfo>\n\n#include \"../common/utils.h\"\n#include \"../../firetools_config.h\"\n#include \"stats_dialog.h\"\n\nint arg_debug = 0;\nint svg_not_found = 0;\n\n\nstatic void usage() {\n\tprintf(\"fstats - Stats & tools for Firetools project\\n\\n\");\n\tprintf(\"Usage: fstats [options]\\n\\n\");\n\tprintf(\"Options:\\n\");\n\tprintf(\"\\t--debug - debug mode\\n\\n\");\n\tprintf(\"\\t--help - this help screen\\n\\n\");\n\tprintf(\"\\t--version - print software version and exit\\n\\n\");\n}\n\nint main(int argc, char *argv[]) {\n\t// parse arguments\n\tfor (int i = 1; i < argc; i++) {\n\t\tif (strcmp(argv[i], \"--debug\") == 0)\n\t\t\targ_debug = 1;\n\t\telse if (strcmp(argv[i], \"--help\") == 0 || strcmp(argv[i], \"-?\") == 0) {\n\t\t\tusage();\n\t\t\treturn 0;\n\t\t}\n\t\telse if (strcmp(argv[i], \"--version\") == 0) {\n\t\t\tprintf(\"fstats version \" PACKAGE_VERSION \"\\n\");\n\t\t\treturn 0;\n\t\t}\n\t\telse {\n\t\t\tfprintf(stderr, \"Error: invalid option\\n\");\n\t\t\tusage();\n\t\t\treturn 1;\n\t\t}\n\t}\n\n#if QT_VERSION >= 0x050000\n\tstruct stat s;\n\t// test run time dependencies - print warning and continue program\n\tQString ppath = QLibraryInfo::location(QLibraryInfo::PluginsPath);\n\tppath += \"/imageformats/libqsvg.so\";\n\tif (stat(ppath.toUtf8().constData(), &s) == -1) {\n\t\tfprintf(stderr, \"Warning: QT5 SVG support not installed, please install libqt5svg5 package\\n\");\n\t\tsvg_not_found = 1;\n\t}\n#endif\n\n\t// test run time dependencies - exit\n\tif (!which(\"firejail\")) {\n\t\tfprintf(stderr, \"Error: firejail package not found, please install it!\\n\");\n\t\texit(1);\n\t}\n\n\t// create firetools config directory if it doesn't exist\n\tcreate_config_directory();\n\n\t// initialize resources\n\tQ_INIT_RESOURCE(fstats);\n\n\tQApplication app(argc, argv);\n\tStatsDialog sd;\n\tsd.show();\n\n\t// Configure system tray\n\tQSystemTrayIcon icon(QIcon(\":resources/fstats-minimal.png\"));\n\ticon.show();\n\ticon.setToolTip(\"Firetools (click to open)\");\n\tQMenu *trayIconMenu = new QMenu(&sd);\n\ttrayIconMenu->addAction(sd.minimizeAction);\n\ttrayIconMenu->addAction(sd.restoreAction);\n\ttrayIconMenu->addSeparator();\n\ttrayIconMenu->addAction(sd.quitAction);\n\ticon.setContextMenu(trayIconMenu);\n\ticon.connect(&icon, SIGNAL(activated(QSystemTrayIcon: :ActivationReason)), &sd, SLOT(trayActivated(QSystemTrayIcon: :ActivationReason)));\n\n\n\n\t// direct all error to /dev/null to work around this qt bug:\n\t//      https://bugreports.qt.io/browse/QTBUG-43270\n\tFILE *rv = NULL;\n\tif (!arg_debug) {\n\t\trv = freopen( \"/dev/null\", \"w\", stderr );\n\t\t(void) rv;\n\t}\n\n\t// start application\n\tint tmp = app.exec();\n\t(void) tmp;\n\n\tif (rv)\n\t\tfclose(rv);\n}\n\n"
  },
  {
    "path": "src/fstats/pid_thread.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include <QtGui>\n#include <QElapsedTimer>\n\n#include \"pid_thread.h\"\n#include \"../common/pid.h\"\n#include \"db.h\"\n#include \"../common/utils.h\"\n\nbool data_ready = false;\n\n\nPidThread::PidThread(): ending_(false) {\n\tstart();\n}\n\n// todo: implement cleanup\nPidThread::~PidThread() {\n\tending_ = true;\n}\n\n// store process data in database\nstatic void store(int pid, int interval, int clocktick) {\n\tassert(pid < max_pids);\n\tDbPid *dbpid = Db::instance().findPid(pid);\n\n\tif (!dbpid) {\n\t\tdbpid = Db::instance().newPid(pid);\n\t}\n\tassert(dbpid);\n\n\tint cycle = Db::instance().getCycle();\n\n\t// store the data in database\n\tDbStorage *st = &dbpid->data_1min_[cycle];\n\tst->cpu_ = (float) ((pids_data[pid].utime + pids_data[pid].stime) * 100) / (interval * clocktick);\n\tst->rss_ = pids_data[pid].rss;\n\tst->shared_ =  pids_data[pid].shared;\n\tst->rx_ = ((float) pids_data[pid].rx) /( interval * 1000);\n\tst->tx_ = ((float) pids_data[pid].tx) /( interval * 1000);\n\n\tif (!dbpid->isConfigured()) {\n\t\tif (arg_debug)\n\t\t\tprintf(\"configuring dbpid for sandbox %d\\n\", pid);\n\n\t\t// user id\n\t\tdbpid->setUid(pids_data[pid].uid);\n\n\t\t// check network namespace\n\t\tchar *name;\n\t\tif (asprintf(&name, \"/run/firejail/network/%d-netmap\", pid) == -1)\n\t\t\terrExit(\"asprintf\");\n\t\tstruct stat s;\n\t\tif (stat(name, &s) == 0)\n\t\t\tdbpid->setNetNamespace(true);\n\t\telse\n\t\t\tdbpid->setNetNamespace(false);\n\t\tfree(name);\n\n\t\t// command line\n\t\tchar *cmd =  pid_proc_cmdline(pid);;\n\t\tdbpid->setCmd(cmd);\n\t\tif (strstr(cmd, \"--net=none\"))\n\t\t\tdbpid->setNetNone(true);\n\t\telse {\n\t\t\t// detect --net=none for symlinks in /usr/local/bin\n\t\t\tint child = pid_find_child(pid);\n\t\t\tif (child != -1) {\n\t\t\t\tchar *fname;\n\t\t\t\tif (asprintf(&fname, \"/proc/%d/net/dev\", child) == -1)\n\t\t\t\t\terrExit(\"asprintf\");\n\t\t\t\tFILE *fp = fopen(fname, \"r\");\n\t\t\t\tif (fp) {\n\t\t\t\t\tchar buf[4096];\n\t\t\t\t\tint cnt = 0;\n\t\t\t\t\twhile (fgets(buf, 4096, fp))\n\t\t\t\t\t\tcnt++;\n\t\t\t\t\tfclose(fp);\n\t\t\t\t\tif (cnt <= 3)\n\t\t\t\t\t\tdbpid->setNetNone(true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfree(cmd);\n\t\tdbpid->setConfigured();\n\t}\n}\n\n// remove closed processes from database\nstatic void clear() {\n\tDbPid *dbpid = Db::instance().firstPid();\n\n\twhile (dbpid) {\n\t\tDbPid *next = dbpid->getNext();\n\t\tpid_t pid = dbpid->getPid();\n\t\tif (pids[pid].level != 1 && pid != 1) {\n\t\t\t// remove database entry\n\t\t\tDbPid *dbentry = Db::instance().removePid(pid);\n\t\t\tif (dbentry)\n\t\t\t\tdelete dbentry;\n\t\t}\n\t\tdbpid = next;\n\t}\n}\n\nvoid PidThread::run() {\n\t// memory page size clicks per second\n\tint pgsz = getpagesize();\n\tint clocktick = sysconf(_SC_CLK_TCK);\n\tbool first = true;\n\n\n\twhile (1) {\n\t\tif (ending_)\n\t\t\tbreak;\n\n\t\t// initialize process table - start with an empty proc table\n\t\tpid_read(0);\n\n\t\t// start cpu and network measurements\n\t\tunsigned utime = 0;\n\t\tunsigned stime = 0;\n\t\tunsigned long long rx;\n\t\tunsigned long long tx;\n\t\tfor (int i = pids_first; i  <= pids_last; i++) {\n\t\t\tif (pids[i].level == 1) {\n\t\t\t\t// cpu\n\t\t\t\tpid_get_cpu_sandbox(i, &utime, &stime);\n\t\t\t\tpids_data[i].utime = utime;\n\t\t\t\tpids_data[i].stime = stime;\n\n\t\t\t\t// network\n\t\t\t\tpid_get_netstats_sandbox(i, &rx, &tx);\n\t\t\t\tpids_data[i].rx = rx;\n\t\t\t\tpids_data[i].tx = tx;\n\t\t\t}\n\t\t}\n\t\t// system network\n\t\tpid_get_netstats_sandbox(SYSTEM_PID, &rx, &tx);\n\t\tpids_data[SYSTEM_PID].rx = rx;\n\t\tpids_data[SYSTEM_PID].tx = tx;\n\n\t\tif (!first) {\n\t\t\t// sleep 1 second\n\t\t\tmsleep(500);\n\t\t\tdata_ready = false;\n\t\t\tmsleep(500);\n\t\t}\n\t\telse\n\t\t\tfirst = false;\n\n\t\t// start a new database cycle\n\t\tDb::instance().newCycle();\n\n\t\ttimetrace_start();\n\t\t// read the cpu time again, memory\n\t\tfor (int i = pids_first; i  <= pids_last; i++) {\n\t\t\tif (pids[i].level == 1) {\n\t\t\t\t// cpu time\n\t\t\t\tpid_get_cpu_sandbox(i, &utime, &stime);\n\t\t\t\tif (pids_data[i].utime <= utime)\n\t\t\t\t\tpids_data[i].utime = utime - pids_data[i].utime;\n\t\t\t\telse\n\t\t\t\t\tpids_data[i].utime = 0;\n\n\t\t\t\tif (pids_data[i].stime <= stime)\n\t\t\t\t\tpids_data[i].stime = stime - pids_data[i].stime;\n\t\t\t\telse\n\t\t\t\t\tpids_data[i].stime = 0;\n\n\t\t\t\t// memory\n\t\t\t\tunsigned rss;\n\t\t\t\tunsigned shared;\n\t\t\t\tpid_get_mem_sandbox(i, &rss, &shared);\n\t\t\t\tpids_data[i].rss = rss * pgsz / 1024;\n\t\t\t\tpids_data[i].shared = shared * pgsz / 1024;\n\n\t\t\t\t// network\n\t\t\t\tDbPid *dbpid = Db::instance().findPid(i);\n\t\t\t\tif (dbpid && dbpid->isConfigured() && dbpid->netNamespace() == true) {\n\t\t\t\t\tpid_get_netstats_sandbox(i, &rx, &tx);\n\t\t\t\t\tif (rx >= pids_data[i].rx)\n\t\t\t\t\t\tpids_data[i].rx = rx - pids_data[i].rx;\n\t\t\t\t\telse\n\t\t\t\t\t\tpids_data[i].rx = 0;\n\n\t\t\t\t\tif (tx > pids_data[i].tx)\n\t\t\t\t\t\tpids_data[i].tx = tx - pids_data[i].tx;\n\t\t\t\t\telse\n\t\t\t\t\t\tpids_data[i].tx = 0;\n\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tpids_data[i].rx = 0;\n\t\t\t\t\tpids_data[i].tx = 0;\n\t\t\t\t}\n\n\t\t\t\tstore(i, 1, clocktick);\n\t\t\t}\n\t\t}\n\n\t\t// store system namespace network data\n\t\tpid_get_netstats_sandbox(SYSTEM_PID, &rx, &tx);\n\n\t\tif (rx >= pids_data[SYSTEM_PID].rx)\n\t\t\tpids_data[SYSTEM_PID].rx = rx - pids_data[SYSTEM_PID].rx;\n\t\telse\n\t\t\tpids_data[SYSTEM_PID].rx = 0;\n\n\t\tif (tx > pids_data[SYSTEM_PID].tx)\n\t\t\tpids_data[SYSTEM_PID].tx = tx - pids_data[SYSTEM_PID].tx;\n\t\telse\n\t\t\tpids_data[SYSTEM_PID].tx = 0;\n\t\tstore(SYSTEM_PID, 1, clocktick);\n\n\t\tfloat delta = timetrace_end();\n\t\tif (arg_debug)\n\t\t\tprintf(\"stats read %.02f ms, pid from %d to %d\\n\", delta, pids_first, pids_last);\n\t\t// remove closed process entries from database\n\t\tclear();\n\n\t\t// 4min to 1h transfer\n\t\tif (Db::instance().getG1HCycleDelta() == 0) {\n\t\t\t// for each pid\n\t\t\tDbPid *dbpid = Db::instance().firstPid();\n\t\t\twhile (dbpid) {\n\t\t\t\tint cycle = Db::instance().getCycle();\n\t\t\t\tint g1hcycle = Db::instance().getG1HCycle();\n\n\t\t\t\tDbStorage result;\n\t\t\t\tfor (int i = 0; i < DbPid::G1HCYCLE_DELTA; i++) {\n\t\t\t\t\tresult += dbpid->data_1min_[cycle];\n\t\t\t\t\tif (--cycle < 0)\n\t\t\t\t\t\tcycle = DbPid::MAXCYCLE - 1;\n\t\t\t\t}\n\t\t\t\tresult /= DbPid::G1HCYCLE_DELTA;\n\t\t\t\tdbpid->data_1h_[g1hcycle] = result;\n\n\n\t\t\t\tif (Db::instance().getG12HCycleDelta() == 0) {\n\t\t\t\t\tint g12hcycle = Db::instance().getG12HCycle();\n\t\t\t\t\tg1hcycle = Db::instance().getG1HCycle();\n\n\t\t\t\t\tDbStorage result2;\n\t\t\t\t\tfor (int i = 0; i < DbPid::G12HCYCLE_DELTA; i++) {\n\t\t\t\t\t\tresult2 += dbpid->data_1h_[g1hcycle];\n\t\t\t\t\t\tif (--g1hcycle < 0)\n\t\t\t\t\t\t\tg1hcycle = DbPid::MAXCYCLE - 1;\n\t\t\t\t\t}\n\t\t\t\t\tresult2 /= DbPid::G12HCYCLE_DELTA;\n\t\t\t\t\tdbpid->data_12h_[g12hcycle] = result2;\n\t\t\t\t}\n\n\n\t\t\t\tdbpid = dbpid->getNext();\n\t\t\t}\n\t\t}\n\n\n\t\t//Db::instance().dbgprint();\n\t\temit cycleReady();\n\t\tdata_ready = true;\n\n\t}\n}\n"
  },
  {
    "path": "src/fstats/pid_thread.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef PID_THREAD_H\n#define PID_THREAD_H\n#include <QImage>\n#include <QMutex>\n#include <QQueue>\n#include <QThread>\n#include <QWaitCondition>\n#include <QStringList>\n#include \"fstats.h\"\n\nclass PidThread : public QThread\n{\nQ_OBJECT\n\npublic:\n\tPidThread();\n\t~PidThread();\n\nsignals:\n\tvoid cycleReady();\n\nprotected:\n\tvoid run();\nprivate:\n\tbool ending_;\t\t\n};\n\n#endif\n"
  },
  {
    "path": "src/fstats/stats_dialog.cpp",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#include <QtGlobal>\n\n#if QT_VERSION >= 0x050000\n\t#include <QtWidgets>\n#else\n\t#include <QtGui>\n#endif\n\n#include <QUrl>\n#include <QProcess>\n#include <sys/types.h>\n#include <sys/utsname.h>\n#include <sys/mman.h>\n#include <sys/stat.h>        /* For mode constants */\n#include <fcntl.h>           /* For O_* constants */\n#include <unistd.h>\n#include <dirent.h>\n\n#include \"stats_dialog.h\"\n#include \"db.h\"\n#include \"graph.h\"\n#include \"../common/common.h\"\n#include \"../common/utils.h\"\n#include \"../common/pid.h\"\n#include \"../../firetools_config.h\"\n#include \"../../firetools_config_extras.h\"\n#include \"pid_thread.h\"\n#include \"fstats.h\"\nextern bool data_ready;\n\nstatic QString getName(pid_t pid);\nstatic QString getProfile(pid_t pid);\nstatic bool userNamespace(pid_t pid);\nstatic int getX11Display(pid_t pid);\n\n\n// from fdns:procs.c - void procs_list(void) {\n// returns malloc memory\nstatic char *find_fdns_shm_file_name(void) {\n\tint procs_addr_default = 0;\n\tint procs_addr_loopback = 0;\n\tchar *procs_addr_real = NULL;\n\n\tDIR *dir;\n\tif (!(dir = opendir(\"/run/fdns\"))) {\n\t\t// sleep 2 seconds and try again\n\t\tsleep(2);\n\t\tif (!(dir = opendir(\"/run/fdns\")))\n\t\t\treturn 0;\n\t}\n\n\tstruct dirent *entry;\n\tint procs_addr_flag = 0;\n\twhile ((entry = readdir(dir))) {\n\t\tif (*entry->d_name == '.')\n\t\t\tcontinue;\n\n\t\tchar *fname;\n\t\tif (asprintf(&fname, \"/proc/%s\", entry->d_name) == -1)\n\t\t\terrExit(\"asprintf\");\n\t\tif (access(fname, R_OK) == 0) {\n\t\t\tchar *runfname;\n\t\t\tif (asprintf(&runfname, \"/run/fdns/%s\", entry->d_name) == -1)\n\t\t\t\terrExit(\"asprintf\");\n\t\t\tif (arg_debug)\n\t\t\t\tprintf(\"pid %s,\", entry->d_name);\n\t\t\tFILE *fp = fopen(runfname, \"r\");\n\t\t\tif (fp) {\n\t\t\t\tstatic const int MAXBUF = 1024;\n\t\t\t\tchar buf[MAXBUF];\n\t\t\t\tif (fgets(buf, MAXBUF, fp)) {\n\t\t\t\t\tchar *ptr = strchr(buf, '\\n');\n\t\t\t\t\tif (ptr)\n\t\t\t\t\t\t*ptr = '\\0';\n\n\t\t\t\t\tif (!procs_addr_flag) {\n\t\t\t\t\t\tif (strcmp(buf, \"127.1.1.1\") == 0) {\n\t\t\t\t\t\t\tprocs_addr_default = 1;\n\t\t\t\t\t\t\tprocs_addr_flag = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (strcmp(buf, \"127.0.0.1\") == 0) {\n\t\t\t\t\t\t\tprocs_addr_loopback = 1;\n\t\t\t\t\t\t\tprocs_addr_flag = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (!procs_addr_real) {\n\t\t\t\t\t\t\tprocs_addr_real = strdup(buf);\n\t\t\t\t\t\t\tif (!procs_addr_real)\n\t\t\t\t\t\t\t\terrExit(\"strdup\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tprintf(\"\\n\");\n\t\t\tfclose(fp);\n\t\t\tfree(runfname);\n\t\t}\n\t\tfree(fname);\n\t}\n\tclosedir(dir);\n\n\tchar *rv = 0;\n\tif (procs_addr_default) {\n\t\trv = strdup(\"/dev/shm/fdns-stats-127.1.1.1\");\n\t\tif (!rv)\n\t\t\terrExit(\"strdup\");\n\t}\n\telse if (procs_addr_loopback) {\n\t\trv = strdup(\"/dev/shm/fdns-stats-127.0.0.1\");\n\t\tif (!rv)\n\t\t\terrExit(\"strdup\");\n\t}\n\telse if (procs_addr_real) {\n\t\tif (asprintf(&rv, \"/dev/shm/fdns-stats-%s\", procs_addr_real) == -1)\n\t\t\terrExit(\"asprintf\");\n\t}\n\n\tif (procs_addr_real)\n\t\tfree(procs_addr_real);\n\n\treturn rv;\n}\n\n\n\nStatsDialog::StatsDialog(): QDialog(), fdns_report_(0), fdns_seq_(0), fdns_fd_(0), fdns_first_run_(true),\n\t\tmode_(MODE_TOP), pid_(0), uid_(0), lts_(false),\n\tpid_initialized_(false), pid_seccomp_(false), pid_caps_(QString(\"\")), pid_noroot_(false),\n\tpid_cpu_cores_(QString(\"\")), pid_protocol_(QString(\"\")), pid_name_(QString(\"\")),\n\tprofile_(QString(\"\")), pid_x11_(0), fdns_dump_(\"\"),\n\thave_join_(true), caps_cnt_(64), graph_type_(GRAPH_1MIN), net_none_(false), shm_file_name_(0) {\n\n\t// clean storage area\n\tcleanStorage();\n\n\t// detect LTS version\n\tchar *str = run_program(\"firejail --version\");\n\tif (str && strstr(str, \"LTS\"))\n\t\tlts_ = true;\n\n\tprocView_ = new QTextBrowser;\n\tprocView_->setOpenLinks(false);\n\tprocView_->setOpenExternalLinks(false);\n\tprocView_->setText(\"accumulating data...\");\n\n\tconnect(procView_,  SIGNAL(anchorClicked(const QUrl &)), this, SLOT(anchorClicked(const QUrl &)));\n\n\tQGridLayout *layout = new QGridLayout;\n\tlayout->addWidget(procView_, 0, 0);\n\tsetLayout(layout);\n\n\t// set screen size and title\n\tint x;\n\tint y;\n\tconfig_read_screen_size(&x, &y);\n \tresize(x, y);\n\tsetWindowTitle(tr(\"Firetools Stats\"));\n\n\t// detect if joining a sandbox is possible on this system\n\tstruct utsname u;\n\tint rv = uname(&u);\n\tif (rv == 0) {\n\t\tint major;\n\t\tint minor;\n\t\tif (2 == sscanf(u.release, \"%d.%d\", &major, &minor)) {\n\t\t\tif (major < 3)\n\t\t\t\thave_join_ = false;\n\t\t\telse if (major == 3 && minor < 8)\n\t\t\t\thave_join_ = false;\n\t\t}\n\t}\n\n\t// detect the number of capabilities supported by the current kernel\n\tstr = run_program(\"firejail --debug-caps\");\n\tif (!str)\n\t\treturn;\n\tint val;\n\tif (sscanf(str, \"Your kernel supports %d\", &val) == 1 && val <= 64) {\n\t\tif (arg_debug)\n\t\t\tprintf(\"%d capabilities supported by the kernel\\n\", val);\n\t\tcaps_cnt_ = val;\n\t}\n\n\tthread_ = new PidThread();\n\tconnect(thread_, SIGNAL(cycleReady()), this, SLOT(cycleReady()));\n\tcreateTrayActions();\n}\n\nStatsDialog::~StatsDialog() {\n\tif (fdns_fd_)\n\t\t::close(fdns_fd_);\n\tif (!isMaximized())\n\t\tconfig_write_screen_size(width(), height());\n}\n\nvoid StatsDialog::cleanStorage() {\n\tstorage_dns_ = \"\";\n\tstorage_caps_ = \"\";\n\tstorage_seccomp_ = \"\";\n\tstorage_intro_ = \"\";\n\tstorage_network_ = \"\";\n\tstorage_netfilter_ = \"\";\n}\n\n// Shutdown sequence\nvoid StatsDialog::main_quit() {\n\tprintf(\"exiting...\\n\");\n\n\tqApp->quit();\n}\n\nvoid StatsDialog::trayActivated(QSystemTrayIcon::ActivationReason reason) {\n\tif (reason == QSystemTrayIcon::Context)\n\t\treturn;\n\tif (reason == QSystemTrayIcon::DoubleClick)\n\t\treturn;\n\tif (reason == QSystemTrayIcon::MiddleClick)\n\t\treturn;\n\n\tif (isVisible())\n\t\thide();\n\telse\n\t\tshowNormal();\n}\n\nvoid StatsDialog::createTrayActions() {\n\tminimizeAction = new QAction(tr(\"Mi&nimize\"), this);\n\tconnect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));\n\n\trestoreAction = new QAction(tr(\"&Restore\"), this);\n\tconnect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));\n\n\tquitAction = new QAction(tr(\"&Quit\"), this);\n\tconnect(quitAction, SIGNAL(triggered()), this, SLOT(main_quit()));\n}\n\nQString StatsDialog::header() {\n\tQString msg;\n\tif (mode_ == MODE_TOP) {\n\t\tmsg += \"<table><tr><td width=\\\"5\\\"></td><td>\";\n\t\tmsg += \"<a href=\\\"about\\\">About</a>\";\n\t\tmsg += \"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"newsandbox\\\">Configure New Sandbox</a>\";\n\t\tmsg += \"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"fdns\\\">Firejail DNS</a>\";\n\t\tmsg += \"</td></tr></table>\";\n\t}\n\n\telse if (mode_ == MODE_FDNS) {\n\t\tmsg += \"<table><tr><td width=\\\"5\\\"></td><td>\";\n\t\tmsg += \"<a href=\\\"top\\\">Home</a>\";\n\t\tmsg += \"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"dump\\\">Proxy</a>\";\n\t\tmsg += \"</td></tr></table>\";\n\t}\n\telse if (mode_ == MODE_FDNS_DUMP) {\n\t\tmsg += \"<table><tr><td width=\\\"5\\\"></td><td>\";\n\t\tmsg += \"<a href=\\\"top\\\">Home</a>\";\n\t\tmsg += \"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"fdns\\\">Live</a>\";\n\t\tmsg += \"</td></tr></table>\";\n\t}\n\n\telse if (mode_ == MODE_PID) {\n\t\tmsg += \"<table><tr><td width=\\\"5\\\"></td><td>\";\n\t\tmsg += \"<a href=\\\"top\\\">Home</a>\";\n\t\tif (uid_ == getuid())\n\t\t\tmsg += \" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"shut\\\">Shutdown</a>\";\n\t\tif (have_join_ && uid_ == getuid())\n\t\t\tmsg += \" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"join\\\">Join</a>\";\n\t\tif (!lts_)\n\t\t\tmsg += \" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"fmgr\\\">File Manager</a>\";\n\t\tmsg += \" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"tree\\\">Process Tree</a>\";\n\t\tmsg += \" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"network\\\">Network</a>\";\n\t\tmsg += \"</td></tr></table>\";\n\t}\n\n\telse {\n\t\tmsg += \"<table><tr><td width=\\\"5\\\"></td><td>\";\n\t\tmsg += \"<a href=\\\"top\\\">Home</a>\";\n\t\tmsg += \" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"back\\\">\" + QString::number(pid_) + \"</a>\";\n\t\tif (uid_ == getuid())\n\t\t\tmsg += \" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"shut\\\">Shutdown</a>\";\n\t\tif (have_join_ && uid_ == getuid())\n\t\t\tmsg += \" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"join\\\">Join</a>\";\n\t\tif (!lts_)\n\t\t\tmsg += \" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"fmgr\\\">File Manager</a>\";\n\t\tmsg += \" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"tree\\\">Process Tree</a>\";\n\t\tmsg += \" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\\\"network\\\">Network</a>\";\n\t\tmsg += \"</td></tr></table>\";\n\t}\n\n\tmsg += \"<hr>\";\n\treturn msg;\n}\n\nvoid StatsDialog::updateTop() {\n\ttimetrace_start();\n\tQString msg = header();\n\tmsg += \"<table><tr><td width=\\\"5\\\"></td><td><b>Sandbox List</b></td></tr></table><br/>\\n\";\n\tmsg += \"<table><tr><td width=\\\"5\\\"></td><td width=\\\"60\\\">PID</td/><td width=\\\"60\\\">CPU<br/>(%)</td><td>Memory<br/>(KiB)&nbsp;&nbsp;</td><td>RX<br/>(KB/s)&nbsp;&nbsp;</td><td>TX<br/>(KB/s)&nbsp;&nbsp;</td><td>Command</td>\\n\";\n\n\tint cycle = Db::instance().getCycle();\n\tassert(cycle < DbPid::MAXCYCLE);\n\tDbPid *ptr = Db::instance().firstPid();\n\n\twhile (ptr) {\n\t\tpid_t pid = ptr->getPid();\n\t\tconst char *cmd = ptr->getCmd();\n\n\t\tif (pid != SYSTEM_PID && cmd) {\n\t\t\tif (arg_debug)\n\t\t\t\tprintf(\"pid %d, netnamespace %d, netnone %d - %s\\n\", pid, ptr->netNamespace(), ptr->netNone(), cmd);\n\t\t\tchar *str;\n\t\t\tDbStorage *st = &ptr->data_1min_[cycle];\n\t\t\tif (ptr->netNone()) {\n\t\t\t\tif (asprintf(&str, \"<tr><td></td><td><a href=\\\"%d\\\">%d</a></td><td>%.02f</td><td>%d</td><td>no network</td><td></td><td>%s</td></tr>\",\n\t\t\t\t\tpid, pid, st->cpu_, (int) (st->rss_ + st->shared_),\n\t\t\t\t\tcmd) != -1) {\n\t\t\t\t\t\tmsg += str;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (ptr->netNamespace()) {\n\t\t\t\tif (asprintf(&str, \"<tr><td></td><td><a href=\\\"%d\\\">%d</a></td><td>%.02f</td><td>%d</td><td>%.02f</td><td>%.02f</td><td>%s</td></tr>\",\n\t\t\t\t\tpid, pid, st->cpu_, (int) (st->rss_ + st->shared_),\n\t\t\t\t\tst->rx_, st->tx_, cmd) != -1) {\n\t\t\t\t\t\tmsg += str;\n\t\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tif (asprintf(&str, \"<tr><td></td><td><a href=\\\"%d\\\">%d</a></td><td>%.02f</td><td>%d</td><td>system</td><td></td><td>%s</td></tr>\",\n\t\t\t\t\tpid, pid, st->cpu_, (int) (st->rss_ + st->shared_),\n\t\t\t\t\tcmd) != -1) {\n\t\t\t\t\t\tmsg += str;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfree(str);\n\t\t}\n\n\t\tptr = ptr->getNext();\n\t}\n\n\tmsg += \"</table><br/><br/><br/>\";\n\tmsg += \"<b>System Network</b><br/>\";\n\tDbPid *dbpid = Db::instance().findPid(SYSTEM_PID);\n\tmsg += \"<table><tr><td></td><td>\"+ graph(2, dbpid, cycle, GRAPH_1MIN) + \"</td><td></td>&nbsp;&nbsp;<td>\" + graph(3, dbpid, cycle, GRAPH_1MIN) + \"</td></tr></table>\";\n\n\tprocView_->setHtml(msg);\n\tfloat delta = timetrace_end();\n\tif (arg_debug)\n\t\tprintf(\"updateTop %.02f ms\\n\", delta);\n}\n\nQString StatsDialog::printDump(int index) {\n\tQString msg = \"\";\n\tstruct tm *t = localtime(&fdns_report_->tstamp[index]);\n\tchar *s;\n\tif (asprintf(&s, \"%02d:%02d:%02d \", t->tm_hour, t->tm_min, t->tm_sec) == -1)\n\t\terrExit(\"asprintf\");\n\tif (strstr(fdns_report_->logentry[index], \"dropped\")) {\n\t\tmsg += \"<font color=\\\"red\\\">\";\n\t\tmsg += QString(s) + fdns_report_->logentry[index];\n\t\tmsg += \"</font>\";\n\t}\n\telse\n\t\tmsg += QString(s) + fdns_report_->logentry[index];\n\n\tfree(s);\n\tmsg += \"<br/>\";\n\n\treturn msg;\n}\n\nvoid StatsDialog::updateFdnsDump() {\n\tif (!fdns_dump_.isEmpty())\n\t\treturn;\n\tQString msg = header();\n\n\tif (access(shm_file_name_, R_OK)) {\n\t\tmsg += QString(\"Error: cannot open shared memory, probably fdns is not running<br/>\");\n\t\tfdns_fd_ = 0;\n\t\tprocView_->setHtml(msg);\n\t\treturn;\n\t}\n\n\tint fd = ::open(shm_file_name_, O_RDONLY);\n\tif (fd <= 0) {\n\t\tmsg +=  \"Error: cannot access Firejail DNS data\";\n\t\tprocView_->setHtml(msg);\n\t\treturn;\n\n\t}\n\n\tDnsReport report;\n\tssize_t len = ::read(fd, &report, sizeof(DnsReport));\n\tif (len != sizeof(DnsReport)) {\n\t\tmsg += \"Error: cannot access Firejail DNS data\";\n\t\tprocView_->setHtml(msg);\n\t\treturn;\n\t}\n\t::close(fd);\n\n\tQDateTime current = QDateTime::currentDateTime();\n\tmsg += \"<b>Fireail DNS report for \" + current.toString() + \"</b><br/><br/>\";\n\n\tmsg += \"<b>Stats:</b><br/>\";\n\tmsg += QString(fdns_report_->header1) + \"<br/>\";\n\tmsg += QString(fdns_report_->header2) + \"<br/><br/>\";\n\n\n\tmsg += \"<b>Resolvers:</b><br/>\";\n\tfor (int i = 0; i < fdns_report_->resolvers; i++) {\n\t\tQString str= QString(\"Resolver %1: \").arg(i);\n\t\tmsg += str;\n\t\tif (fdns_report_->encrypted[i]) {\n\t\t\tchar *s;\n\t\t\tif (asprintf(&s, \"connected to %d.%d.%d.%d<br/>\", PRINT_IP(fdns_report_->peer_ip[i])) == -1)\n\t\t\t\terrExit(\"asprintf\");\n\t\t\tQString str2 = s;\n\t\t\tfree(s);\n\t\t\tmsg += str2;\n\t\t}\n\t\telse\n\t\t\tmsg += \"fallback mode<br/>\";\n\t}\n\tmsg += \"<br/>\";\n\n\tmsg += \"<b>Process:</b><br/>\";\n\tQString qs = QString(\"PID: %1<br/>\").arg(report.pid);\n\tmsg += qs;\n\tqs = QString(\"Fallback server: %1<br/>\").arg(report.fallback);\n\tmsg += qs;\n\tif (report.disable_local_doh)\n\t\tmsg += \"DoH disabled for applications behind the proxy<br/>\";\n\telse\n\t\tmsg += \"DoH allowed for applications behind the proxy<br/>\";\n\tqs = QString(\"To shutdown the proxy run <b>\\\"sudo kill -9 %1\\\"</b> in a terminal<br/><br/>\").arg(report.pid);\n\tmsg += qs;\n\n\tmsg += \"<b>Queries:</b><br/>\";\n\tqs = QString(\"(queries cleared after %1 minutes)<br/>\").arg(report.log_timeout);\n\tmsg += qs;\n\tfor (int i = fdns_report_->logindex; i < MAX_LOG_ENTRIES; i++) {\n\t\tif (fdns_report_->tstamp && strlen(fdns_report_->logentry[i]))\n\t\t\tmsg += printDump(i);\n\t}\n\tfor (int i = 0; i < fdns_report_->logindex; i++) {\n\t\tif (fdns_report_->tstamp && strlen(fdns_report_->logentry[i]))\n\t\t\tmsg += printDump(i);\n\t}\n\n\tprocView_->setHtml(msg);\n\tfdns_dump_ = msg;\n\tif (fdns_fd_)\n\t\t::close(fdns_fd_);\n\tfdns_fd_ = 0;\n\tfdns_report_ = 0;\n}\n\n\nvoid StatsDialog::updateFdns() {\n\tQString msg = header();\n\n\tif (access(shm_file_name_, R_OK)) {\n\t\tmsg += QString(\"Error: cannot open shared memory, probably fdns is not running<br/>\");\n\t\tif (fdns_fd_)\n\t\t\t::close(fdns_fd_);\n\t\tfdns_fd_ = 0;\n\t\tfdns_report_ = 0;\n\t\tprocView_->setHtml(msg);\n\t\treturn;\n\t}\n\n\t// open fdns shared memory if necessary\n\tif (!fdns_fd_) {\n\t\tfdns_fd_ = shm_open(shm_file_name_ + 8, O_RDONLY, S_IRWXU);\n\t\tif (fdns_fd_ == -1) {\n\t\t\tmsg += \"Error: cannot access shared memory, probably fdns is not running<br/>\";\n\t\t\tif (fdns_fd_)\n\t\t\t\t::close(fdns_fd_);\n\t\t\tfdns_fd_ = 0;\n\t\t\tfdns_report_ = 0;\n\t\t\tprocView_->setHtml(msg);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (fdns_fd_ && fdns_report_ == 0) {\n\t\tfdns_report_ = (DnsReport *) mmap(0, sizeof(DnsReport), PROT_READ, MAP_SHARED, fdns_fd_, 0 );\n\t\tif (fdns_report_ == (void *) - 1) {\n\t\t\tmsg += \"Error: cannot map /dev/shm/fdns_stats file in process memory<<br/>\";\n\t\t\tfdns_report_ = 0;\n\t\t\t::close(fdns_fd_);\n\t\t\tfdns_fd_ = 0;\n\t\t\tprocView_->setHtml(msg);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (fdns_fd_ && fdns_report_) {\n\t\tif (fdns_first_run_ || fdns_seq_ != fdns_report_->seq) {\n\t\t\tfdns_first_run_ = false;\n\t\t\tfdns_seq_ = fdns_report_->seq;\n\n\t\t\t// print header\n\t\t\tmsg += \"<b>\";\n\t\t\tmsg += fdns_report_->header1;\n\t\t\tmsg += \"</b><br/><b>\";\n\t\t\tmsg += fdns_report_->header2;\n\t\t\tmsg += \"</b><br/><br/>\";\n\n\t\t\t// print log lines\n\t\t\tint row = 24;\n\t\t\tint i;\n\t\t\tint logrows = MAX_LOG_ENTRIES;\n\t\t\tif ((row - 4) > 0 && (row - 4) < MAX_LOG_ENTRIES)\n\t\t\t\tlogrows = row - 4;\n\n\t\t\tint index = fdns_report_->logindex - logrows;\n\t\t\tfor (i = 0; i < logrows; i++, index++) {\n\t\t\t\tint position = index;\n\t\t\t\tif (index < 0)\n\t\t\t\t\tposition += MAX_LOG_ENTRIES;\n\n\t\t\t\tif (fdns_report_->tstamp && strlen(fdns_report_->logentry[position]))\n\t\t\t\t\tmsg += printDump(position);\n\t\t\t}\n\t\t\tprocView_->setHtml(msg);\n\t\t}\n\t}\n\tprocView_->update();\n}\n\n\nvoid StatsDialog::updateFirewall() {\n\tDbPid *dbptr = Db::instance().findPid(pid_);\n\tif (!dbptr) {\n\t\tmode_ = MODE_TOP;\n\t\treturn;\n\t}\n\n\tQString msg = storage_netfilter_;\n\tif (msg.isEmpty()) {\n\t\tif (arg_debug)\n\t\t\tprintf(\"reading firewall configuration\\n\");\n\t\tmsg = header() + storage_intro_;\n\n\t\tchar *cmd;\n\t\tif (asprintf(&cmd, \"firejail --netfilter.print=%d\", pid_) != -1) {\n\t\t\tchar *str = run_program(cmd);\n\t\t\tif (str)\n\t\t\t\tmsg += \"<pre>\" + QString(str) + \"</pre>\";\n\t\t}\n\t\tstorage_netfilter_ = msg;\n\t\tprocView_->setHtml(msg);\n\t}\n}\n\n\nvoid StatsDialog::updateTree() {\n\tDbPid *dbptr = Db::instance().findPid(pid_);\n\tif (!dbptr) {\n\t\tmode_ = MODE_TOP;\n\t\treturn;\n\t}\n\n\tif (arg_debug)\n\t\tprintf(\"reading process tree configuration\\n\");\n\tQString msg = header() + storage_intro_;\n\tmsg += \"<table><tr><td width=\\\"5\\\"></td><td>\";\n\n\tchar *str = 0;\n\tchar *cmd;\n\tif (asprintf(&cmd, \"firemon --tree --wrap %d\", pid_) != -1) {\n\t\tstr = run_program(cmd);\n\t\tchar *ptr = str;\n\t\t// htmlize!\n\t\twhile (*ptr != 0) {\n\t\t\tif (*ptr == '\\n') {\n\t\t\t\t*ptr = '\\0';\n\t\t\t\tmsg += QString(str) + \"<br/>\\n\";\n\t\t\t\tptr++;\n\n\t\t\t\twhile (*ptr == ' ') {\n\t\t\t\t\tmsg += \"&nbsp;&nbsp;\";\n\t\t\t\t\tptr++;\n\t\t\t\t}\n\t\t\t\tstr = ptr;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tptr++;\n\t\t}\n\t\tfree(cmd);\n\t}\n\n\tmsg += \"</td></tr></table>\";\n\tprocView_->setHtml(msg);\n}\n\n\nvoid StatsDialog::updateSeccomp() {\n\tDbPid *dbptr = Db::instance().findPid(pid_);\n\tif (!dbptr) {\n\t\tmode_ = MODE_TOP;\n\t\treturn;\n\t}\n\n\tQString msg = storage_seccomp_;\n\tif (msg.isEmpty()) {\n\t\tif (arg_debug)\n\t\t\tprintf(\"reading seccomp configuration\\n\");\n\t\tQString msg = header() + storage_intro_;\n\t\tmsg += \"<table><tr><td width=\\\"5\\\"></td><td>\";\n\n\t\tchar *str = 0;\n\t\tchar *cmd;\n\t\tif (asprintf(&cmd, \"firejail --seccomp.print=%d\", pid_) != -1) {\n\t\t\tstr = run_program(cmd);\n\t\t\tchar *ptr = str;\n\t\t\t// htmlize!\n\t\t\twhile (*ptr != 0) {\n\t\t\t\tif (*ptr == '\\n') {\n\t\t\t\t\t*ptr = '\\0';\n\t\t\t\t\tmsg += QString(str) + \"<br/>\\n\";\n\t\t\t\t\tptr++;\n\n\t\t\t\t\twhile (*ptr == ' ') {\n\t\t\t\t\t\tmsg += \"&nbsp;&nbsp;\";\n\t\t\t\t\t\tptr++;\n\t\t\t\t\t}\n\t\t\t\t\tstr = ptr;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tptr++;\n\t\t\t}\n\t\t\tfree(cmd);\n\t\t}\n\n\t\tmsg += \"</td></tr></table>\";\n\t\tprocView_->setHtml(msg);\n\t\tstorage_seccomp_ = msg;\n\t}\n}\n\n\nvoid StatsDialog::updateCaps() {\n\tDbPid *dbptr = Db::instance().findPid(pid_);\n\tif (!dbptr) {\n\t\tmode_ = MODE_TOP;\n\t\treturn;\n\t}\n\n\tQString msg = storage_caps_;\n\tif (msg.isEmpty()) {\n\t\tif (arg_debug)\n\t\t\tprintf(\"reading caps configuration\\n\");\n\t\tmsg = header() + storage_intro_;\n\t\tmsg += \"<table><tr><td width=\\\"5\\\"></td><td>\";\n\n\t\tchar *str = 0;\n\t\tchar *cmd;\n\t\tif (asprintf(&cmd, \"firejail --caps.print=%d\", pid_) != -1) {\n\t\t\tstr = run_program(cmd);\n\t\t\tchar *ptr = str;\n\t\t\t// htmlize!\n\t\t\tint cnt = 0;\n\t\t\twhile (*ptr != 0) {\n\t\t\t\tif (*ptr == '\\n') {\n\t\t\t\t\t// print only caps supported by the current kernel\n\t\t\t\t\tif (cnt >= caps_cnt_)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcnt++;\n\n\t\t\t\t\t*ptr = '\\0';\n\t\t\t\t\tmsg += QString(str) + \"<br/>\\n\";\n\t\t\t\t\tptr++;\n\t\t\t\t\tstr = ptr;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tptr++;\n\t\t\t}\n\t\t\tfree(cmd);\n\t\t}\n\n\t\tmsg += \"</pre></td></tr></table>\";\n\t\tprocView_->setHtml(msg);\n\t\tstorage_caps_ = msg;\n\t}\n}\n\nstatic QString get_dns(int pid) {\n\tQString rv;\n\n\tchar *str = 0;\n\tchar *cmd;\n\tif (asprintf(&cmd, \"firejail --dns.print=%d\", pid) != -1) {\n\t\tstr = run_program(cmd);\n\t\tchar *ptr = str;\n\n\t\t// htmlize!\n\t\twhile (*ptr != 0) {\n\t\t\tif (*ptr == '\\n') {\n\t\t\t\t*ptr = '\\0';\n\t\t\t\tbool skip = false;\n\t\t\t\tif (*str == '#')\n\t\t\t\t\tskip = true;\n\t\t\t\tif (!skip)\n\t\t\t\t\trv += QString(str) + \"<br/>\\n\";\n\t\t\t\tptr++;\n\n\t\t\t\twhile (*ptr == ' ') {\n\t\t\t\t\tif (!skip)\n\t\t\t\t\t\trv += \"&nbsp;&nbsp;\";\n\t\t\t\t\tptr++;\n\t\t\t\t}\n\t\t\t\tstr = ptr;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tptr++;\n\t\t}\n\t}\n\tfree(cmd);\n\treturn rv;\n}\n\n// build the network interface list for firejail versions 0.9.56 or older, including 0.9.56-LTS\nstatic QString get_interfaces_old(int pid) {\n\tQString rv;\n\n\tchar *fname;\n\tif (asprintf(&fname, \"/run/firejail/network/%d-netmap\", pid) == -1)\n\t\terrExit(\"asprintf\");\n\n\tFILE *fp = fopen(fname, \"r\");\n\tif (fp) {\n\t\tchar buf[4096];\n\t\tint i = -1;\n\t\twhile (fgets(buf, 4096, fp)) {\n\t\t\ti++;\n\t\t\tchar *ptr = strchr(buf, '\\n');\n\t\t\tif (ptr)\n\t\t\t\t*ptr = '\\0';\n\n\t\t\t// extract parent device\n\t\t\tptr = strchr(buf, ':');\n\t\t\tif (!ptr)\n\t\t\t\tcontinue;\n\t\t\tchar *parent_dev = buf;\n\t\t\t*ptr = '\\0';\n\t\t\tptr++;\n\t\t\tchar *child_dev = ptr;\n\n\t\t\tQString str = QString(\"%1 (parent device %2\").arg(child_dev).arg(parent_dev);\n\n\t\t\t// detect bridge device\n\t\t\tchar *sysfile;\n\t\t\tif (asprintf(&sysfile, \"/sys/class/net/%s/bridge\", parent_dev) == -1)\n\t\t\t\terrExit(\"asprintf\");\n\t\t\tstruct stat s;\n\t\t\tif (stat(sysfile, &s) == 0)\n\t\t\t\tstr += \", bridge)\";\n\t\t\telse\n\t\t\t\tstr += \")\";\n\t\t\tfree(sysfile);\n\n\t\t\trv += str + \"<br/>\";\n\t\t}\n\t\tfclose(fp);\n\t}\n\tfree(fname);\n\n\treturn rv;\n}\n\n// build the network interface list for firejail versions 0.9.57 and up\n// returns an empty string if --net.print is not available in the currently installed firejail version\nstatic QString get_interfaces_new(int pid) {\n\tQString rv;\n\tchar *str = 0;\n\tchar *cmd;\n\tif (asprintf(&cmd, \"firejail --net.print=%d 2>&1\", pid) != -1) {\n\t\tstr = run_program(cmd);\n\t\tfree(cmd);\n\n\t\t// htmlize!\n\t\tchar *ptr = strtok(str, \"\\n\");\n\t\tif (!ptr || strncmp(ptr, \"Error\", 5) == 0)\n\t\t\tgoto errexit;\n\t\twhile ((ptr = strtok(NULL, \"\\n\")) != NULL) {\n\t\t\tif (strncmp(ptr, \"Error\", 5) == 0)\n\t\t\t\tgoto errexit;\n\t\t\tif (strncmp(ptr, \"Interface \", 10) == 0)\n\t\t\t\tcontinue;\n\t\t\tif (strncmp(ptr, \"lo \", 3) == 0)\n\t\t\t\tcontinue;\n\n\t\t\t// parse the interface line, example\n\t\t\t//eth0-12202       c6:7f:d1:a9:3d:bc  192.168.1.82     255.255.255.0    UP\n\t\t\t// ifname\n\t\t\tchar *ifname = ptr;\n\t\t\twhile (*ptr != ' ' && *ptr != '\\0')\n\t\t\t\tptr++;\n\t\t\tif (*ptr == '\\0')\n\t\t\t\tgoto errexit;\n\t\t\t*ptr = '\\0';\n\t\t\tptr++;\n\n\t\t\t// skip mac address\n\t\t\twhile (*ptr == ' ')\n\t\t\t\tptr++;\n\t\t\twhile (*ptr != ' ' && *ptr != '\\0')\n\t\t\t\tptr++;\n\t\t\tif (*ptr == '\\0')\n\t\t\t\tgoto errexit;\n\t\t\twhile (*ptr == ' ')\n\t\t\t\tptr++;\n\n\t\t\t// ip address\n\t\t\tchar *ip = ptr;\n\t\t\twhile (*ptr != ' ' && *ptr != '\\0')\n\t\t\t\tptr++;\n\t\t\tif (*ptr == '\\0')\n\t\t\t\tgoto errexit;\n\t\t\t*ptr = '\\0';\n\t\t\tptr++;\n\t\t\twhile (*ptr == ' ')\n\t\t\t\tptr++;\n\n\t\t\t// extract mask...\n\t\t\tchar *mask\t= ptr;\n\t\t\twhile (*ptr != ' ' && *ptr != '\\0')\n\t\t\t\tptr++;\n\t\t\tif (*ptr == '\\0')\n\t\t\t\tgoto errexit;\n\t\t\t*ptr = '\\0';\n\t\t\t// ... and build a CIDR addrss\n\t\t\tuint32_t mask_uint32;\n\t\t\tif (atoip(mask, &mask_uint32))\n\t\t\t\tgoto errexit;\n\t\t\tint bits = mask2bits(mask_uint32);\n\t\t\trv += QString(ifname) + \"&nbsp;&nbsp;&nbsp;\" + QString(ip) + \"/\" +\n\t\t\t\tQString::number(bits) + \"<br/>\";\n\t\t}\n\t}\n\n\treturn rv;\n\nerrexit:\n\treturn QString(); // empty string\n}\n\nvoid StatsDialog::updateNetwork() {\n\tint cycle = Db::instance().getCycle();\n\tassert(cycle < DbPid::MAXCYCLE);\n\tDbPid *dbptr = Db::instance().findPid(pid_);\n\tif (!dbptr) {\n\t\tmode_ = MODE_TOP;\n\t\treturn;\n\t}\n\n\t// DNS\n\tQString msg = header() + storage_intro_;\n\tif (storage_dns_.isEmpty()) {\n\t\tif (arg_debug)\n\t\t\tprintf(\"reading dns configuration\\n\");\n\n\t\tstorage_dns_ += \"<table><tr><td width=\\\"5\\\"></td><td><b>DNS</b><br/>\";\n\t\tstorage_dns_ += get_dns(pid_);\n\t\tstorage_dns_ += \"</td>\";\n\t}\n\tmsg += storage_dns_;\n\n\t// network interfaces\n\tif (storage_network_.isEmpty()) {\n\t\tif (net_none_)\n\t\t\tstorage_network_ = \"<td><b>Network Interfaces</b><br/>lo<br/>\";\n\t\telse if (dbptr->netNamespace() == false)\n\t\t\tstorage_network_ = \"<td>Using the system network namespace\";\n\t\telse {\n\n\t\t\tstorage_network_ = \"<td><b>Network Interfaces</b><br/>lo<br/>\";\n\t\t\tQString tmp = get_interfaces_new(pid_);\n\t\t\tif (tmp.isEmpty())\n\t\t\t\ttmp = get_interfaces_old(pid_);\n\t\t\tstorage_network_ += tmp;\n\t\t}\n\t\tstorage_network_ += \"</td></tr>\";\n\n\t}\n\tmsg += storage_network_;\n\n\n\n\t// graph type\n\tmsg += \"<tr><td></td>\";\n\tif (dbptr->netNamespace() == true && net_none_ == false) {\n\t\tif (graph_type_ == GRAPH_1MIN) {\n\t\t\tmsg += \"<td><b>Stats: </b>1min <a href=\\\"1h\\\">1h</a> <a href=\\\"12h\\\">12h</a></td>\";\n\t\t}\n\t\telse if (graph_type_ == GRAPH_1H) {\n\t\t\tmsg += \"<td><b>Stats: </b><a href=\\\"1min\\\">1min</a> 1h <a href=\\\"12h\\\">12h</a></td>\";\n\t\t}\n\t\telse if (graph_type_ == GRAPH_12H) {\n\t\t\tmsg += \"<td><b>Stats: </b><a href=\\\"1min\\\">1min</a> <a href=\\\"1h\\\">1h</a> 12h</td>\";\n\t\t}\n\t\telse\n\t\t\tassert(0);\n\t}\n\n\t// netfilter\n\tif (dbptr->netNamespace() == true && net_none_ == false)\n\t\tmsg += \"<td><b>Firewall</b>: <a href=\\\"firewall\\\">enabled</a></td></tr>\\n\";\n\telse if (dbptr->netNone() == true)\n\t\tmsg += \"<td><b>Firewall</b>: no firewall</td></tr>\\n\";\n\telse\n\t\tmsg += \"<td><b>Firewall</b>: system firewall</td></tr>\\n\";\n\n\n\tif (dbptr->netNamespace() == true && net_none_ == false)\n\t\tmsg += \"<tr><td></td><td>\"+ graph(2, dbptr, cycle, graph_type_) + \"</td><td>\" + graph(3, dbptr, cycle, graph_type_) + \"</td></tr>\";\n\n\tmsg += QString(\"</table><br/>\");\n\n\t// bandwidth limits\n\tif (dbptr->netNamespace() == true && net_none_ == false) {\n\t\tchar *fname;\n\t\tif (asprintf(&fname, \"/run/firejail/bandwidth/%d-bandwidth\", pid_) == -1)\n\t\t\terrExit(\"asprintf\");\n\t\tFILE *fp = fopen(fname, \"r\");\n\t\tif (fp) {\n\t\t\tmsg += \"<br/><table><tr><td width=\\\"5\\\"></td><td>\";\n\t\t\tmsg += \"<b>Bandwidth limits:</b><br/><br/>\\n\";\n\t\t\tchar buf[1024];\n\t\t\twhile (fgets(buf, 1024, fp)) {\n\t\t\t\tmsg += buf;\n\t\t\t\tmsg += \"<br/>\";\n\t\t\t}\n\t\t\tfclose(fp);\n\t\t\tmsg += \"</td></tr></table>\";\n\t\t}\n\t\tfree(fname);\n\t}\n\n\tprocView_->setHtml(msg);\n\n}\n\nvoid StatsDialog::kernelSecuritySettings() {\n\tif (arg_debug)\n\t\tprintf(\"Checking security settings for pid %d\\n\", pid_);\n\n\t// reset all\n\tpid_seccomp_ = false;\n\tpid_caps_ = QString(\"\");\n\tpid_cpu_cores_ = QString(\"\");\n\tpid_protocol_ = QString(\"\");\n\tpid_mem_deny_exec_ = QString(\"disabled\");\n\tpid_apparmor_ = QString(\"\");\n\n\t// caps\n\tchar *cmd;\n\tif (asprintf(&cmd, \"firemon --caps %d\", pid_) == -1)\n\t\treturn;\n\tchar *str = run_program(cmd);\n\tif (str) {\n\t\tchar *ptr = strstr(str, \"CapBnd:\");\n\t\tif (ptr)\n\t\t\tpid_caps_ = QString(ptr + 7);\n\t\telse\n\t\t\tpid_caps_ = QString(\"\");\n\t}\n\tfree(cmd);\n\n\t// seccomp\n\tif (asprintf(&cmd, \"firemon --seccomp %d\", pid_) == -1)\n\t\treturn;\n\tstr = run_program(cmd);\n\tif (str) {\n\t\tchar *ptr = strstr(str, \"Seccomp\");\n\t\tif (ptr) {\n\t\t\tif (strstr(ptr, \"2\"))\n\t\t\t\tpid_seccomp_ = true;\n\t\t}\n\t}\n\tfree(cmd);\n\n\t// cpu cores\n\tif (asprintf(&cmd, \"firemon --cpu %d\", pid_) == -1)\n\t\treturn;\n\tstr = run_program(cmd);\n\tif (str) {\n\t\tchar *ptr = strstr(str, \"Cpus_allowed_list:\");\n\t\tif (ptr) {\n\t\t\tptr += 18;\n\t\t\tpid_cpu_cores_ = QString(ptr);\n\t\t}\n\t}\n\tfree(cmd);\n\n\t// protocols\n\tif (asprintf(&cmd, \"firejail --protocol.print=%d\", pid_) == -1)\n\t\treturn;\n\n\tstr = run_program(cmd);\n\tif (str) {\n\t\tif (strncmp(str, \"Cannot\", 6) == 0)\n\t\t\tpid_protocol_ = QString(\"disabled\");\n\t\telse\n\t\t\tpid_protocol_ = QString(str);\n\t}\n\tfree(cmd);\n\n\t// mem deny exec\n\tif (asprintf(&cmd, \"firejail --ls=%d /run/firejail/mnt\", pid_) == -1)\n\t\treturn;\n\tstr = run_program(cmd);\n\tif (str) {\n\t\tif (strstr(str, \"seccomp.mdwx\"))\n\t\t\tpid_mem_deny_exec_ = \"enabled\";\n\t}\n\tfree(cmd);\n\n\t// apparmor\n\tif (asprintf(&cmd, \"firejail --apparmor.print=%d\", pid_) == -1)\n\t\treturn;\n\tstr = run_program(cmd);\n\tif (str) {\n\t\tconst char *tofind = \"AppArmor: \";\n\t\tchar *ptr = strstr(str, tofind);\n\t\tif (ptr)\n\t\t\tpid_apparmor_ = QString(ptr + strlen(tofind));\n\t}\n\tfree(cmd);\n}\n\nvoid StatsDialog::updatePid() {\n\tQString msg = \"\";\n\n\tint cycle = Db::instance().getCycle();\n\tassert(cycle < DbPid::MAXCYCLE);\n\tDbPid *ptr = Db::instance().findPid(pid_);\n\tif (!ptr) {\n\t\tmode_ = MODE_TOP;\n\t\treturn;\n\t}\n\n\tconst char *cmd = ptr->getCmd();\n\tif (!cmd) {\n\t\tmode_ = MODE_TOP;\n\t\treturn;\n\t}\n\n\t// initialize static values\n\tif (pid_initialized_ == false) {\n\t\tkernelSecuritySettings();\n\t\tpid_noroot_ = userNamespace(pid_);\n\t\tpid_name_ = getName(pid_);\n\t\tprofile_ = getProfile(pid_);\n\t\tpid_x11_ = getX11Display(pid_);\n\t\tpid_initialized_ = true;\n\n\t\t// detect --net=none\n\t\tint child = pid_find_child(pid_);\n\t\tchar *fname;\n\t\tif (asprintf(&fname, \"/proc/%d/net/dev\", child) == -1)\n\t\t\terrExit(\"asprintf\");\n\t\tFILE *fp = fopen(fname, \"r\");\n\t\tif (fp) {\n\t\t\tchar buf[4096];\n\t\t\tint cnt = 0;\n\t\t\twhile (fgets(buf, 4096, fp))\n\t\t\t\tcnt++;\n\t\t\tfclose(fp);\n\t\t\tif (cnt <= 3)\n\t\t\t\tnet_none_ = true;\n\t\t\telse\n\t\t\t\tnet_none_ = false;\n\t\t}\n\t\tfree(fname);\n\t}\n\n\t// get user name\n\tDbStorage *st = &ptr->data_1min_[cycle];\n\tstruct passwd *pw = getpwuid(ptr->getUid());\n\tif (!pw)\n\t\terrExit(\"getpwuid\");\n\tuid_ = pw->pw_uid;\n\n\t// add header\n\tmsg += header();\n\n\t// add intro\n\tstorage_intro_ = \"<table>\";\n\tif (!pid_name_.isEmpty())\n\t\tstorage_intro_ += \"<tr><td width=\\\"5\\\"></td><td><b>Sandbox name:</b> \" + pid_name_ + \"</td></tr>\";\n\tstorage_intro_ += \"<tr><td width=\\\"5\\\"></td><td><b>Command:</b> \" + QString(cmd) + \"</td></tr>\";\n\tif (!profile_.isEmpty())\n\t\tstorage_intro_ += \"<tr><td width=\\\"5\\\"></td><td><b>Profile:</b> \" + profile_ + \"</td></tr>\";\n\tstorage_intro_ += \"</table><br/>\";\n\tmsg += storage_intro_;\n\n\tmsg += \"<table>\";\n\tmsg += QString(\"<tr><td width=\\\"5\\\"></td><td><b>PID:</b> \") +  QString::number(pid_) + \"</td>\";\n\tif (ptr->netNamespace() == false) {\n\t\tQString net = (net_none_)? \" no network\": \" system\";\n\t\tmsg += \"<td><b>RX:</b> \" + net + \"</td></tr>\";\n\t}\n\telse\n\t\tmsg += QString(\"<td><b>RX:</b> \") + QString::number(st->rx_) + \" KB/s</td></tr>\";\n\n\tmsg += QString(\"<tr><td></td><td><b>User:</b> \") + pw->pw_name  + \"</td>\";\n\tif (ptr->netNamespace() == false) {\n\t\tQString net = (net_none_)? \" no network\": \" system\";\n\t\tmsg += \"<td><b>TX:</b> \" + net + \"</td></tr>\";\n\t}\n\telse\n\t\tmsg += QString(\"<td><b>TX:</b> \") + QString::number(st->tx_) + \" KB/s</td></tr>\";\n\n\tmsg += QString(\"<tr><td></td><td><b>CPU:</b> \") + QString::number(st->cpu_) + \"%</td>\";\n\tmsg += QString(\"<td><b>Seccomp:</b> \");\n\tif (pid_seccomp_)\n\t\tmsg += \"<a href=\\\"seccomp\\\">enabled</a>\";\n\telse\n\t\tmsg += \"disabled\";\n\tmsg += \"</td></tr>\";\n\n\tmsg += QString(\"<tr><td></td><td><b>Memory:</b> \") + QString::number((int) (st->rss_ + st->shared_)) + \" KiB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>\";\n\tmsg += QString(\"<td><b>Capabilities:</b> <a href=\\\"caps\\\">\") + pid_caps_ + \"</a></td></tr>\";\n\n\tmsg += QString(\"<tr><td></td><td><b>RSS</b> \" + QString::number((int) st->rss_) + \", <b>shared</b> \" + QString::number((int) st->shared_)) + \"</td>\";\n\n\t// user namespace\n\tmsg += \"<td><b>User Namespace:</b> \";\n\n\tif (pid_noroot_)\n\t\tmsg += \"enabled\";\n\telse\n\t\tmsg += \"disabled\";\n\tmsg += \"</td></tr>\";\n\n\tmsg += QString(\"<tr><td></td><td><b>CPU Cores:</b> \") + pid_cpu_cores_ + \"</td>\";\n\tif (pid_seccomp_)\n\t\tmsg += QString(\"<td><b>Protocols:</b> \") + pid_protocol_ + \"</td>\";\n\telse\n\t\tmsg += QString(\"<td><b>Protocols:</b> disabled</td>\");\n\tmsg += \"</td></tr>\";\n\n\tmsg += \"<tr><td></td>\";\n\n\t// X11 display\n\tif (pid_x11_) {\n\t\tmsg += \"<td><b>X11 Dispaly:</b> \" + QString::number(pid_x11_) + \"</td>\";\n\t}\n\telse\n\t\tmsg +=\"<td></td>\";\n\n\t// memory deny exec\n\tmsg += \"<td><b>Memory deny exec:</b> \" + pid_mem_deny_exec_ + \"</td></tr>\";\n\n\n\t// apparmor\n\tif (!pid_apparmor_.isEmpty())\n\t\tmsg += \"<tr><td></td><td></td><td><b>AppArmor: </b>\" + pid_apparmor_ + \"</td></tr>\";\n\n\n\t// graph type\n\tmsg += \"<tr></tr>\";\n\tmsg += \"<tr><td></td>\";\n\tif (graph_type_ == GRAPH_1MIN) {\n\t\tmsg += \"<td><b>Stats: </b>1min <a href=\\\"1h\\\">1h</a> <a href=\\\"12h\\\">12h</a></td>\";\n\t}\n\telse if (graph_type_ == GRAPH_1H) {\n\t\tmsg += \"<td><b>Stats: </b><a href=\\\"1min\\\">1min</a> 1h <a href=\\\"12h\\\">12h</a></td>\";\n\t}\n\telse if (graph_type_ == GRAPH_12H) {\n\t\tmsg += \"<td><b>Stats: </b><a href=\\\"1min\\\">1min</a> <a href=\\\"1h\\\">1h</a> 12h</td>\";\n\t}\n\telse\n\t\tassert(0);\n\n\t// graphs\n\tmsg += \"<tr></tr>\";\n\tmsg += \"<tr><td></td><td>\"+ graph(0, ptr, cycle, graph_type_) + \"</td><td>\" + graph(1, ptr, cycle, graph_type_) + \"</td></tr>\";\n\n\tmsg += QString(\"</table><br/>\");\n\n\tprocView_->setHtml(msg);\n}\n\nvoid StatsDialog::cycleReady() {\n\tif (mode_ == MODE_TOP)\n\t\tupdateTop();\n\telse if (mode_ == MODE_FDNS)\n\t\tupdateFdns();\n\telse if (mode_ == MODE_FDNS_DUMP)\n\t\tupdateFdnsDump();\n\telse if (mode_ == MODE_PID)\n\t\tupdatePid();\n\telse if (mode_ == MODE_TREE)\n\t\tupdateTree();\n\telse if (mode_ == MODE_SECCOMP)\n\t\tupdateSeccomp();\n\telse if (mode_ == MODE_NETWORK)\n\t\tupdateNetwork();\n\telse if (mode_ == MODE_CAPS)\n\t\tupdateCaps();\n\telse if (mode_ == MODE_FIREWALL)\n\t\tupdateFirewall();\n}\n\nvoid StatsDialog::anchorClicked(const QUrl & link) {\n\tcleanStorage(); // full storage cleanup on any click\n\tQString linkstr = link.toString();\n\n\tif (linkstr == \"top\") {\n\t\tmode_ = MODE_TOP;\n\t}\n\telse if (linkstr == \"back\") {\n\t\tif (mode_ == MODE_PID)\n\t\t\tmode_ = MODE_TOP;\n\t\telse if (mode_ == MODE_TREE)\n\t\t\tmode_ = MODE_PID;\n\t\telse if (mode_ == MODE_SECCOMP)\n\t\t\tmode_ = MODE_PID;\n\t\telse if (mode_ == MODE_NETWORK)\n\t\t\tmode_ = MODE_PID;\n\t\telse if (mode_ == MODE_CAPS)\n\t\t\tmode_ = MODE_PID;\n\t\telse if (mode_ == MODE_FIREWALL)\n\t\t\tmode_ = MODE_PID;\n\t\telse if (mode_ == MODE_TOP)\n\t\t\t;\n\t\telse\n\t\t\tassert(0);\n\t}\n\telse if (linkstr == \"tree\") {\n\t\tmode_ = MODE_TREE;\n\t}\n\telse if (linkstr == \"seccomp\") {\n\t\tmode_ = MODE_SECCOMP;\n\t}\n\telse if (linkstr == \"caps\") {\n\t\tmode_ = MODE_CAPS;\n\t}\n\telse if (linkstr == \"1h\") {\n\t\tgraph_type_ = GRAPH_1H;\n\t}\n\telse if (linkstr == \"12h\") {\n\t\tgraph_type_ = GRAPH_12H;\n\t}\n\telse if (linkstr == \"1min\") {\n\t\tgraph_type_ = GRAPH_1MIN;\n\t}\n\telse if (linkstr == \"network\") {\n\t\tmode_ = MODE_NETWORK;\n\t}\n\telse if (linkstr == \"firewall\") {\n\t\tmode_ = MODE_FIREWALL;\n\t}\n\telse if (linkstr == \"shut\") {\n\t\tQMessageBox msgBox;\n\t\tmsgBox.setText(QString(\"Are you sure you want to shutdown PID \") + QString::number(pid_) + \"?\\n\");\n\t\tmsgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);\n\t\tmsgBox.setDefaultButton(QMessageBox::Cancel);\n\t\tint rv = msgBox.exec();\n\t\tif (rv == QMessageBox::Ok) {\n\t\t\t// shutdown sandbox\n\t\t\tQApplication::setOverrideCursor(Qt::WaitCursor);\n\t\t\tchar *cmd;\n\t\t\tif (asprintf(&cmd, \"firejail --shutdown=%d\", pid_) != -1) {\n\t\t\t\tint rv = system(cmd);\n\t\t\t\t(void) rv;\n\t\t\t\tfree(cmd);\n\t\t\t}\n\t\t\tQApplication::restoreOverrideCursor();\n\t\t\tmode_ = MODE_TOP;\n\t\t}\n\t}\n\telse if (linkstr == \"join\") {\n\t\t// join the process in a new xterm\n\t\tchar *cmd;\n\t\tif (asprintf(&cmd, \"xterm -T \\\"Firejail Sandbox %d\\\" -e firejail --join=%d&\", pid_, pid_) != -1) {\n\t\t\tint rv = system(cmd);\n\t\t\t(void) rv;\n\t\t\tfree(cmd);\n\t\t}\n\t}\n\telse if (linkstr == \"fmgr\") {\n\t\tchar *cmd;\n\t\tif (asprintf(&cmd, PACKAGE_LIBDIR \"/fmgr %d&\", pid_) != -1) {\n\t\t\tint rv = system(cmd);\n\t\t\t(void) rv;\n\t\t\tfree(cmd);\n\t\t}\n\t}\n\telse if (linkstr == \"about\") {\n\t\tQString msg = \"<table cellpadding=\\\"10\\\"><tr><td><img src=\\\":/resources/fstats.png\\\"></td>\";\n\t\tmsg += \"<td>\" + tr(\n\t\t\t\"Firetools is a GUI application for Firejail. \"\n\t\t\t\"It offers a system tray launcher for sandboxed apps, \"\n\t\t\t\"sandbox editing, management, and statistics. \"\n\t\t\t\"The software package also includes a sandbox configuration wizard, firejail-ui.<br/><br/>\"\n\t\t\t\"Firejail  is  a  SUID sandbox program that reduces the risk of security \"\n\t\t\t\"breaches by restricting the running environment of  untrusted  applications \"\n\t\t\t\"using Linux namespaces, Linux capabilities and seccomp-bpf.<br/><br/>\") +\n\t\t\ttr(\"Firetools version:\") + \" \" + PACKAGE_VERSION + \"<br/>\" +\n\t\t\ttr(\"QT version: \") + \" \" + QT_VERSION_STR + \"<br/>\" +\n\t\t\ttr(\"License:\") + \" GPL v2<br/>\" +\n\t\t\ttr(\"Homepage:\") + \" \" + QString(PACKAGE_URL) + \"</td></tr></table><br/><br/>\";\n\n\t\tQMessageBox::about(this, tr(\"About\"), msg);\n\n\t}\n\telse if (linkstr == \"fdns\") {\n\t\tif (mode_ != MODE_FDNS_DUMP) {\n\t\t\tif (shm_file_name_)\n\t\t\t\tfree(shm_file_name_);\n\t\t\tshm_file_name_ = find_fdns_shm_file_name();\n\t\t\tif (fdns_report_)\n\t\t\t\tfdns_report_ = 0;\n\t\t\tif (fdns_fd_) {\n\t\t\t\t::close(fdns_fd_);\n\t\t\t\tsleep(1); // give the kernel some time to close the shared mem file in order to open another one\n\t\t\t}\n\t\t}\n\t\tmode_ = MODE_FDNS;\n\t}\n\telse if (linkstr == \"dump\") {\n\t\tfdns_dump_ = QString(\"\");\n\t\tmode_ = MODE_FDNS_DUMP;\n\t}\n\telse if (linkstr == \"newsandbox\") {\n\t\t// start firejail-ui as a separate process\n\n\t\tQProcess *process = new QProcess();\n\t\tQStringList arguments;\n//\t\targuments << \"--nofiretools\";\n\t\tprocess->startDetached(QString(\"firejail-ui\"), arguments);\n\t}\n\telse { // linstr == \"home\"\n\t\tpid_ = linkstr.toInt();\n\t\tpid_initialized_ = false;\n\t\tpid_caps_ = QString(\"\");\n\t\tpid_name_ = QString(\"\");\n\t\tpid_x11_ = 0;\n\t\tmode_ = MODE_PID;\n\t}\n\n\t// reset fdns\n\tfdns_first_run_ = true;\n\n\tif (data_ready)\n\t\tcycleReady();\n}\n\n\nstatic bool userNamespace(pid_t pid) {\n\tif (arg_debug)\n\t\tprintf(\"Checking user namespace for pid %d\\n\", pid);\n\n\t// test user namespaces available in the kernel\n\tstruct stat s1;\n\tstruct stat s2;\n\tstruct stat s3;\n\tif (stat(\"/proc/self/ns/user\", &s1) == 0 &&\n\t    stat(\"/proc/self/uid_map\", &s2) == 0 &&\n\t    stat(\"/proc/self/gid_map\", &s3) == 0);\n\telse\n\t\treturn false;\n\n\tpid = pid_find_child(pid);\n\tif (pid == -1)\n\t\treturn false;\n\n\t// read uid map\n\tchar *uidmap;\n\tif (asprintf(&uidmap, \"/proc/%u/uid_map\", pid) == -1)\n\t\terrExit(\"asprintf\");\n\tFILE *fp = fopen(uidmap, \"r\");\n\tif (!fp) {\n\t\tfree(uidmap);\n\t\treturn false;\n\t}\n\n\t// check uid map\n\tint u1;\n\tint u2;\n\tbool found = false;\n\tif (fscanf(fp, \"%d %d\", &u1, &u2) == 2) {\n\t\tif (u1 != 0 || u2 != 0)\n\t\t\tfound = true;\n\t}\n\tfclose(fp);\n\tfree(uidmap);\n\treturn found;\n}\n\nstatic QString getName(pid_t pid) {\n\tQString retval(\"\");\n\n\tchar *fname;\n\tif (asprintf(&fname, \"/run/firejail/name/%d\", (int) pid) == -1)\n\t\terrExit(\"asprintf\");\n\tFILE *fp = fopen(fname, \"r\");\n\tif (fp) {\n\t\tchar name[250];\n\t\tif (fgets(name, 250, fp))\n\t\t\tretval = QString(name);\n\t\tfclose(fp);\n\t}\n\tfree(fname);\n\n\treturn retval;\n}\n\nstatic QString getProfile(pid_t pid) {\n\tQString retval(\"\");\n\n\tchar *fname;\n\tif (asprintf(&fname, \"/run/firejail/profile/%d\", (int) pid) == -1)\n\t\terrExit(\"asprintf\");\n\tFILE *fp = fopen(fname, \"r\");\n\tif (fp) {\n\t\tchar name[250];\n\t\tif (fgets(name, 250, fp))\n\t\t\tretval = QString(name);\n\t\tfclose(fp);\n\t}\n\tfree(fname);\n\n\treturn retval;\n}\n\nstatic int getX11Display(pid_t pid) {\n\tint retval = 0;\n\n\tchar *fname;\n\tif (asprintf(&fname, \"/run/firejail/x11/%d\", (int) pid) == -1)\n\t\terrExit(\"asprintf\");\n\tFILE *fp = fopen(fname, \"r\");\n\tif (fp) {\n\t\tint val;\n\t\tif (fscanf(fp, \"%d\", &val) == 1)\n\t\t\tretval = val;\n\t\tfclose(fp);\n\t}\n\tfree(fname);\n\n\treturn retval;\n}\n"
  },
  {
    "path": "src/fstats/stats_dialog.h",
    "content": "/*\n * Copyright (C) 2015-2018 Firetools Authors\n *\n * This file is part of firetools project\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along\n * with this program; if not, write to the Free Software Foundation, Inc.,\n * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n*/\n#ifndef STATS_DIALOG_H\n#define STATS_DIALOG_H\n#include <sys/types.h>\n#include <pwd.h>\n#include <QWidget>\n#include <QDialog>\n#include <QAction>\n#include <QSystemTrayIcon>\n#include \"fstats.h\"\n\nclass QTextBrowser;\nclass QUrl;\n\nclass PidThread;\n\n\nextern \"C\" {\ntypedef struct dns_report_t {\n\tvolatile uint32_t seq;\t//sqence number used to detect data changes\n\n\t// proxy config\n\tunsigned pid;\n\tint log_timeout;\n\tint disable_local_doh;\n\tint nofilter;\n#define MAX_ENTRY_LEN 82 \t// a full line on a terminal screen, \\n and \\0\n\tchar fallback[MAX_ENTRY_LEN];\n\n\t// resolvers\n#define RESOLVERS_CNT_MAX 10\n\tint resolvers;\n\tint encrypted[RESOLVERS_CNT_MAX];\n\tuint32_t peer_ip[RESOLVERS_CNT_MAX];\n\n\t// header\n\tchar header1[MAX_ENTRY_LEN];\n\tchar header2[MAX_ENTRY_LEN];\n\n\t// queries\n\tint logindex;\n#define MAX_LOG_ENTRIES 512 \t// 18 lines on the screen in order to handle tab terminals\n\ttime_t tstamp[MAX_LOG_ENTRIES];\n\tchar logentry[MAX_LOG_ENTRIES][MAX_ENTRY_LEN];\n} DnsReport;\n} // extern \"C\"\n\nclass StatsDialog: public QDialog {\nQ_OBJECT\n\npublic:\n\tStatsDialog();\n\t~StatsDialog();\n\nprivate slots:\n\tvoid main_quit();\n\npublic slots:\n\tvoid cycleReady();\n\tvoid anchorClicked(const QUrl & link);\n\tvoid trayActivated(QSystemTrayIcon::ActivationReason);\n\nprivate:\n\tQString header();\n\tvoid kernelSecuritySettings();\n\tvoid updateTop();\n\tvoid updateFdns();\n\tinline QString printDump(int index);\n\tvoid updateFdnsDump();\n\tvoid updatePid();\n\tvoid updateTree();\n\tvoid updateSeccomp();\n\tvoid updateNetwork();\n\tvoid updateCaps();\n\tvoid updateFirewall();\n\tvoid cleanStorage();\n\tvoid createTrayActions();\n\nprivate:\n\tDnsReport *fdns_report_;\n\tuint32_t fdns_seq_;\n\tint fdns_fd_;\n\tbool fdns_first_run_;\n\n\tQTextBrowser *procView_;\n\n#define MODE_TOP 0\n#define MODE_PID 1\n#define MODE_TREE 2\n#define MODE_SECCOMP 3\n#define MODE_NETWORK 4\n#define MODE_CAPS 5\n#define MODE_FIREWALL 6\n#define MODE_FDNS 7\n#define MODE_FDNS_DUMP 8\n#define MODE_MAX 9 // always the last one\n\tint mode_;\n\tint pid_;\t// pid value for mode 1\n\tuid_t uid_;\n\tbool lts_;\t// flag to detect LTS version of firejail\n\n\t// security settings\n\tbool pid_initialized_;\n\tbool pid_seccomp_;\n\tQString pid_caps_;\n\tbool pid_noroot_;\n\tQString pid_cpu_cores_;\n\tQString pid_protocol_;\n\tQString pid_name_;\n\tQString pid_mem_deny_exec_;\n\tQString pid_apparmor_;\n\tQString profile_;\n\tint pid_x11_;\n\tQString fdns_dump_;\n\n\tbool have_join_;\n\tint caps_cnt_;\n\tGraphType graph_type_;\n\tbool net_none_;\n\n\tPidThread *thread_;\n\n\t// storage for various sandbox settings\n\tQString storage_dns_;\n\tQString storage_caps_;\n\tQString storage_seccomp_;\n\tQString storage_intro_;\n\tQString storage_network_;\n\tQString storage_netfilter_;\n\n\tchar *shm_file_name_;\npublic:\n\tQAction *minimizeAction;\n\tQAction *restoreAction;\n\tQAction *quitAction;\n};\n\n\n#endif\n"
  },
  {
    "path": "src/man/firejail-ui.txt",
    "content": ".TH FIREJAIL-UI 1 \"MONTH YEAR\" \"VERSION\" \"firejail-ui man page\"\n.SH NAME\nfirejail-ui \\- Firejail sandbox configuration wizard\n.SH SYNOPSIS\nfirejail-ui [OPTIONS]\n.SH DESCRIPTION\nThis  manual  page  documents  briefly firejail-ui, the sandbox configuration wizard for Firejail sandbox.\n.SH OPTIONS\n.TP\n\\fB\\-\\-debug\\fR\nPrint debug messages.\n.TP\n\\fB\\-?\\fR, \\fB\\-\\-help\\fR\nPrint options end exit.\n.TP\n\\fB\\-\\-version\\fR\nPrint software version and exit.\n.SH ABOUT FIREJAIL\nFirejail is a SUID sandbox program that reduces the risk of security breaches by\nrestricting the running environment of untrusted applications using Linux\nnamespaces, seccomp-bpf and Linux capabilities.\nIt allows a process and all its descendants to have their own private view of the\nglobally shared kernel resources, such as the network stack, process table, mount table.\nFirejail can work in a SELinux or AppArmor environment,\nand it is integrated with Linux Control Groups.\n.SH LICENSE\nThis program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\n.PP\nHomepage: http://firejail.wordpress.com\n.SH SEE ALSO\n\\&\\flfirejail\\fR\\|(1),\n\\&\\flfiretools\\fR\\|(1)\n\n\n\n\n"
  },
  {
    "path": "src/man/firetools.txt",
    "content": ".TH FIRETOOLS 1 \"MONTH YEAR\" \"VERSION\" \"firetools man page\"\n.SH NAME\nFiretools \\- Graphical tools collection for Firejail security sandbox\n.SH SYNOPSIS\nfiretools [OPTIONS]\n.SH DESCRIPTION\nFiretools is a GUI application for Firejail.\nIt offers a system tray launcher for sandboxed apps, sandbox editing, management, and statistics.\nThe software package also includes a sandbox configuration wizard, firejail-ui.\n\nThe list of applications recognized automatically by Firetools is stored in /usr/lib/firetools/applist.\nTo add more applications to the list drop a similar file in your home directory in ~/.config/firetools/uiapps.\n\n.SH OPTIONS\n.TP\n\\fB\\-\\-autostart\\fR\nConfigure firetools to run automatically in system tray when X11 session is started.\n.TP\n\\fB\\-\\-debug\\fR\nPrint debug messages.\n.TP\n\\fB\\-?\\fR, \\fB\\-\\-help\\fR\nPrint options end exit.\n.TP\n\\fB\\-\\-version\\fR\nPrint software version and exit.\n\n.SH CONFIGURATION\n/usr/lib/firetools/uiapps file contains the default list of applications recognized by default. The user can add more applications\nby creating a simillar file in ~/.config/firetools/uiapps in user home directory. Each line describes an application as follows:\n.PP\n.RS\nexecutable; description; icon; (optional) firejail command\n.RE\n\nSome examples:\n.PP\n.RS\ninkscape;Inkscape SVG Editor;inkscape\n.br\ncalibre;eBook Reader;/usr/share/calibre/images/lt.png\n.br\nmpv;MPV;mpv;firejail mpv --player-operation-mode=pseudo-gui\n.br\n.RE\n\n.SH ABOUT FIREJAIL\nFirejail is a SUID sandbox program that reduces the risk of security breaches by\nrestricting the running environment of untrusted applications using Linux\nnamespaces, seccomp-bpf and Linux capabilities.\nIt allows a process and all its descendants to have their own private view of the\nglobally shared kernel resources, such as the network stack, process table, mount table.\nFirejail can work in a SELinux or AppArmor environment,\nand it is integrated with Linux Control Groups.\n.SH LICENSE\nThis program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\n.PP\nHomepage: http://firejail.wordpress.com\n.SH SEE ALSO\n\\&\\flfirejail\\fR\\|(1),\n\\&\\flfirejail-ui\\fR\\|(1),\n\n\n"
  },
  {
    "path": "todo",
    "content": "1. Documentation: packages needed on Debian Jessie: qt5-default, libqt5svg5, firejail, xterm\n\n2. If a program is uninstalled, do not leave it in the launcher\n\n3. On debian i386, open new xterm sandbox, join it, shut down the join process - it does not shut down!\n\n4. Detecting sandbox features from command line params:\n--net detected in pid_thread.cpp (strstr(pids[pid].cmd, \"--net\")), it might pick it up from the\nparams of the sandboxed program\n\n5. Merge from firejail main\nMar 10:  fix --list reporting for sandboxes using --x11=none;\n\n6. Update copyright years\n"
  }
]