From: William Douglas Date: Wed, 13 Jun 2012 23:04:18 +0000 (-0700) Subject: Add systemd with tizen patches X-Git-Tag: build/2012-08-08.212442~8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=63998ceb5951d02a19811cbd4cef04aa86c6dd1a;p=external%2Fsystemd.git Add systemd with tizen patches Change-Id: Ib2692ea352ab596b3c5de1e584dff6614902b216 Signed-off-by: William Douglas --- diff --git a/DISTRO_PORTING b/DISTRO_PORTING new file mode 100644 index 0000000..2b08bf8 --- /dev/null +++ b/DISTRO_PORTING @@ -0,0 +1,58 @@ +Porting systemd To New Distributions + +HOWTO: + You need to make the follow changes to adapt systemd to your + distribution: + + 0) Make your distribution recognized via the autoconf checks + in configure.ac. Grep for the word "fedora" (case + insensitively) and you should be able to find the places where + you need to add/change things. + + 1) Patch src/hostname-setup.c so that systemd knows where to + read your host name from. You might also want to update + status_welcome() in util.c. + + 2) Check the unit files in units/ if they match your + distribution. Most likely you will have to make additions to + units/*.m4 and create a copy of units/fedora/ with changes for + your distribution. + + 3) Adjust Makefile.am to register the unit files you added in + step 2. Also you might need to update the m4 invocation in + Makefile.am. Grep for the word "fedora" (case insensitively) + and you should be able to find the places where you need to + add/change things. + + 4) Try it out. Play around with 'systemd --test --system' for + a test run of systemd without booting. This will read the unit + files and print the initial transaction it would execute + during boot-up. This will also inform you about ordering loops + and suchlike. + +CONTRIBUTING UPSTREAM: + We are interested in merging your changes upstream, if they + are for a big, and well-known distribution. Unfortunately we + don't have the time and resources to maintain + distribution-specific patches for all distributions on the + planet, hence please do not send us patches that add systemd + support for non-mainstream or niche distributions. + + Thank you for understanding. + +BE CONSIDERATE: + We'd like to keep differences between the distributions + minimal. This both simplifies our maintenance work, as well + as it helps administrators to move from one distribution to + another. + + Hence we'd like to ask you to keep your changes minimal, and + not rename any units without a very good reason (if you need a + particular name for compatibility reasons, consider using + alias names via symlinks). Before you make changes that change + semantics from upstream, please talk to us! + + In SysV almost every distribution uses a different + nomenclature and different locations for the boot-up + scripts. We'd like to avoid chaos like that with systemd right + from the beginning. So please, be considerate! diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..9762da1 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,2530 @@ +# This file is part of systemd. +# +# Copyright 2011 Lennart Poettering +# Copyright 2011 Kay Sievers +# +# systemd 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. +# +# systemd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with systemd; If not, see . + +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS = po + +LIBSYSTEMD_LOGIN_CURRENT=2 +LIBSYSTEMD_LOGIN_REVISION=0 +LIBSYSTEMD_LOGIN_AGE=2 + +LIBSYSTEMD_DAEMON_CURRENT=0 +LIBSYSTEMD_DAEMON_REVISION=1 +LIBSYSTEMD_DAEMON_AGE=0 + +LIBSYSTEMD_ID128_CURRENT=0 +LIBSYSTEMD_ID128_REVISION=2 +LIBSYSTEMD_ID128_AGE=0 + +LIBSYSTEMD_JOURNAL_CURRENT=0 +LIBSYSTEMD_JOURNAL_REVISION=2 +LIBSYSTEMD_JOURNAL_AGE=0 + +# Dirs of external packages +dbuspolicydir=@dbuspolicydir@ +dbussessionservicedir=@dbussessionservicedir@ +dbussystemservicedir=@dbussystemservicedir@ +dbusinterfacedir=@dbusinterfacedir@ +udevrulesdir=@udevrulesdir@ +pamlibdir=@pamlibdir@ +pkgconfigdatadir=$(datadir)/pkgconfig +pkgconfiglibdir=$(libdir)/pkgconfig +polkitpolicydir=$(datadir)/polkit-1/actions +bashcompletiondir=$(sysconfdir)/bash_completion.d + +# Our own, non-special dirs +pkgsysconfdir=$(sysconfdir)/systemd +userunitdir=$(prefix)/lib/systemd/user +tmpfilesdir=$(prefix)/lib/tmpfiles.d +sysctldir=$(prefix)/lib/sysctl.d +usergeneratordir=$(pkglibexecdir)/user-generators +pkgincludedir=$(includedir)/systemd + +# And these are the special ones for / +rootprefix=@rootprefix@ +rootbindir=$(rootprefix)/bin +rootlibexecdir=$(rootprefix)/lib/systemd +systemgeneratordir=$(rootlibexecdir)/system-generators +systemshutdowndir=$(rootlibexecdir)/system-shutdown +systemunitdir=$(rootprefix)/lib/systemd/system + +CLEANFILES = +EXTRA_DIST = +INSTALL_EXEC_HOOKS = +UNINSTALL_EXEC_HOOKS = +INSTALL_DATA_HOOKS = +pkginclude_HEADERS = +lib_LTLIBRARIES = +pkgconfiglib_DATA = +polkitpolicy_in_files = +dist_udevrules_DATA = + +AM_CPPFLAGS = \ + -include $(top_builddir)/config.h \ + -DSYSTEM_CONFIG_FILE=\"$(pkgsysconfdir)/system.conf\" \ + -DSYSTEM_CONFIG_UNIT_PATH=\"$(pkgsysconfdir)/system\" \ + -DSYSTEM_DATA_UNIT_PATH=\"$(systemunitdir)\" \ + -DSYSTEM_SYSVINIT_PATH=\"$(SYSTEM_SYSVINIT_PATH)\" \ + -DSYSTEM_SYSVRCND_PATH=\"$(SYSTEM_SYSVRCND_PATH)\" \ + -DUSER_CONFIG_FILE=\"$(pkgsysconfdir)/user.conf\" \ + -DUSER_CONFIG_UNIT_PATH=\"$(pkgsysconfdir)/user\" \ + -DUSER_DATA_UNIT_PATH=\"$(userunitdir)\" \ + -DSYSTEMD_CGROUP_AGENT_PATH=\"$(rootlibexecdir)/systemd-cgroups-agent\" \ + -DSYSTEMD_BINARY_PATH=\"$(rootlibexecdir)/systemd\" \ + -DSYSTEMD_SHUTDOWN_BINARY_PATH=\"$(rootlibexecdir)/systemd-shutdown\" \ + -DSYSTEMCTL_BINARY_PATH=\"$(rootbindir)/systemctl\" \ + -DSYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH=\"$(rootbindir)/systemd-tty-ask-password-agent\" \ + -DSYSTEMD_STDIO_BRIDGE_BINARY_PATH=\"$(bindir)/systemd-stdio-bridge\" \ + -DROOTPREFIX=\"$(rootprefix)\" \ + -DRUNTIME_DIR=\"/run\" \ + -DRANDOM_SEED=\"$(localstatedir)/lib/random-seed\" \ + -DSYSTEMD_CRYPTSETUP_PATH=\"$(rootlibexecdir)/systemd-cryptsetup\" \ + -DSYSTEM_GENERATOR_PATH=\"$(systemgeneratordir)\" \ + -DUSER_GENERATOR_PATH=\"$(usergeneratordir)\" \ + -DSYSTEM_SHUTDOWN_PATH=\"$(systemshutdowndir)\" \ + -DSYSTEMD_KBD_MODEL_MAP=\"$(pkgdatadir)/kbd-model-map\" \ + -DX_SERVER=\"$(bindir)/X\" \ + -I $(top_srcdir)/src \ + -I $(top_srcdir)/src/readahead \ + -I $(top_srcdir)/src/login \ + -I $(top_srcdir)/src/journal \ + -I $(top_srcdir)/src/systemd + +if TARGET_GENTOO +AM_CPPFLAGS += \ + -DKBD_LOADKEYS=\"/usr/bin/loadkeys\" \ + -DKBD_SETFONT=\"/usr/bin/setfont\" \ + -DDEFAULT_FONT=\"LatArCyrHeb-16\" +else +if TARGET_ARCH +AM_CPPFLAGS += \ + -DKBD_LOADKEYS=\"/usr/bin/loadkeys\" \ + -DKBD_SETFONT=\"/usr/bin/setfont\" \ + -DDEFAULT_FONT=\"LatArCyrHeb-16\" +else +if TARGET_FRUGALWARE +AM_CPPFLAGS += \ + -DKBD_LOADKEYS=\"/usr/bin/loadkeys\" \ + -DKBD_SETFONT=\"/usr/bin/setfont\" \ + -DDEFAULT_FONT=\"LatArCyrHeb-16\" +else +if TARGET_MANDRIVA +AM_CPPFLAGS += \ + -DKBD_LOADKEYS=\"/bin/loadkeys\" \ + -DKBD_SETFONT=\"/bin/setfont\" \ + -DDEFAULT_FONT=\"LatArCyrHeb-16\" +else +if TARGET_MEEGO +AM_CPPFLAGS += \ + -DKBD_LOADKEYS=\"/bin/loadkeys\" \ + -DKBD_SETFONT=\"/bin/setfont\" \ + -DDEFAULT_FONT=\"LatArCyrHeb-16\" +else +if TARGET_ANGSTROM +AM_CPPFLAGS += \ + -DKBD_LOADKEYS=\"/usr/bin/loadkeys\" \ + -DKBD_SETFONT=\"/usr/bin/setfont\" \ + -DDEFAULT_FONT=\"LatArCyrHeb-16\" +else +if TARGET_MAGEIA +AM_CPPFLAGS += \ + -DKBD_LOADKEYS=\"/bin/loadkeys\" \ + -DKBD_SETFONT=\"/bin/setfont\" \ + -DDEFAULT_FONT=\"LatArCyrHeb-16\" +else +AM_CPPFLAGS += \ + -DKBD_LOADKEYS=\"/bin/loadkeys\" \ + -DKBD_SETFONT=\"/bin/setfont\" \ + -DDEFAULT_FONT=\"latarcyrheb-sun16\" +endif +endif +endif +endif +endif +endif +endif + +rootbin_PROGRAMS = \ + systemctl \ + systemd-notify \ + systemd-ask-password \ + systemd-tty-ask-password-agent \ + systemd-tmpfiles \ + systemd-machine-id-setup + +bin_PROGRAMS = \ + systemd-cgls \ + systemd-cgtop \ + systemd-stdio-bridge \ + systemd-nspawn + +dist_bin_SCRIPTS = \ + src/systemd-analyze + +if HAVE_GTK +bin_PROGRAMS += \ + systemadm \ + systemd-gnome-ask-password-agent +endif + +rootlibexec_PROGRAMS = \ + systemd \ + systemd-cgroups-agent \ + systemd-initctl \ + systemd-update-utmp \ + systemd-shutdownd \ + systemd-shutdown \ + systemd-modules-load \ + systemd-remount-api-vfs \ + systemd-reply-password \ + systemd-fsck \ + systemd-timestamp \ + systemd-ac-power \ + systemd-detect-virt \ + systemd-sysctl + +systemgenerator_PROGRAMS = \ + systemd-getty-generator + +noinst_PROGRAMS = \ + test-engine \ + test-job-type \ + test-ns \ + test-loopback \ + test-hostname \ + test-daemon \ + test-cgroup \ + test-env-replace \ + test-strv \ + test-install + +dist_pkgsysconf_DATA = \ + src/system.conf \ + src/user.conf + +dist_dbuspolicy_DATA = \ + src/org.freedesktop.systemd1.conf + +dist_dbussystemservice_DATA = \ + src/org.freedesktop.systemd1.service + +nodist_udevrules_DATA = \ + src/99-systemd.rules + +dbusinterface_DATA = \ + org.freedesktop.systemd1.Manager.xml \ + org.freedesktop.systemd1.Job.xml \ + org.freedesktop.systemd1.Unit.xml \ + org.freedesktop.systemd1.Service.xml \ + org.freedesktop.systemd1.Socket.xml \ + org.freedesktop.systemd1.Timer.xml \ + org.freedesktop.systemd1.Target.xml \ + org.freedesktop.systemd1.Device.xml \ + org.freedesktop.systemd1.Mount.xml \ + org.freedesktop.systemd1.Automount.xml \ + org.freedesktop.systemd1.Snapshot.xml \ + org.freedesktop.systemd1.Swap.xml \ + org.freedesktop.systemd1.Path.xml + +dist_bashcompletion_DATA = \ + src/systemd-bash-completion.sh + +dist_tmpfiles_DATA = \ + tmpfiles.d/systemd.conf \ + tmpfiles.d/tmp.conf \ + tmpfiles.d/x11.conf + +if HAVE_SYSV_COMPAT +dist_tmpfiles_DATA += \ + tmpfiles.d/legacy.conf +endif + +dist_systemunit_DATA = \ + units/graphical.target \ + units/multi-user.target \ + units/emergency.service \ + units/emergency.target \ + units/sysinit.target \ + units/basic.target \ + units/getty.target \ + units/halt.target \ + units/kexec.target \ + units/local-fs.target \ + units/local-fs-pre.target \ + units/remote-fs.target \ + units/remote-fs-pre.target \ + units/network.target \ + units/nss-lookup.target \ + units/mail-transfer-agent.target \ + units/http-daemon.target \ + units/poweroff.target \ + units/reboot.target \ + units/rescue.target \ + units/rpcbind.target \ + units/time-sync.target \ + units/shutdown.target \ + units/final.target \ + units/umount.target \ + units/sigpwr.target \ + units/sockets.target \ + units/swap.target \ + units/systemd-initctl.socket \ + units/systemd-shutdownd.socket \ + units/syslog.socket \ + units/dev-hugepages.mount \ + units/dev-mqueue.mount \ + units/sys-kernel-config.mount \ + units/sys-kernel-debug.mount \ + units/sys-kernel-security.mount \ + units/sys-fs-fuse-connections.mount \ + units/var-run.mount \ + units/media.mount \ + units/remount-rootfs.service \ + units/printer.target \ + units/sound.target \ + units/bluetooth.target \ + units/smartcard.target \ + units/systemd-tmpfiles-clean.timer \ + units/quotaon.service \ + units/systemd-ask-password-wall.path \ + units/systemd-ask-password-console.path \ + units/syslog.target + +if HAVE_SYSV_COMPAT +dist_systemunit_DATA += \ + units/var-lock.mount +endif + +nodist_systemunit_DATA = \ + units/getty@.service \ + units/serial-getty@.service \ + units/console-shell.service \ + units/systemd-initctl.service \ + units/systemd-shutdownd.service \ + units/systemd-modules-load.service \ + units/systemd-remount-api-vfs.service \ + units/systemd-update-utmp-runlevel.service \ + units/systemd-update-utmp-shutdown.service \ + units/systemd-tmpfiles-setup.service \ + units/systemd-tmpfiles-clean.service \ + units/systemd-ask-password-wall.service \ + units/systemd-ask-password-console.service \ + units/systemd-sysctl.service \ + units/halt.service \ + units/poweroff.service \ + units/reboot.service \ + units/kexec.service \ + units/fsck@.service \ + units/fsck-root.service \ + units/rescue.service \ + units/user@.service + +dist_userunit_DATA = \ + units/user/default.target \ + units/user/exit.target + +nodist_userunit_DATA = \ + units/user/exit.service + +EXTRA_DIST += \ + units/getty@.service.m4 \ + units/serial-getty@.service.m4 \ + units/console-shell.service.m4 \ + units/rescue.service.m4 \ + units/systemd-initctl.service.in \ + units/systemd-shutdownd.service.in \ + units/systemd-modules-load.service.in \ + units/systemd-remount-api-vfs.service.in \ + units/systemd-update-utmp-runlevel.service.in \ + units/systemd-update-utmp-shutdown.service.in \ + units/systemd-tmpfiles-setup.service.in \ + units/systemd-tmpfiles-clean.service.in \ + units/systemd-ask-password-wall.service.in \ + units/systemd-ask-password-console.service.in \ + units/systemd-sysctl.service.in \ + units/halt.service.in \ + units/poweroff.service.in \ + units/reboot.service.in \ + units/kexec.service.in \ + units/user/exit.service.in \ + units/fsck@.service.in \ + units/fsck-root.service.in \ + units/user@.service.in \ + src/systemd.pc.in \ + introspect.awk \ + src/99-systemd.rules.in \ + man/custom-html.xsl + +if TARGET_FEDORA +dist_systemunit_DATA += \ + units/fedora/prefdm.service \ + units/fedora/rc-local.service \ + units/fedora/halt-local.service +systemgenerator_PROGRAMS += \ + systemd-rc-local-generator +endif + +if TARGET_MANDRIVA +dist_systemunit_DATA += \ + units/mandriva/prefdm.service \ + units/fedora/rc-local.service \ + units/fedora/halt-local.service +systemgenerator_PROGRAMS += \ + systemd-rc-local-generator +endif + +if TARGET_FRUGALWARE +dist_systemunit_DATA += \ + units/frugalware/display-manager.service +endif + +if TARGET_SUSE +dist_systemunit_DATA += \ + units/suse/rc-local.service \ + units/suse/halt-local.service +systemgenerator_PROGRAMS += \ + systemd-rc-local-generator +endif + +if TARGET_MAGEIA +dist_systemunit_DATA += \ + units/mageia/prefdm.service \ + units/fedora/rc-local.service \ + units/fedora/halt-local.service +systemgenerator_PROGRAMS += \ + systemd-rc-local-generator +endif + +if HAVE_PLYMOUTH +dist_systemunit_DATA += \ + units/plymouth-start.service \ + units/plymouth-read-write.service \ + units/plymouth-quit.service \ + units/plymouth-quit-wait.service \ + units/plymouth-reboot.service \ + units/plymouth-kexec.service \ + units/plymouth-poweroff.service \ + units/plymouth-halt.service \ + units/systemd-ask-password-plymouth.path + +nodist_systemunit_DATA += \ + units/systemd-ask-password-plymouth.service + +EXTRA_DIST += \ + units/systemd-ask-password-plymouth.service.in +endif + +dist_doc_DATA = \ + README \ + NEWS \ + LICENSE \ + DISTRO_PORTING + +pkgconfigdata_DATA = \ + src/systemd.pc + +# First passed through sed, followed by intltool +polkitpolicy_in_in_files = \ + src/org.freedesktop.systemd1.policy.in.in + +nodist_polkitpolicy_DATA = \ + $(polkitpolicy_in_files:.policy.in=.policy) \ + $(polkitpolicy_in_in_files:.policy.in.in=.policy) + +EXTRA_DIST += \ + $(polkitpolicy_in_files) \ + $(polkitpolicy_in_in_files) + +@INTLTOOL_POLICY_RULE@ + +noinst_LTLIBRARIES = \ + libsystemd-basic.la \ + libsystemd-core.la + +libsystemd_basic_la_SOURCES = \ + src/util.c \ + src/virt.c \ + src/label.c \ + src/hashmap.c \ + src/set.c \ + src/strv.c \ + src/conf-parser.c \ + src/socket-util.c \ + src/log.c \ + src/ratelimit.c \ + src/exit-status.c + +libsystemd_basic_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(SELINUX_CFLAGS) + +libsystemd_basic_la_LIBADD = \ + $(SELINUX_LIBS) \ + $(CAP_LIBS) + +libsystemd_core_la_SOURCES = \ + src/unit.c \ + src/job.c \ + src/manager.c \ + src/path-lookup.c \ + src/load-fragment.c \ + src/service.c \ + src/automount.c \ + src/mount.c \ + src/swap.c \ + src/device.c \ + src/target.c \ + src/snapshot.c \ + src/socket.c \ + src/timer.c \ + src/path.c \ + src/load-dropin.c \ + src/execute.c \ + src/utmp-wtmp.c \ + src/dbus.c \ + src/dbus-manager.c \ + src/dbus-unit.c \ + src/dbus-job.c \ + src/dbus-service.c \ + src/dbus-socket.c \ + src/dbus-timer.c \ + src/dbus-target.c \ + src/dbus-mount.c \ + src/dbus-automount.c \ + src/dbus-swap.c \ + src/dbus-snapshot.c \ + src/dbus-device.c \ + src/dbus-execute.c \ + src/dbus-path.c \ + src/cgroup.c \ + src/mount-setup.c \ + src/hostname-setup.c \ + src/selinux-setup.c \ + src/loopback-setup.c \ + src/kmod-setup.c \ + src/locale-setup.c \ + src/machine-id-setup.c \ + src/specifier.c \ + src/unit-name.c \ + src/fdset.c \ + src/namespace.c \ + src/tcpwrap.c \ + src/cgroup-util.c \ + src/condition.c \ + src/dbus-common.c \ + src/sd-daemon.c \ + src/install.c \ + src/cgroup-attr.c \ + src/sd-id128.c + +nodist_libsystemd_core_la_SOURCES = \ + src/load-fragment-gperf.c \ + src/load-fragment-gperf-nulstr.c + +EXTRA_DIST += \ + src/load-fragment-gperf.gperf.m4 + +libsystemd_core_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(UDEV_CFLAGS) \ + $(LIBWRAP_CFLAGS) \ + $(PAM_CFLAGS) \ + $(AUDIT_CFLAGS) \ + $(KMOD_CFLAGS) + +libsystemd_core_la_LIBADD = \ + libsystemd-basic.la \ + $(DBUS_LIBS) \ + $(UDEV_LIBS) \ + $(LIBWRAP_LIBS) \ + $(PAM_LIBS) \ + $(AUDIT_LIBS) \ + $(CAP_LIBS) \ + $(KMOD_LIBS) + +# This is needed because automake is buggy in how it generates the +# rules for C programs, but not Vala programs. We therefore can't +# list the .h files as dependencies if we want make dist to work. + +EXTRA_DIST += \ + src/util.h \ + src/virt.h \ + src/label.h \ + src/hashmap.h \ + src/set.h \ + src/strv.h \ + src/conf-parser.h \ + src/socket-util.h \ + src/log.h \ + src/ratelimit.h \ + src/exit-status.h \ + src/unit.h \ + src/job.h \ + src/manager.h \ + src/path-lookup.h \ + src/load-fragment.h \ + src/service.h \ + src/automount.h \ + src/mount.h \ + src/swap.h \ + src/device.h \ + src/target.h \ + src/snapshot.h \ + src/socket.h \ + src/timer.h \ + src/path.h \ + src/load-dropin.h \ + src/execute.h \ + src/utmp-wtmp.h \ + src/dbus.h \ + src/dbus-manager.h \ + src/dbus-unit.h \ + src/dbus-job.h \ + src/dbus-service.h \ + src/dbus-socket.h \ + src/dbus-timer.h \ + src/dbus-target.h \ + src/dbus-mount.h \ + src/dbus-automount.h \ + src/dbus-swap.h \ + src/dbus-snapshot.h \ + src/dbus-device.h \ + src/dbus-execute.h \ + src/dbus-path.h \ + src/cgroup.h \ + src/mount-setup.h \ + src/hostname-setup.h \ + src/selinux-setup.h \ + src/loopback-setup.h \ + src/kmod-setup.h \ + src/locale-setup.h \ + src/machine-id-setup.h \ + src/specifier.h \ + src/unit-name.h \ + src/fdset.h \ + src/namespace.h \ + src/tcpwrap.h \ + src/cgroup-util.h \ + src/condition.h \ + src/dbus-common.h \ + src/install.h \ + src/cgroup-attr.h \ + src/macro.h \ + src/def.h \ + src/ioprio.h \ + src/missing.h \ + src/list.h \ + src/securebits.h \ + src/linux/auto_dev-ioctl.h \ + src/linux/fanotify.h \ + src/initreq.h \ + src/special.h \ + src/dbus-common.h \ + src/bus-errors.h \ + src/cgroup-show.h \ + src/build.h \ + src/shutdownd.h \ + src/umount.h \ + src/ask-password-api.h \ + src/pager.h \ + src/sysfs-show.h \ + src/polkit.h \ + src/dbus-loop.h \ + src/spawn-agent.h \ + src/acl-util.h \ + src/logs-show.h + +MANPAGES = \ + man/systemd.1 \ + man/systemctl.1 \ + man/systemadm.1 \ + man/systemd-cgls.1 \ + man/systemd-cgtop.1 \ + man/systemd-nspawn.1 \ + man/systemd-tmpfiles.8 \ + man/systemd-notify.1 \ + man/systemd.unit.5 \ + man/systemd.service.5 \ + man/systemd.socket.5 \ + man/systemd.mount.5 \ + man/systemd.automount.5 \ + man/systemd.swap.5 \ + man/systemd.timer.5 \ + man/systemd.path.5 \ + man/systemd.target.5 \ + man/systemd.device.5 \ + man/systemd.snapshot.5 \ + man/systemd.exec.5 \ + man/daemon.7 \ + man/runlevel.8 \ + man/telinit.8 \ + man/halt.8 \ + man/shutdown.8 \ + man/pam_systemd.8 \ + man/systemd.conf.5 \ + man/tmpfiles.d.5 \ + man/hostname.5 \ + man/timezone.5 \ + man/machine-id.5 \ + man/locale.conf.5 \ + man/os-release.5 \ + man/machine-info.5 \ + man/modules-load.d.5 \ + man/sysctl.d.5 \ + man/systemd-ask-password.1 + +MANPAGES_ALIAS = \ + man/reboot.8 \ + man/poweroff.8 \ + man/init.1 + +man/reboot.8: man/halt.8 +man/poweroff.8: man/halt.8 +man/init.1: man/systemd.1 + +if ENABLE_MANPAGES +dist_man_MANS = \ + $(MANPAGES) \ + $(MANPAGES_ALIAS) + +nodist_man_MANS = \ + man/systemd.special.7 + +XML_FILES = \ + ${patsubst %.1,%.xml,${patsubst %.3,%.xml,${patsubst %.5,%.xml,${patsubst %.7,%.xml,${patsubst %.8,%.xml,$(MANPAGES)}}}}} + +XML_IN_FILES = \ + ${patsubst %.1,%.xml.in,${patsubst %.3,%.xml.in,${patsubst %.5,%.xml.in,${patsubst %.7,%.xml.in,${patsubst %.8,%.xml.in,$(nodist_man_MANS)}}}}} + +dist_noinst_DATA = \ + ${XML_FILES:.xml=.html} + +nodist_noinst_DATA = \ + ${XML_IN_FILES:.xml.in=.html} + +EXTRA_DIST += \ + $(XML_FILES) \ + $(XML_IN_FILES) \ + ${nodist_man_MANS:=.in} \ + ${XML_IN_FILES:.xml.in=.html.in} +endif + +systemd_SOURCES = \ + src/main.c + +systemd_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(UDEV_CFLAGS) + +systemd_LDADD = \ + libsystemd-core.la + +test_engine_SOURCES = \ + src/test-engine.c + +test_engine_CFLAGS = $(systemd_CFLAGS) +test_engine_LDADD = $(systemd_LDADD) + +test_job_type_SOURCES = \ + src/test-job-type.c + +test_job_type_CFLAGS = $(systemd_CFLAGS) +test_job_type_LDADD = $(systemd_LDADD) + +test_ns_SOURCES = \ + src/test-ns.c + +test_ns_CFLAGS = $(systemd_CFLAGS) +test_ns_LDADD = $(systemd_LDADD) + +test_loopback_SOURCES = \ + src/test-loopback.c \ + src/loopback-setup.c + +test_loopback_LDADD = \ + libsystemd-basic.la + +test_hostname_SOURCES = \ + src/test-hostname.c \ + src/hostname-setup.c + +test_hostname_LDADD = \ + libsystemd-basic.la + +test_daemon_SOURCES = \ + src/test-daemon.c + +test_daemon_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la + +test_cgroup_SOURCES = \ + src/test-cgroup.c \ + src/cgroup-util.c + +test_cgroup_LDADD = \ + libsystemd-basic.la + +test_env_replace_SOURCES = \ + src/test-env-replace.c + +test_env_replace_LDADD = \ + libsystemd-basic.la + +test_strv_SOURCES = \ + src/test-strv.c \ + src/specifier.c + +test_strv_LDADD = \ + libsystemd-basic.la + +test_install_SOURCES = \ + src/test-install.c \ + src/install.c \ + src/path-lookup.c \ + src/unit-name.c + +test_install_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +test_install_LDADD = \ + libsystemd-basic.la + +systemd_initctl_SOURCES = \ + src/initctl.c \ + src/dbus-common.c + +systemd_initctl_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_initctl_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la \ + $(DBUS_LIBS) + +systemd_update_utmp_SOURCES = \ + src/update-utmp.c \ + src/dbus-common.c \ + src/utmp-wtmp.c + +systemd_update_utmp_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(AUDIT_CFLAGS) + +systemd_update_utmp_LDADD = \ + libsystemd-basic.la \ + $(DBUS_LIBS) \ + $(AUDIT_LIBS) + +systemd_shutdownd_SOURCES = \ + src/utmp-wtmp.c \ + src/shutdownd.c + +systemd_shutdownd_CFLAGS = \ + $(AM_CFLAGS) + +systemd_shutdownd_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la + +systemd_shutdown_SOURCES = \ + src/mount-setup.c \ + src/umount.c \ + src/shutdown.c + +systemd_shutdown_CFLAGS = \ + $(AM_CFLAGS) \ + $(UDEV_CFLAGS) + +systemd_shutdown_LDADD = \ + libsystemd-basic.la \ + $(UDEV_LIBS) + +systemd_modules_load_SOURCES = \ + src/modules-load.c + +systemd_modules_load_CFLAGS = \ + $(KMOD_CFLAGS) + +systemd_modules_load_LDADD = \ + libsystemd-basic.la \ + $(KMOD_LIBS) + +systemd_tmpfiles_SOURCES = \ + src/tmpfiles.c + +systemd_tmpfiles_LDADD = \ + libsystemd-basic.la + +systemd_machine_id_setup_SOURCES = \ + src/machine-id-setup.c \ + src/machine-id-main.c \ + src/sd-id128.c + +systemd_machine_id_setup_LDADD = \ + libsystemd-basic.la + +systemd_sysctl_SOURCES = \ + src/sysctl.c + +systemd_sysctl_LDADD = \ + libsystemd-basic.la + +systemd_fsck_SOURCES = \ + src/fsck.c \ + src/dbus-common.c + +systemd_fsck_CFLAGS = \ + $(AM_CFLAGS) \ + $(UDEV_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_fsck_LDADD = \ + libsystemd-basic.la \ + $(UDEV_LIBS) \ + $(DBUS_LIBS) + +systemd_timestamp_SOURCES = \ + src/timestamp.c + +systemd_timestamp_LDADD = \ + libsystemd-basic.la + +systemd_ac_power_SOURCES = \ + src/ac-power.c + +systemd_ac_power_CFLAGS = \ + $(AM_CFLAGS) \ + $(UDEV_CFLAGS) + +systemd_ac_power_LDADD = \ + libsystemd-basic.la \ + $(UDEV_LIBS) + +systemd_detect_virt_SOURCES = \ + src/detect-virt.c + +systemd_detect_virt_LDADD = \ + libsystemd-basic.la + +systemd_getty_generator_SOURCES = \ + src/getty-generator.c \ + src/unit-name.c + +systemd_getty_generator_LDADD = \ + libsystemd-basic.la + +systemd_rc_local_generator_SOURCES = \ + src/rc-local-generator.c + +systemd_rc_local_generator_LDADD = \ + libsystemd-basic.la + +systemd_remount_api_vfs_SOURCES = \ + src/remount-api-vfs.c \ + src/mount-setup.c \ + src/exit-status.c + +systemd_remount_api_vfs_LDADD = \ + libsystemd-basic.la + +systemd_cgroups_agent_SOURCES = \ + src/cgroups-agent.c \ + src/dbus-common.c + +systemd_cgroups_agent_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_cgroups_agent_LDADD = \ + libsystemd-basic.la \ + $(DBUS_LIBS) + +systemctl_SOURCES = \ + src/systemctl.c \ + src/utmp-wtmp.c \ + src/dbus-common.c \ + src/path-lookup.c \ + src/cgroup-show.c \ + src/cgroup-util.c \ + src/exit-status.c \ + src/unit-name.c \ + src/pager.c \ + src/install.c \ + src/spawn-agent.c \ + src/logs-show.c + +systemctl_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemctl_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la \ + libsystemd-journal.la \ + libsystemd-id128.la \ + $(DBUS_LIBS) + +systemd_notify_SOURCES = \ + src/notify.c \ + src/readahead/sd-readahead.c + +systemd_notify_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la + +systemd_ask_password_SOURCES = \ + src/ask-password.c \ + src/ask-password-api.c + +systemd_ask_password_LDADD = \ + libsystemd-basic.la + +systemd_reply_password_SOURCES = \ + src/reply-password.c + +systemd_reply_password_LDADD = \ + libsystemd-basic.la + +systemd_cgls_SOURCES = \ + src/cgls.c \ + src/cgroup-show.c \ + src/cgroup-util.c \ + src/pager.c + +systemd_cgls_LDADD = \ + libsystemd-basic.la + +systemd_cgtop_SOURCES = \ + src/cgtop.c \ + src/cgroup-util.c + +systemd_cgtop_LDADD = \ + libsystemd-basic.la + +systemd_nspawn_SOURCES = \ + src/nspawn.c \ + src/cgroup-util.c \ + src/loopback-setup.c + +systemd_nspawn_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la + +systemd_stdio_bridge_SOURCES = \ + src/bridge.c + +systemd_stdio_bridge_LDADD = \ + libsystemd-basic.la + +systemadm_SOURCES = \ + src/systemadm.vala \ + src/systemd-interfaces.vala \ + src/wraplabel.vala + +systemadm_CFLAGS = \ + $(AM_CFLAGS) \ + $(GTK_CFLAGS) \ + -Wno-unused-variable \ + -Wno-unused-function \ + -Wno-shadow \ + -Wno-format-nonliteral + +systemadm_VALAFLAGS = \ + --pkg=posix \ + --pkg=gtk+-2.0 \ + --pkg=gee-1.0 \ + -g + +systemadm_LDADD = \ + $(GTK_LIBS) + +systemd_gnome_ask_password_agent_SOURCES = \ + src/gnome-ask-password-agent.vala + +systemd_gnome_ask_password_agent_CFLAGS = \ + $(AM_CFLAGS) \ + $(LIBNOTIFY_CFLAGS) \ + $(GTK_CFLAGS) \ + -Wno-unused-variable \ + -Wno-unused-function \ + -Wno-shadow \ + -Wno-format-nonliteral + +systemd_gnome_ask_password_agent_VALAFLAGS = \ + --pkg=posix \ + --pkg=gtk+-2.0 \ + --pkg=linux \ + --pkg=gio-unix-2.0 \ + --pkg=libnotify \ + -g + +systemd_gnome_ask_password_agent_LDADD = \ + $(LIBNOTIFY_LIBS) \ + $(GTK_LIBS) + +systemd_tty_ask_password_agent_SOURCES = \ + src/tty-ask-password-agent.c \ + src/ask-password-api.c \ + src/utmp-wtmp.c + +systemd_tty_ask_password_agent_LDADD = \ + libsystemd-basic.la + +# ------------------------------------------------------------------------------ +libsystemd_daemon_la_SOURCES = \ + src/sd-daemon.c + +libsystemd_daemon_la_CFLAGS = \ + $(AM_CFLAGS) \ + -fvisibility=hidden \ + -DSD_EXPORT_SYMBOLS + +libsystemd_daemon_la_LDFLAGS = \ + -shared \ + -version-info $(LIBSYSTEMD_DAEMON_CURRENT):$(LIBSYSTEMD_DAEMON_REVISION):$(LIBSYSTEMD_DAEMON_AGE) \ + -Wl,--version-script=$(top_srcdir)/src/libsystemd-daemon.sym + +pkginclude_HEADERS += \ + src/systemd/sd-daemon.h + +# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed +libsystemd-daemon-install-hook: + if test "$(libdir)" != "$(rootlibdir)"; then \ + mkdir -p $(DESTDIR)$(rootlibdir) && \ + so_img_name=$$(readlink $(DESTDIR)$(libdir)/libsystemd-daemon.so) && \ + so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \ + ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libsystemd-daemon.so && \ + mv $(DESTDIR)$(libdir)/libsystemd-daemon.so.* $(DESTDIR)$(rootlibdir); \ + fi + +INSTALL_EXEC_HOOKS += \ + libsystemd-daemon-install-hook + +libsystemd-daemon-uninstall-hook: + rm -f $(DESTDIR)$(rootlibdir)/libsystemd-daemon.so* + +UNINSTALL_EXEC_HOOKS += \ + libsystemd-daemon-uninstall-hook + +lib_LTLIBRARIES += \ + libsystemd-daemon.la + +pkgconfiglib_DATA += \ + src/libsystemd-daemon.pc + +MANPAGES += \ + man/sd-daemon.7 \ + man/sd_notify.3 \ + man/sd_listen_fds.3 \ + man/sd_is_fifo.3 \ + man/sd_booted.3 + +MANPAGES_ALIAS += \ + man/sd_is_socket.3 \ + man/sd_is_socket_unix.3 \ + man/sd_is_socket_inet.3 \ + man/sd_is_mq.3 \ + man/sd_notifyf.3 + +man/sd_is_socket.3: man/sd_is_fifo.3 +man/sd_is_socket_unix.3: man/sd_is_fifo.3 +man/sd_is_socket_inet.3: man/sd_is_fifo.3 +man/sd_is_mq.3: man/sd_is_fifo.3 +man/sd_notifyf.3: man/sd_notify.3 + +EXTRA_DIST += \ + src/libsystemd-daemon.pc.in \ + src/libsystemd-daemon.sym + +# ------------------------------------------------------------------------------ +libsystemd_id128_la_SOURCES = \ + src/sd-id128.c + +libsystemd_id128_la_CFLAGS = \ + $(AM_CFLAGS) \ + -fvisibility=hidden + +libsystemd_id128_la_LDFLAGS = \ + -shared \ + -version-info $(LIBSYSTEMD_ID128_CURRENT):$(LIBSYSTEMD_ID128_REVISION):$(LIBSYSTEMD_ID128_AGE) \ + -Wl,--version-script=$(top_srcdir)/src/libsystemd-id128.sym + +libsystemd_id128_la_LIBADD = \ + libsystemd-basic.la + +test_id128_SOURCES = \ + src/test-id128.c \ + src/sd-id128.c + +test_id128_LDADD = \ + libsystemd-basic.la + +noinst_PROGRAMS += \ + test-id128 + +pkginclude_HEADERS += \ + src/systemd/sd-id128.h + +lib_LTLIBRARIES += \ + libsystemd-id128.la + +pkgconfiglib_DATA += \ + src/libsystemd-id128.pc + +# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed +libsystemd-id128-install-hook: + if test "$(libdir)" != "$(rootlibdir)"; then \ + mkdir -p $(DESTDIR)$(rootlibdir) && \ + so_img_name=$$(readlink $(DESTDIR)$(libdir)/libsystemd-id128.so) && \ + so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \ + ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libsystemd-id128.so && \ + mv $(DESTDIR)$(libdir)/libsystemd-id128.so.* $(DESTDIR)$(rootlibdir); \ + fi + +INSTALL_EXEC_HOOKS += \ + libsystemd-id128-install-hook + +libsystemd-id128-uninstall-hook: + rm -f $(DESTDIR)$(rootlibdir)/libsystemd-id128.so* + +UNINSTALL_EXEC_HOOKS += \ + libsystemd-id128-uninstall-hook + +EXTRA_DIST += \ + src/libsystemd-id128.pc.in \ + src/libsystemd-id128.sym + +# ------------------------------------------------------------------------------ +systemd_journald_SOURCES = \ + src/journal/journald.c \ + src/journal/sd-journal.c \ + src/journal/journal-file.c \ + src/journal/lookup3.c \ + src/journal/journal-rate-limit.c \ + src/sd-id128.c \ + src/cgroup-util.c + +if HAVE_ACL +systemd_journald_SOURCES += \ + src/acl-util.c +endif + +nodist_systemd_journald_SOURCES = \ + src/journal/journald-gperf.c + +systemd_journald_CFLAGS = \ + $(AM_CFLAGS) \ + $(ACL_CFLAGS) + +systemd_journald_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la \ + libsystemd-login.la \ + $(ACL_LIBS) + +if HAVE_XZ +systemd_journald_SOURCES += \ + src/journal/compress.c +systemd_journald_CFLAGS += \ + $(XZ_CFLAGS) +systemd_journald_LDADD += \ + $(XZ_LIBS) +endif + +systemd_cat_SOURCES = \ + src/journal/cat.c + +systemd_cat_LDADD = \ + libsystemd-basic.la \ + libsystemd-journal.la + +systemd_journalctl_SOURCES = \ + src/journal/journalctl.c \ + src/pager.c \ + src/logs-show.c + +systemd_journalctl_LDADD = \ + libsystemd-basic.la \ + libsystemd-journal.la \ + libsystemd-id128.la + +if HAVE_XZ +systemd_journalctl_SOURCES += \ + src/journal/compress.c +systemd_journalctl_CFLAGS = \ + $(AM_CFLAGS) \ + $(XZ_CFLAGS) +systemd_journalctl_LDADD += \ + $(XZ_LIBS) +endif + +test_journal_SOURCES = \ + src/journal/test-journal.c \ + src/journal/sd-journal.c \ + src/journal/journal-file.c \ + src/journal/lookup3.c \ + src/journal/journal-send.c \ + src/sd-id128.c + +test_journal_LDADD = \ + libsystemd-basic.la + +if HAVE_XZ +test_journal_SOURCES += \ + src/journal/compress.c + +test_journal_CFLAGS = \ + $(AM_CFLAGS) \ + $(XZ_CFLAGS) + +test_journal_LDADD += \ + $(XZ_LIBS) +endif + +libsystemd_journal_la_SOURCES = \ + src/journal/sd-journal.c \ + src/journal/journal-file.c \ + src/journal/lookup3.c \ + src/journal/journal-send.c + +libsystemd_journal_la_CFLAGS = \ + $(AM_CFLAGS) \ + -fvisibility=hidden + +libsystemd_journal_la_LDFLAGS = \ + -shared \ + -version-info $(LIBSYSTEMD_JOURNAL_CURRENT):$(LIBSYSTEMD_JOURNAL_REVISION):$(LIBSYSTEMD_JOURNAL_AGE) \ + -Wl,--version-script=$(top_srcdir)/src/journal/libsystemd-journal.sym + +libsystemd_journal_la_LIBADD = \ + libsystemd-basic.la \ + libsystemd-id128.la + +if HAVE_XZ +libsystemd_journal_la_SOURCES += \ + src/journal/compress.c + +libsystemd_journal_la_CFLAGS += \ + $(XZ_CFLAGS) + +libsystemd_journal_la_LIBADD += \ + $(XZ_LIBS) +endif + +# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed +libsystemd-journal-install-hook: + if test "$(libdir)" != "$(rootlibdir)"; then \ + mkdir -p $(DESTDIR)$(rootlibdir) && \ + so_img_name=$$(readlink $(DESTDIR)$(libdir)/libsystemd-journal.so) && \ + so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \ + ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libsystemd-journal.so && \ + mv $(DESTDIR)$(libdir)/libsystemd-journal.so.* $(DESTDIR)$(rootlibdir); \ + fi + +INSTALL_EXEC_HOOKS += \ + libsystemd-journal-install-hook + +libsystemd-journal-uninstall-hook: + rm -f $(DESTDIR)$(rootlibdir)/libsystemd-journal.so* + +UNINSTALL_EXEC_HOOKS += \ + libsystemd-journal-uninstall-hook + +noinst_PROGRAMS += \ + test-journal + +pkginclude_HEADERS += \ + src/systemd/sd-journal.h \ + src/systemd/sd-messages.h + +lib_LTLIBRARIES += \ + libsystemd-journal.la + +rootlibexec_PROGRAMS += \ + systemd-journald + +rootbin_PROGRAMS += \ + systemd-journalctl + +bin_PROGRAMS += \ + systemd-cat + +dist_systemunit_DATA += \ + units/systemd-journald.socket + +nodist_systemunit_DATA += \ + units/systemd-journald.service + +dist_pkgsysconf_DATA += \ + src/journal/systemd-journald.conf + +pkgconfiglib_DATA += \ + src/journal/libsystemd-journal.pc + +journal-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(systemunitdir)/sockets.target.wants \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants + ( cd $(DESTDIR)$(systemunitdir)/sockets.target.wants && \ + rm -f systemd-journald.socket && \ + $(LN_S) ../systemd-journald.socket ) + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f systemd-journald.service && \ + $(LN_S) ../systemd-journald.service ) + +INSTALL_DATA_HOOKS += \ + journal-install-data-hook + +EXTRA_DIST += \ + src/journal/journald.h \ + src/journal/journal-def.h \ + src/journal/journal-internal.h \ + src/journal/journal-file.h \ + src/journal/lookup3.h \ + src/journal/compress.h \ + src/journal/journal-rate-limit.h \ + src/journal/libsystemd-journal.pc.in \ + src/journal/libsystemd-journal.sym \ + units/systemd-journald.service.in \ + src/journal/journald-gperf.gperf + +CLEANFILES += \ + src/journal/journald-gperf.c + +# ------------------------------------------------------------------------------ +if ENABLE_COREDUMP +systemd_coredump_SOURCES = \ + src/journal/coredump.c + +systemd_coredump_LDADD = \ + libsystemd-basic.la \ + libsystemd-journal.la \ + libsystemd-login.la + +rootlibexec_PROGRAMS += \ + systemd-coredump + +sysctl_DATA = \ + sysctl.d/coredump.conf + +EXTRA_DIST += \ + sysctl.d/coredump.conf.in + +CLEANFILES += \ + sysctl.d/coredump.conf +endif + +# ------------------------------------------------------------------------------ +if ENABLE_BINFMT +systemd_binfmt_SOURCES = \ + src/binfmt/binfmt.c + +systemd_binfmt_LDADD = \ + libsystemd-basic.la + +rootlibexec_PROGRAMS += \ + systemd-binfmt + +dist_systemunit_DATA += \ + units/proc-sys-fs-binfmt_misc.automount \ + units/proc-sys-fs-binfmt_misc.mount + +nodist_systemunit_DATA += \ + units/systemd-binfmt.service + +binfmt-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(prefix)/lib/binfmt.d \ + $(DESTDIR)$(sysconfdir)/binfmt.d \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f systemd-binfmt.service \ + proc-sys-fs-binfmt_misc.automount && \ + $(LN_S) ../systemd-binfmt.service systemd-binfmt.service && \ + $(LN_S) ../proc-sys-fs-binfmt_misc.automount proc-sys-fs-binfmt_misc.automount ) + +INSTALL_DATA_HOOKS += \ + binfmt-install-data-hook + +MANPAGES += \ + man/binfmt.d.5 + +EXTRA_DIST += \ + units/systemd-binfmt.service.in +endif + +# ------------------------------------------------------------------------------ +if ENABLE_VCONSOLE +systemd_vconsole_setup_SOURCES = \ + src/vconsole/vconsole-setup.c + +systemd_vconsole_setup_LDADD = \ + libsystemd-basic.la + +rootlibexec_PROGRAMS += \ + systemd-vconsole-setup + +nodist_systemunit_DATA += \ + units/systemd-vconsole-setup.service + +vconsole-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f systemd-vconsole-setup.service && \ + $(LN_S) ../systemd-vconsole-setup.service systemd-vconsole-setup.service ) + +INSTALL_DATA_HOOKS += \ + vconsole-install-data-hook + +MANPAGES += \ + man/vconsole.conf.5 + +EXTRA_DIST += \ + units/systemd-vconsole-setup.service.in +endif + +# ------------------------------------------------------------------------------ +if ENABLE_READAHEAD +systemd_readahead_collect_SOURCES = \ + src/readahead/readahead-collect.c \ + src/readahead/readahead-common.c + +systemd_readahead_collect_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la \ + $(UDEV_LIBS) + +systemd_readahead_collect_CFLAGS = \ + $(AM_CFLAGS) \ + $(UDEV_CFLAGS) + +systemd_readahead_replay_SOURCES = \ + src/readahead/readahead-replay.c \ + src/readahead/readahead-common.c + +systemd_readahead_replay_CFLAGS = \ + $(AM_CFLAGS) \ + $(UDEV_CFLAGS) + +systemd_readahead_replay_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la \ + $(UDEV_LIBS) + +rootlibexec_PROGRAMS += \ + systemd-readahead-collect \ + systemd-readahead-replay + +dist_systemunit_DATA += \ + units/systemd-readahead-done.timer + +nodist_systemunit_DATA += \ + units/systemd-readahead-collect.service \ + units/systemd-readahead-replay.service \ + units/systemd-readahead-done.service + +EXTRA_DIST += \ + src/systemd/sd-readahead.h \ + src/readahead/readahead-common.h \ + units/systemd-readahead-collect.service.in \ + units/systemd-readahead-replay.service.in \ + units/systemd-readahead-done.service.in + +MANPAGES += \ + man/sd_readahead.3 \ + man/sd-readahead.7 +endif + +# ------------------------------------------------------------------------------ +if ENABLE_QUOTACHECK +rootlibexec_PROGRAMS += \ + systemd-quotacheck + +nodist_systemunit_DATA += \ + units/quotacheck.service + +EXTRA_DIST += \ + units/quotacheck.service.in + +systemd_quotacheck_SOURCES = \ + src/quotacheck.c + +systemd_quotacheck_LDADD = \ + libsystemd-basic.la +endif + +# ------------------------------------------------------------------------------ +if ENABLE_RANDOMSEED +rootlibexec_PROGRAMS += \ + systemd-random-seed + +nodist_systemunit_DATA += \ + units/systemd-random-seed-save.service \ + units/systemd-random-seed-load.service + +EXTRA_DIST += \ + units/systemd-random-seed-save.service.in \ + units/systemd-random-seed-load.service.in + +systemd_random_seed_SOURCES = \ + src/random-seed.c + +systemd_random_seed_LDADD = \ + libsystemd-basic.la + +randomseed-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(systemunitdir)/shutdown.target.wants \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants + ( cd $(DESTDIR)$(systemunitdir)/shutdown.target.wants && \ + rm -f systemd-random-seed-save.service && \ + $(LN_S) ../systemd-random-seed-save.service systemd-random-seed-save.service ) + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f systemd-random-seed-load.service && \ + $(LN_S) ../systemd-random-seed-load.service systemd-random-seed-load.service ) + +INSTALL_DATA_HOOKS += \ + randomseed-install-data-hook +endif + +# ------------------------------------------------------------------------------ +if HAVE_LIBCRYPTSETUP +rootlibexec_PROGRAMS += \ + systemd-cryptsetup + +systemgenerator_PROGRAMS += \ + systemd-cryptsetup-generator + +dist_systemunit_DATA += \ + units/cryptsetup.target + +systemd_cryptsetup_SOURCES = \ + src/cryptsetup/cryptsetup.c \ + src/ask-password-api.c + +systemd_cryptsetup_CFLAGS = \ + $(AM_CFLAGS) \ + $(LIBCRYPTSETUP_CFLAGS) \ + $(UDEV_CFLAGS) + +systemd_cryptsetup_LDADD = \ + $(LIBCRYPTSETUP_LIBS) \ + $(UDEV_LIBS) \ + libsystemd-basic.la + +systemd_cryptsetup_generator_SOURCES = \ + src/cryptsetup/cryptsetup-generator.c \ + src/unit-name.c + +systemd_cryptsetup_generator_LDADD = \ + libsystemd-basic.la + +cryptsetup-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f cryptsetup.target && \ + $(LN_S) ../cryptsetup.target cryptsetup.target ) + +INSTALL_DATA_HOOKS += \ + cryptsetup-install-data-hook +endif + +# ------------------------------------------------------------------------------ +if ENABLE_HOSTNAMED +systemd_hostnamed_SOURCES = \ + src/hostname/hostnamed.c \ + src/dbus-common.c \ + src/polkit.c + +systemd_hostnamed_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_hostnamed_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la \ + $(DBUS_LIBS) + +rootlibexec_PROGRAMS += \ + systemd-hostnamed + +nodist_systemunit_DATA += \ + units/systemd-hostnamed.service + +dist_dbuspolicy_DATA += \ + src/hostname/org.freedesktop.hostname1.conf + +dist_dbussystemservice_DATA += \ + src/hostname/org.freedesktop.hostname1.service + +polkitpolicy_in_files += \ + src/hostname/org.freedesktop.hostname1.policy.in + +dbusinterface_DATA += \ + org.freedesktop.hostname1.xml + +org.freedesktop.hostname1.xml: systemd-hostnamed + $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.hostname1 $< $@.tmp && \ + $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \ + $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp + +hostnamed-install-data-hook: + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f dbus-org.freedesktop.hostname1.service && \ + $(LN_S) systemd-hostnamed.service dbus-org.freedesktop.hostname1.service ) + +INSTALL_DATA_HOOKS += \ + hostnamed-install-data-hook + +EXTRA_DIST += \ + units/systemd-hostnamed.service.in +endif + +# ------------------------------------------------------------------------------ +if ENABLE_LOCALED +systemd_localed_SOURCES = \ + src/locale/localed.c \ + src/dbus-common.c \ + src/polkit.c + +systemd_localed_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_localed_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la \ + $(DBUS_LIBS) + +nodist_systemunit_DATA += \ + units/systemd-localed.service + +rootlibexec_PROGRAMS += \ + systemd-localed + +dist_dbuspolicy_DATA += \ + src/locale/org.freedesktop.locale1.conf + +dist_dbussystemservice_DATA += \ + src/locale/org.freedesktop.locale1.service + +polkitpolicy_in_files += \ + src/locale/org.freedesktop.locale1.policy.in + +dbusinterface_DATA += \ + org.freedesktop.locale1.xml + +org.freedesktop.locale1.xml: systemd-localed + $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.locale1 $< $@.tmp && \ + $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \ + $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp + +localed-install-data-hook: + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f dbus-org.freedesktop.locale1.service && \ + $(LN_S) systemd-localed.service dbus-org.freedesktop.locale1.service ) + +INSTALL_DATA_HOOKS += \ + localed-install-data-hook + +EXTRA_DIST += \ + units/systemd-localed.service.in + +dist_pkgdata_DATA = \ + src/locale/kbd-model-map + +dist_noinst_SCRIPT = \ + src/locale/generate-kbd-model-map + +update-kbd-model-map: + src/locale/generate-kbd-model-map > src/locale/kbd-model-map + +endif + +# ------------------------------------------------------------------------------ +if ENABLE_TIMEDATED +systemd_timedated_SOURCES = \ + src/timedate/timedated.c \ + src/dbus-common.c \ + src/polkit.c + +systemd_timedated_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_timedated_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la \ + $(DBUS_LIBS) + +rootlibexec_PROGRAMS += \ + systemd-timedated + +dist_dbussystemservice_DATA += \ + src/timedate/org.freedesktop.timedate1.service + +dist_dbuspolicy_DATA += \ + src/timedate/org.freedesktop.timedate1.conf + +nodist_systemunit_DATA += \ + units/systemd-timedated.service + +polkitpolicy_in_files += \ + src/timedate/org.freedesktop.timedate1.policy.in + +org.freedesktop.timedate1.xml: systemd-timedated + $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.timedate1 $< $@.tmp && \ + $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \ + $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp + +dbusinterface_DATA += \ + org.freedesktop.timedate1.xml + +timedated-install-data-hook: + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f dbus-org.freedesktop.timedate1.service && \ + $(LN_S) systemd-timedated.service dbus-org.freedesktop.timedate1.service ) + +INSTALL_DATA_HOOKS += \ + timedated-install-data-hook + +EXTRA_DIST += \ + units/systemd-timedated.service.in +endif + +# ------------------------------------------------------------------------------ +if ENABLE_LOGIND +systemd_logind_SOURCES = \ + src/login/logind.c \ + src/login/logind-dbus.c \ + src/login/logind-device.c \ + src/login/logind-seat.c \ + src/login/logind-seat-dbus.c \ + src/login/logind-session.c \ + src/login/logind-session-dbus.c \ + src/login/logind-user.c \ + src/login/logind-user-dbus.c \ + src/dbus-common.c \ + src/dbus-loop.c \ + src/cgroup-util.c \ + src/polkit.c + +nodist_systemd_logind_SOURCES = \ + src/login/logind-gperf.c + +if HAVE_ACL +systemd_logind_SOURCES += \ + src/login/logind-acl.c \ + src/acl-util.c +endif + +systemd_logind_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(UDEV_CFLAGS) \ + $(ACL_CFLAGS) + +systemd_logind_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la \ + $(DBUS_LIBS) \ + $(UDEV_LIBS) \ + $(ACL_LIBS) + +systemd_user_sessions_SOURCES = \ + src/login/user-sessions.c \ + src/cgroup-util.c + +systemd_user_sessions_LDADD = \ + libsystemd-basic.la + +rootlibexec_PROGRAMS += \ + systemd-logind \ + systemd-user-sessions + +systemd_loginctl_SOURCES = \ + src/login/loginctl.c \ + src/login/sysfs-show.c \ + src/dbus-common.c \ + src/cgroup-show.c \ + src/cgroup-util.c \ + src/pager.c + +systemd_loginctl_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(UDEV_CFLAGS) + +systemd_loginctl_LDADD = \ + libsystemd-basic.la \ + $(DBUS_LIBS) \ + $(UDEV_LIBS) + +rootbin_PROGRAMS += \ + systemd-loginctl + +test_login_SOURCES = \ + src/login/test-login.c + +test_login_LDADD = \ + libsystemd-basic.la \ + libsystemd-login.la + +noinst_PROGRAMS += \ + test-login + +libsystemd_login_la_SOURCES = \ + src/login/sd-login.c \ + src/cgroup-util.c + +libsystemd_login_la_CFLAGS = \ + $(AM_CFLAGS) \ + -fvisibility=hidden + +libsystemd_login_la_LDFLAGS = \ + -shared \ + -version-info $(LIBSYSTEMD_LOGIN_CURRENT):$(LIBSYSTEMD_LOGIN_REVISION):$(LIBSYSTEMD_LOGIN_AGE) \ + -Wl,--version-script=$(top_srcdir)/src/login/libsystemd-login.sym + +libsystemd_login_la_LIBADD = \ + libsystemd-basic.la + +if HAVE_PAM +pam_systemd_la_SOURCES = \ + src/login/pam-module.c \ + src/dbus-common.c + +pam_systemd_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(PAM_CFLAGS) \ + $(DBUS_CFLAGS) \ + -fvisibility=hidden + +pam_systemd_la_LDFLAGS = \ + -module \ + -export-dynamic \ + -avoid-version \ + -shared \ + -export-symbols-regex '^pam_sm_.*' + +pam_systemd_la_LIBADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la \ + $(PAM_LIBS) \ + $(DBUS_LIBS) + +pamlib_LTLIBRARIES = \ + pam_systemd.la +endif + +# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed +libsystemd-login-install-hook: + if test "$(libdir)" != "$(rootlibdir)"; then \ + mkdir -p $(DESTDIR)$(rootlibdir) && \ + so_img_name=$$(readlink $(DESTDIR)$(libdir)/libsystemd-login.so) && \ + so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \ + ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libsystemd-login.so && \ + mv $(DESTDIR)$(libdir)/libsystemd-login.so.* $(DESTDIR)$(rootlibdir); \ + fi + +INSTALL_EXEC_HOOKS += \ + libsystemd-login-install-hook + +libsystemd-login-uninstall-hook: + rm -f $(DESTDIR)$(rootlibdir)/libsystemd-login.so* + +UNINSTALL_EXEC_HOOKS += \ + libsystemd-login-uninstall-hook + +nodist_systemunit_DATA += \ + units/systemd-logind.service \ + units/systemd-user-sessions.service + +dist_dbussystemservice_DATA += \ + src/login/org.freedesktop.login1.service + +dist_dbuspolicy_DATA += \ + src/login/org.freedesktop.login1.conf + +dist_pkgsysconf_DATA += \ + src/login/systemd-logind.conf + +pkginclude_HEADERS += \ + src/systemd/sd-login.h + +lib_LTLIBRARIES += \ + libsystemd-login.la + +pkgconfiglib_DATA += \ + src/login/libsystemd-login.pc + +polkitpolicy_in_files += \ + src/login/org.freedesktop.login1.policy.in + +logind-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(systemunitdir)/multi-user.target.wants \ + $(DESTDIR)$(localstatedir)/lib/systemd + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f dbus-org.freedesktop.login1.service && \ + $(LN_S) systemd-logind.service dbus-org.freedesktop.login1.service) + ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \ + rm -f systemd-logind.service systemd-user-sessions.service && \ + $(LN_S) ../systemd-logind.service systemd-logind.service && \ + $(LN_S) ../systemd-user-sessions.service systemd-user-sessions.service ) + +INSTALL_DATA_HOOKS += \ + logind-install-data-hook + +systemd_multi_seat_x_SOURCES = \ + src/login/multi-seat-x.c + +systemd_multi_seat_x_CFLAGS = \ + $(AM_CFLAGS) \ + $(UDEV_CFLAGS) + +systemd_multi_seat_x_LDADD = \ + libsystemd-basic.la \ + $(UDEV_LIBS) + +rootlibexec_PROGRAMS += \ + systemd-multi-seat-x + +systemd_uaccess_SOURCES = \ + src/login/uaccess.c + +if HAVE_ACL +systemd_uaccess_SOURCES += \ + src/login/logind-acl.c \ + src/acl-util.c +endif + +systemd_uaccess_CFLAGS = \ + $(AM_CFLAGS) \ + $(UDEV_CFLAGS) \ + $(ACL_CFLAGS) + +systemd_uaccess_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la \ + libsystemd-login.la \ + $(UDEV_LIBS) \ + $(ACL_LIBS) + +rootlibexec_PROGRAMS += \ + systemd-uaccess + +dist_udevrules_DATA += \ + src/login/70-uaccess.rules + +dist_udevrules_DATA += \ + src/login/71-seat.rules + +nodist_udevrules_DATA += \ + src/login/73-seat-late.rules + +MANPAGES += \ + man/systemd-logind.conf.5 \ + man/sd-login.7 \ + man/systemd-loginctl.1 \ + man/sd_login_monitor_new.3 \ + man/sd_pid_get_session.3 \ + man/sd_uid_get_state.3 \ + man/sd_session_is_active.3 \ + man/sd_seat_get_active.3 \ + man/sd_get_seats.3 + +MANPAGES_ALIAS += \ + man/sd_login_monitor_unref.3 \ + man/sd_login_monitor_flush.3 \ + man/sd_login_monitor_get_fd.3 \ + man/sd_session_get_uid.3 \ + man/sd_session_get_seat.3 \ + man/sd_pid_get_owner_uid.3 \ + man/sd_pid_get_unit.3 \ + man/sd_uid_is_on_seat.3 \ + man/sd_uid_get_sessions.3 \ + man/sd_uid_get_seats.3 \ + man/sd_seat_get_sessions.3 \ + man/sd_seat_can_multi_session.3 \ + man/sd_get_sessions.3 \ + man/sd_get_uids.3 + +man/sd_login_monitor_unref.3: man/sd_login_monitor_new.3 +man/sd_login_monitor_flush.3: man/sd_login_monitor_new.3 +man/sd_login_monitor_get_fd.3: man/sd_login_monitor_new.3 +man/sd_session_get_uid.3: man/sd_session_is_active.3 +man/sd_session_get_seat.3: man/sd_session_is_active.3 +man/sd_pid_get_owner_uid.3: man/sd_pid_get_session.3 +man/sd_pid_get_unit.3: man/sd_pid_get_session.3 +man/sd_uid_is_on_seat.3: man/sd_uid_get_state.3 +man/sd_uid_get_sessions.3: man/sd_uid_get_state.3 +man/sd_uid_get_seats.3: man/sd_uid_get_state.3 +man/sd_seat_get_sessions.3: man/sd_seat_get_active.3 +man/sd_seat_can_multi_session.3: man/sd_seat_get_active.3 +man/sd_get_sessions.3: man/sd_get_seats.3 +man/sd_get_uids.3: man/sd_get_seats.3 + +EXTRA_DIST += \ + src/login/logind-gperf.gperf \ + src/login/libsystemd-login.pc.in \ + src/login/libsystemd-login.sym \ + src/login/logind.h \ + src/login/logind-device.h \ + src/login/logind-seat.h \ + src/login/logind-session.h \ + src/login/logind-user.h \ + src/login/logind-acl.h \ + src/login/73-seat-late.rules.in \ + units/systemd-logind.service.in \ + units/systemd-user-sessions.service.in + +CLEANFILES += \ + src/login/logind-gperf.c \ + src/login/73-seat-late.rules +endif +# ------------------------------------------------------------------------------ + +SED_PROCESS = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(SED) -e 's,@rootlibexecdir\@,$(rootlibexecdir),g' \ + -e 's,@rootbindir\@,$(rootbindir),g' \ + -e 's,@bindir\@,$(bindir),g' \ + -e 's,@SYSTEMCTL\@,$(rootbindir)/systemctl,g' \ + -e 's,@SYSTEMD_NOTIFY\@,$(rootbindir)/systemd-notify,g' \ + -e 's,@pkgsysconfdir\@,$(pkgsysconfdir),g' \ + -e 's,@pkgdatadir\@,$(pkgdatadir),g' \ + -e 's,@pkglibexecdir\@,$(pkglibexecdir),g' \ + -e 's,@systemunitdir\@,$(systemunitdir),g' \ + -e 's,@userunitdir\@,$(userunitdir),g' \ + -e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \ + -e 's,@PACKAGE_NAME\@,$(PACKAGE_NAME),g' \ + -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' \ + -e 's,@prefix\@,$(prefix),g' \ + -e 's,@exec_prefix\@,$(exec_prefix),g' \ + -e 's,@libdir\@,$(libdir),g' \ + -e 's,@includedir\@,$(includedir),g' \ + < $< > $@ || rm $@ + +units/%: units/%.in Makefile + $(SED_PROCESS) + +man/%: man/%.in Makefile + $(SED_PROCESS) + +sysctl.d/%: sysctl.d/%.in Makefile + $(SED_PROCESS) + +%.pc: %.pc.in Makefile + $(SED_PROCESS) + +src/%.policy.in: src/%.policy.in.in Makefile + $(SED_PROCESS) + +src/%.rules: src/%.rules.in Makefile + $(SED_PROCESS) + +src/%.c: src/%.gperf + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(GPERF) < $< > $@ + +src/%: src/%.m4 + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(M4) -P $(M4_DEFINES) < $< > $@ || rm $@ + +src/load-fragment-gperf-nulstr.c: src/load-fragment-gperf.gperf + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(AWK) 'BEGIN{ keywords=0 ; FS="," ; print "extern const char load_fragment_gperf_nulstr[];" ; print "const char load_fragment_gperf_nulstr[] ="} ; keyword==1 { print "\"" $$1 "\\0\"" } ; /%%/ { keyword=1} ; END { print ";" }' < $< > $@ || rm $@ + +M4_PROCESS_SYSTEM = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(M4) -P $(M4_DEFINES) -DFOR_SYSTEM=1 < $< > $@ || rm $@ + +M4_PROCESS_USER = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(M4) -P $(M4_DEFINES) -DFOR_USER=1 < $< > $@ || rm $@ + +units/%: units/%.m4 Makefile + $(M4_PROCESS_SYSTEM) + +units/user/%: units/%.m4 Makefile + $(M4_PROCESS_USER) + +CLEANFILES += \ + $(nodist_systemunit_DATA) \ + $(nodist_userunit_DATA) \ + $(nodist_man_MANS) \ + ${XML_IN_FILES:.xml.in=.html} \ + $(pkgconfigdata_DATA) \ + $(pkgconfiglib_DATA) \ + $(nodist_polkitpolicy_DATA) \ + src/load-fragment-gperf.gperf \ + src/load-fragment-gperf.c \ + src/load-fragment-gperf-nulstr.c \ + src/99-systemd.rules + +if HAVE_VALAC +CLEANFILES += \ + ${systemadm_SOURCES:.vala=.c} +endif + +if HAVE_XSLTPROC +XSLTPROC_FLAGS = \ + --nonet \ + --stringparam funcsynopsis.style ansi + +XSLTPROC_PROCESS_MAN = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< + +XSLTPROC_PROCESS_MAN_IN = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(XSLTPROC) -o ${@:.in=} $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< && \ + mv ${@:.in=} $@ + +XSLTPROC_PROCESS_HTML = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(srcdir)/man/custom-html.xsl $< + +XSLTPROC_PROCESS_HTML_IN = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(XSLTPROC) -o ${@:.in=} $(XSLTPROC_FLAGS) $(srcdir)/man/custom-html.xsl $< && \ + mv ${@:.in=} $@ + +man/%.1: man/%.xml + $(XSLTPROC_PROCESS_MAN) + +man/%.1.in: man/%.xml.in + $(XSLTPROC_PROCESS_MAN) + +man/%.3: man/%.xml + $(XSLTPROC_PROCESS_MAN) + +man/%.3.in: man/%.xml.in + $(XSLTPROC_PROCESS_MAN) + +man/%.5: man/%.xml + $(XSLTPROC_PROCESS_MAN) + +man/%.5.in: man/%.xml.in + $(XSLTPROC_PROCESS_MAN) + +man/%.7: man/%.xml + $(XSLTPROC_PROCESS_MAN) + +man/%.7.in: man/%.xml.in + $(XSLTPROC_PROCESS_MAN_IN) + +man/%.8: man/%.xml + $(XSLTPROC_PROCESS_MAN) + +man/%.8.in: man/%.xml.in + $(XSLTPROC_PROCESS_MAN_IN) + +man/%.html: man/%.xml + $(XSLTPROC_PROCESS_HTML) + +man/%.html.in: man/%.xml.in + $(XSLTPROC_PROCESS_HTML_IN) + +CLEANFILES += \ + $(dist_man_MANS) \ + ${nodist_man_MANS:=.in} \ + ${XML_FILES:.xml=.html} \ + ${XML_IN_FILES:.xml.in=.html.in} +endif + +DBUS_PREPROCESS = $(CPP) -P $(DBUS_CFLAGS) -imacros dbus/dbus-protocol.h + +org.freedesktop.systemd1.%.xml: systemd + $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.$* $< $@.tmp && \ + $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \ + $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp + +CLEANFILES += \ + $(dbusinterface_DATA) + +systemd-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(tmpfilesdir) \ + $(DESTDIR)$(sysconfdir)/tmpfiles.d \ + $(DESTDIR)$(prefix)/lib/modules-load.d \ + $(DESTDIR)$(sysconfdir)/modules-load.d \ + $(DESTDIR)$(prefix)/lib/sysctl.d \ + $(DESTDIR)$(sysconfdir)/sysctl.d \ + $(DESTDIR)$(systemshutdowndir) \ + $(DESTDIR)$(systemgeneratordir) \ + $(DESTDIR)$(usergeneratordir) + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(systemunitdir) \ + $(DESTDIR)$(userunitdir) \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants \ + $(DESTDIR)$(systemunitdir)/sockets.target.wants \ + $(DESTDIR)$(systemunitdir)/basic.target.wants \ + $(DESTDIR)$(systemunitdir)/shutdown.target.wants \ + $(DESTDIR)$(systemunitdir)/local-fs.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel1.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel2.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel3.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel4.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel5.target.wants \ + $(DESTDIR)$(systemunitdir)/multi-user.target.wants \ + $(DESTDIR)$(systemunitdir)/graphical.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/system \ + $(DESTDIR)$(pkgsysconfdir)/system/sysinit.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/system/local-fs.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/system/getty.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/user \ + $(DESTDIR)$(dbussessionservicedir) \ + $(DESTDIR)$(sysconfdir)/xdg/systemd + ( cd $(DESTDIR)$(sysconfdir)/xdg/systemd/ && \ + rm -f user && \ + $(LN_S) $(pkgsysconfdir)/user user ) + ( cd $(DESTDIR)$(systemunitdir)/sockets.target.wants && \ + rm -f systemd-initctl.socket systemd-shutdownd.socket && \ + $(LN_S) ../systemd-initctl.socket systemd-initctl.socket && \ + $(LN_S) ../systemd-shutdownd.socket systemd-shutdownd.socket ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel1.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel2.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel3.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel4.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel5.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/shutdown.target.wants && \ + rm -f systemd-update-utmp-shutdown.service && \ + $(LN_S) ../systemd-update-utmp-shutdown.service systemd-update-utmp-shutdown.service ) + ( cd $(DESTDIR)$(systemunitdir)/local-fs.target.wants && \ + rm -f systemd-remount-api-vfs.service \ + fsck-root.service \ + remount-rootfs.service \ + var-run.mount \ + media.mount && \ + $(LN_S) ../systemd-remount-api-vfs.service systemd-remount-api-vfs.service && \ + $(LN_S) ../fsck-root.service fsck-root.service && \ + $(LN_S) ../remount-rootfs.service remount-rootfs.service && \ + $(LN_S) ../var-run.mount var-run.mount && \ + $(LN_S) ../media.mount media.mount ) + ( cd $(DESTDIR)$(userunitdir) && \ + rm -f shutdown.target sockets.target bluetooth.target printer.target sound.target && \ + $(LN_S) $(systemunitdir)/shutdown.target shutdown.target && \ + $(LN_S) $(systemunitdir)/sockets.target sockets.target && \ + $(LN_S) $(systemunitdir)/bluetooth.target bluetooth.target && \ + $(LN_S) $(systemunitdir)/printer.target printer.target && \ + $(LN_S) $(systemunitdir)/sound.target sound.target ) + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f runlevel0.target runlevel1.target runlevel2.target runlevel3.target runlevel4.target runlevel5.target runlevel6.target && \ + $(LN_S) poweroff.target runlevel0.target && \ + $(LN_S) rescue.target runlevel1.target && \ + $(LN_S) multi-user.target runlevel2.target && \ + $(LN_S) multi-user.target runlevel3.target && \ + $(LN_S) multi-user.target runlevel4.target && \ + $(LN_S) graphical.target runlevel5.target && \ + $(LN_S) reboot.target runlevel6.target ) + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f default.target ctrl-alt-del.target autovt@.service && \ + $(LN_S) graphical.target default.target && \ + $(LN_S) reboot.target ctrl-alt-del.target && \ + $(LN_S) getty@.service autovt@.service ) + ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \ + rm -f getty.target systemd-ask-password-wall.path && \ + $(LN_S) ../getty.target getty.target && \ + $(LN_S) ../systemd-ask-password-wall.path systemd-ask-password-wall.path) + ( cd $(DESTDIR)$(pkgsysconfdir)/system/getty.target.wants && \ + rm -f getty@tty1.service && \ + $(LN_S) $(systemunitdir)/getty@.service getty@tty1.service ) + ( cd $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants && \ + rm -f remote-fs.target && \ + $(LN_S) $(systemunitdir)/remote-fs.target remote-fs.target ) + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f dev-hugepages.mount \ + dev-mqueue.mount \ + sys-kernel-config.mount \ + sys-kernel-debug.mount \ + sys-kernel-security.mount \ + sys-fs-fuse-connections.mount \ + systemd-modules-load.service \ + systemd-tmpfiles-setup.service \ + systemd-sysctl.service \ + systemd-ask-password-console.path && \ + $(LN_S) ../dev-hugepages.mount dev-hugepages.mount && \ + $(LN_S) ../dev-mqueue.mount dev-mqueue.mount && \ + $(LN_S) ../sys-kernel-config.mount sys-kernel-config.mount && \ + $(LN_S) ../sys-kernel-debug.mount sys-kernel-debug.mount && \ + $(LN_S) ../sys-kernel-security.mount sys-kernel-security.mount && \ + $(LN_S) ../sys-fs-fuse-connections.mount sys-fs-fuse-connections.mount && \ + $(LN_S) ../systemd-modules-load.service systemd-modules-load.service && \ + $(LN_S) ../systemd-tmpfiles-setup.service systemd-tmpfiles-setup.service && \ + $(LN_S) ../systemd-sysctl.service systemd-sysctl.service && \ + $(LN_S) ../systemd-ask-password-console.path systemd-ask-password-console.path ) + ( cd $(DESTDIR)$(systemunitdir)/basic.target.wants && \ + rm -f systemd-tmpfiles-clean.timer && \ + $(LN_S) ../systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.timer ) + ( cd $(DESTDIR)$(dbussessionservicedir) && \ + rm -f org.freedesktop.systemd1.service && \ + $(LN_S) ../system-services/org.freedesktop.systemd1.service org.freedesktop.systemd1.service ) +if HAVE_PLYMOUTH + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(SYSTEM_SYSVINIT_PATH) \ + $(DESTDIR)$(systemunitdir)/reboot.target.wants \ + $(DESTDIR)$(systemunitdir)/kexec.target.wants \ + $(DESTDIR)$(systemunitdir)/poweroff.target.wants \ + $(DESTDIR)$(systemunitdir)/halt.target.wants + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f plymouth-start.service plymouth-read-write.service && \ + $(LN_S) ../plymouth-start.service plymouth-start.service && \ + $(LN_S) ../plymouth-read-write.service plymouth-read-write.service ) + ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \ + rm -f plymouth-quit.service plymouth-quit-wait.service && \ + $(LN_S) ../plymouth-quit.service plymouth-quit.service && \ + $(LN_S) ../plymouth-quit-wait.service plymouth-quit-wait.service ) + ( cd $(DESTDIR)$(systemunitdir)/reboot.target.wants && \ + rm -f plymouth-reboot.service && \ + $(LN_S) ../plymouth-reboot.service plymouth-reboot.service ) + ( cd $(DESTDIR)$(systemunitdir)/kexec.target.wants && \ + rm -f plymouth-kexec.service && \ + $(LN_S) ../plymouth-kexec.service plymouth-kexec.service ) + ( cd $(DESTDIR)$(systemunitdir)/poweroff.target.wants && \ + rm -f plymouth-poweroff.service && \ + $(LN_S) ../plymouth-poweroff.service plymouth-poweroff.service ) + ( cd $(DESTDIR)$(systemunitdir)/halt.target.wants && \ + rm -f plymouth-halt.service && \ + $(LN_S) ../plymouth-halt.service plymouth-halt.service ) +endif +if TARGET_MEEGO + $(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants + ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \ + rm -f network.target && \ + $(LN_S) $(systemunitdir)/network.target network.target ) + ( cd $(DESTDIR)$(pkgsysconfdir)/system/sysinit.target.wants && \ + rm -f * ) + ( cd $(DESTDIR)$(pkgsysconfdir)/system/local-fs.target.wants && \ + rm -f * ) + ( cd $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants && \ + rm -f * ) + ( cd $(DESTDIR)$(pkgsysconfdir)/system/getty.target.wants && \ + rm -f * ) +endif + +if TARGET_FEDORA + $(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants + ( cd $(DESTDIR)$(systemunitdir)/final.target.wants && \ + rm -f halt-local.service && \ + $(LN_S) $(systemunitdir)/halt-local.service halt-local.service ) + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f display-manager.service single.service && \ + $(LN_S) prefdm.service display-manager.service && \ + $(LN_S) rescue.service single.service ) + ( cd $(DESTDIR)$(systemunitdir)/graphical.target.wants && \ + rm -f display-manager.service && \ + $(LN_S) $(systemunitdir)/display-manager.service display-manager.service ) +endif + +if TARGET_MANDRIVA + $(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants + ( cd $(DESTDIR)$(systemunitdir)/final.target.wants && \ + rm -f halt-local.service && \ + $(LN_S) $(systemunitdir)/halt-local.service halt-local.service ) + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f display-manager.service dm.service single.service && \ + $(LN_S) prefdm.service display-manager.service && \ + $(LN_S) prefdm.service dm.service && \ + $(LN_S) rescue.service single.service ) + ( cd $(DESTDIR)$(systemunitdir)/graphical.target.wants && \ + rm -f display-manager.service && \ + $(LN_S) $(systemunitdir)/display-manager.service display-manager.service ) +endif + +if TARGET_DEBIAN_OR_UBUNTU + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f runlevel5.target && \ + $(LN_S) multi-user.target runlevel5.target ) +endif + +if TARGET_SUSE + $(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f local.service && \ + $(LN_S) rc-local.service local.service ) + ( cd $(DESTDIR)$(systemunitdir)/final.target.wants && \ + rm -f halt-local.service && \ + $(LN_S) $(systemunitdir)/halt-local.service halt-local.service ) +endif + +if TARGET_MAGEIA + $(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants + ( cd $(DESTDIR)$(systemunitdir)/final.target.wants && \ + rm -f halt-local.service && \ + $(LN_S) $(systemunitdir)/halt-local.service halt-local.service ) + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f display-manager.service && \ + $(LN_S) prefdm.service display-manager.service && \ + $(LN_S) prefdm.service dm.service ) + ( cd $(DESTDIR)$(systemunitdir)/graphical.target.wants && \ + rm -f display-manager.service && \ + $(LN_S) $(systemunitdir)/display-manager.service display-manager.service ) +endif + +if HAVE_SYSV_COMPAT + ( cd $(DESTDIR)$(systemunitdir)/local-fs.target.wants && \ + rm -f var-lock.mount && \ + $(LN_S) ../var-lock.mount var-lock.mount ) +endif + +install-exec-hook: $(INSTALL_EXEC_HOOKS) + +uninstall-hook: $(UNINSTALL_EXEC_HOOKS) + +install-data-hook: systemd-install-data-hook $(INSTALL_DATA_HOOKS) + +DISTCHECK_CONFIGURE_FLAGS = \ + --with-dbuspolicydir=$$dc_install_base/$(dbuspolicydir) \ + --with-dbussessionservicedir=$$dc_install_base/$(dbussessionservicedir) \ + --with-dbussystemservicedir=$$dc_install_base/$(dbussystemservicedir) \ + --with-dbusinterfacedir=$$dc_install_base/$(dbusinterfacedir) \ + --with-udevrulesdir=$$dc_install_base/$(udevrulesdir) \ + --with-pamlibdir=$$dc_install_base/$(pamlibdir) \ + --with-rootprefix=$$dc_install_base/$(prefix) + + +upload: all distcheck + cp -v systemd-$(VERSION).tar.xz /home/lennart/git.fedora/systemd/ + scp systemd-$(VERSION).tar.xz fdo:/srv/www.freedesktop.org/www/software/systemd/ + scp man/*.html fdo:/srv/www.freedesktop.org/www/software/systemd/man/ + scp man/*.html tango:public/systemd-man/ + +git-tag: + git tag "v$(VERSION)" -m "systemd $(VERSION)" diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..1c4ae86 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,8483 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This file is part of systemd. +# +# Copyright 2011 Lennart Poettering +# Copyright 2011 Kay Sievers +# +# systemd 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. +# +# systemd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with systemd; If not, see . + + + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@TARGET_GENTOO_TRUE@am__append_1 = \ +@TARGET_GENTOO_TRUE@ -DKBD_LOADKEYS=\"/usr/bin/loadkeys\" \ +@TARGET_GENTOO_TRUE@ -DKBD_SETFONT=\"/usr/bin/setfont\" \ +@TARGET_GENTOO_TRUE@ -DDEFAULT_FONT=\"LatArCyrHeb-16\" + +@TARGET_ARCH_TRUE@@TARGET_GENTOO_FALSE@am__append_2 = \ +@TARGET_ARCH_TRUE@@TARGET_GENTOO_FALSE@ -DKBD_LOADKEYS=\"/usr/bin/loadkeys\" \ +@TARGET_ARCH_TRUE@@TARGET_GENTOO_FALSE@ -DKBD_SETFONT=\"/usr/bin/setfont\" \ +@TARGET_ARCH_TRUE@@TARGET_GENTOO_FALSE@ -DDEFAULT_FONT=\"LatArCyrHeb-16\" + +@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_TRUE@@TARGET_GENTOO_FALSE@am__append_3 = \ +@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_TRUE@@TARGET_GENTOO_FALSE@ -DKBD_LOADKEYS=\"/usr/bin/loadkeys\" \ +@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_TRUE@@TARGET_GENTOO_FALSE@ -DKBD_SETFONT=\"/usr/bin/setfont\" \ +@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_TRUE@@TARGET_GENTOO_FALSE@ -DDEFAULT_FONT=\"LatArCyrHeb-16\" + +@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MANDRIVA_TRUE@am__append_4 = \ +@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MANDRIVA_TRUE@ -DKBD_LOADKEYS=\"/bin/loadkeys\" \ +@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MANDRIVA_TRUE@ -DKBD_SETFONT=\"/bin/setfont\" \ +@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MANDRIVA_TRUE@ -DDEFAULT_FONT=\"LatArCyrHeb-16\" + +@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_TRUE@am__append_5 = \ +@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_TRUE@ -DKBD_LOADKEYS=\"/bin/loadkeys\" \ +@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_TRUE@ -DKBD_SETFONT=\"/bin/setfont\" \ +@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_TRUE@ -DDEFAULT_FONT=\"LatArCyrHeb-16\" + +@TARGET_ANGSTROM_TRUE@@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_FALSE@am__append_6 = \ +@TARGET_ANGSTROM_TRUE@@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_FALSE@ -DKBD_LOADKEYS=\"/usr/bin/loadkeys\" \ +@TARGET_ANGSTROM_TRUE@@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_FALSE@ -DKBD_SETFONT=\"/usr/bin/setfont\" \ +@TARGET_ANGSTROM_TRUE@@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_FALSE@ -DDEFAULT_FONT=\"LatArCyrHeb-16\" + +@TARGET_ANGSTROM_FALSE@@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MAGEIA_TRUE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_FALSE@am__append_7 = \ +@TARGET_ANGSTROM_FALSE@@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MAGEIA_TRUE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_FALSE@ -DKBD_LOADKEYS=\"/bin/loadkeys\" \ +@TARGET_ANGSTROM_FALSE@@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MAGEIA_TRUE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_FALSE@ -DKBD_SETFONT=\"/bin/setfont\" \ +@TARGET_ANGSTROM_FALSE@@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MAGEIA_TRUE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_FALSE@ -DDEFAULT_FONT=\"LatArCyrHeb-16\" + +@TARGET_ANGSTROM_FALSE@@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MAGEIA_FALSE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_FALSE@am__append_8 = \ +@TARGET_ANGSTROM_FALSE@@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MAGEIA_FALSE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_FALSE@ -DKBD_LOADKEYS=\"/bin/loadkeys\" \ +@TARGET_ANGSTROM_FALSE@@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MAGEIA_FALSE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_FALSE@ -DKBD_SETFONT=\"/bin/setfont\" \ +@TARGET_ANGSTROM_FALSE@@TARGET_ARCH_FALSE@@TARGET_FRUGALWARE_FALSE@@TARGET_GENTOO_FALSE@@TARGET_MAGEIA_FALSE@@TARGET_MANDRIVA_FALSE@@TARGET_MEEGO_FALSE@ -DDEFAULT_FONT=\"latarcyrheb-sun16\" + +rootbin_PROGRAMS = systemctl$(EXEEXT) systemd-notify$(EXEEXT) \ + systemd-ask-password$(EXEEXT) \ + systemd-tty-ask-password-agent$(EXEEXT) \ + systemd-tmpfiles$(EXEEXT) systemd-machine-id-setup$(EXEEXT) \ + systemd-journalctl$(EXEEXT) $(am__EXEEXT_3) +bin_PROGRAMS = systemd-cgls$(EXEEXT) systemd-cgtop$(EXEEXT) \ + systemd-stdio-bridge$(EXEEXT) systemd-nspawn$(EXEEXT) \ + $(am__EXEEXT_1) systemd-cat$(EXEEXT) +@HAVE_GTK_TRUE@am__append_9 = \ +@HAVE_GTK_TRUE@ systemadm \ +@HAVE_GTK_TRUE@ systemd-gnome-ask-password-agent + +rootlibexec_PROGRAMS = systemd$(EXEEXT) systemd-cgroups-agent$(EXEEXT) \ + systemd-initctl$(EXEEXT) systemd-update-utmp$(EXEEXT) \ + systemd-shutdownd$(EXEEXT) systemd-shutdown$(EXEEXT) \ + systemd-modules-load$(EXEEXT) systemd-remount-api-vfs$(EXEEXT) \ + systemd-reply-password$(EXEEXT) systemd-fsck$(EXEEXT) \ + systemd-timestamp$(EXEEXT) systemd-ac-power$(EXEEXT) \ + systemd-detect-virt$(EXEEXT) systemd-sysctl$(EXEEXT) \ + systemd-journald$(EXEEXT) $(am__EXEEXT_4) $(am__EXEEXT_5) \ + $(am__EXEEXT_6) $(am__EXEEXT_7) $(am__EXEEXT_8) \ + $(am__EXEEXT_9) $(am__EXEEXT_10) $(am__EXEEXT_11) \ + $(am__EXEEXT_12) $(am__EXEEXT_13) $(am__EXEEXT_14) +systemgenerator_PROGRAMS = systemd-getty-generator$(EXEEXT) \ + $(am__EXEEXT_15) $(am__EXEEXT_16) $(am__EXEEXT_17) \ + $(am__EXEEXT_18) $(am__EXEEXT_19) +noinst_PROGRAMS = test-engine$(EXEEXT) test-job-type$(EXEEXT) \ + test-ns$(EXEEXT) test-loopback$(EXEEXT) test-hostname$(EXEEXT) \ + test-daemon$(EXEEXT) test-cgroup$(EXEEXT) \ + test-env-replace$(EXEEXT) test-strv$(EXEEXT) \ + test-install$(EXEEXT) test-id128$(EXEEXT) \ + test-journal$(EXEEXT) $(am__EXEEXT_2) +@HAVE_SYSV_COMPAT_TRUE@am__append_10 = \ +@HAVE_SYSV_COMPAT_TRUE@ tmpfiles.d/legacy.conf + +@HAVE_SYSV_COMPAT_TRUE@am__append_11 = \ +@HAVE_SYSV_COMPAT_TRUE@ units/var-lock.mount + +@TARGET_FEDORA_TRUE@am__append_12 = \ +@TARGET_FEDORA_TRUE@ units/fedora/prefdm.service \ +@TARGET_FEDORA_TRUE@ units/fedora/rc-local.service \ +@TARGET_FEDORA_TRUE@ units/fedora/halt-local.service + +@TARGET_FEDORA_TRUE@am__append_13 = \ +@TARGET_FEDORA_TRUE@ systemd-rc-local-generator + +@TARGET_MANDRIVA_TRUE@am__append_14 = \ +@TARGET_MANDRIVA_TRUE@ units/mandriva/prefdm.service \ +@TARGET_MANDRIVA_TRUE@ units/fedora/rc-local.service \ +@TARGET_MANDRIVA_TRUE@ units/fedora/halt-local.service + +@TARGET_MANDRIVA_TRUE@am__append_15 = \ +@TARGET_MANDRIVA_TRUE@ systemd-rc-local-generator + +@TARGET_FRUGALWARE_TRUE@am__append_16 = \ +@TARGET_FRUGALWARE_TRUE@ units/frugalware/display-manager.service + +@TARGET_SUSE_TRUE@am__append_17 = \ +@TARGET_SUSE_TRUE@ units/suse/rc-local.service \ +@TARGET_SUSE_TRUE@ units/suse/halt-local.service + +@TARGET_SUSE_TRUE@am__append_18 = \ +@TARGET_SUSE_TRUE@ systemd-rc-local-generator + +@TARGET_MAGEIA_TRUE@am__append_19 = \ +@TARGET_MAGEIA_TRUE@ units/mageia/prefdm.service \ +@TARGET_MAGEIA_TRUE@ units/fedora/rc-local.service \ +@TARGET_MAGEIA_TRUE@ units/fedora/halt-local.service + +@TARGET_MAGEIA_TRUE@am__append_20 = \ +@TARGET_MAGEIA_TRUE@ systemd-rc-local-generator + +@HAVE_PLYMOUTH_TRUE@am__append_21 = \ +@HAVE_PLYMOUTH_TRUE@ units/plymouth-start.service \ +@HAVE_PLYMOUTH_TRUE@ units/plymouth-read-write.service \ +@HAVE_PLYMOUTH_TRUE@ units/plymouth-quit.service \ +@HAVE_PLYMOUTH_TRUE@ units/plymouth-quit-wait.service \ +@HAVE_PLYMOUTH_TRUE@ units/plymouth-reboot.service \ +@HAVE_PLYMOUTH_TRUE@ units/plymouth-kexec.service \ +@HAVE_PLYMOUTH_TRUE@ units/plymouth-poweroff.service \ +@HAVE_PLYMOUTH_TRUE@ units/plymouth-halt.service \ +@HAVE_PLYMOUTH_TRUE@ units/systemd-ask-password-plymouth.path + +@HAVE_PLYMOUTH_TRUE@am__append_22 = \ +@HAVE_PLYMOUTH_TRUE@ units/systemd-ask-password-plymouth.service + +@HAVE_PLYMOUTH_TRUE@am__append_23 = \ +@HAVE_PLYMOUTH_TRUE@ units/systemd-ask-password-plymouth.service.in + +@ENABLE_MANPAGES_TRUE@am__append_24 = \ +@ENABLE_MANPAGES_TRUE@ $(XML_FILES) \ +@ENABLE_MANPAGES_TRUE@ $(XML_IN_FILES) \ +@ENABLE_MANPAGES_TRUE@ ${nodist_man_MANS:=.in} \ +@ENABLE_MANPAGES_TRUE@ ${XML_IN_FILES:.xml.in=.html.in} + +@HAVE_ACL_TRUE@am__append_25 = \ +@HAVE_ACL_TRUE@ src/acl-util.c + +@HAVE_XZ_TRUE@am__append_26 = \ +@HAVE_XZ_TRUE@ src/journal/compress.c + +@HAVE_XZ_TRUE@am__append_27 = \ +@HAVE_XZ_TRUE@ $(XZ_CFLAGS) + +@HAVE_XZ_TRUE@am__append_28 = \ +@HAVE_XZ_TRUE@ $(XZ_LIBS) + +@HAVE_XZ_TRUE@am__append_29 = \ +@HAVE_XZ_TRUE@ src/journal/compress.c + +@HAVE_XZ_TRUE@am__append_30 = \ +@HAVE_XZ_TRUE@ $(XZ_LIBS) + +@HAVE_XZ_TRUE@am__append_31 = \ +@HAVE_XZ_TRUE@ src/journal/compress.c + +@HAVE_XZ_TRUE@am__append_32 = \ +@HAVE_XZ_TRUE@ $(XZ_LIBS) + +@HAVE_XZ_TRUE@am__append_33 = \ +@HAVE_XZ_TRUE@ src/journal/compress.c + +@HAVE_XZ_TRUE@am__append_34 = \ +@HAVE_XZ_TRUE@ $(XZ_CFLAGS) + +@HAVE_XZ_TRUE@am__append_35 = \ +@HAVE_XZ_TRUE@ $(XZ_LIBS) + +@ENABLE_COREDUMP_TRUE@am__append_36 = \ +@ENABLE_COREDUMP_TRUE@ systemd-coredump + +@ENABLE_COREDUMP_TRUE@am__append_37 = \ +@ENABLE_COREDUMP_TRUE@ sysctl.d/coredump.conf.in + +@ENABLE_COREDUMP_TRUE@am__append_38 = \ +@ENABLE_COREDUMP_TRUE@ sysctl.d/coredump.conf + +@ENABLE_BINFMT_TRUE@am__append_39 = \ +@ENABLE_BINFMT_TRUE@ systemd-binfmt + +@ENABLE_BINFMT_TRUE@am__append_40 = \ +@ENABLE_BINFMT_TRUE@ units/proc-sys-fs-binfmt_misc.automount \ +@ENABLE_BINFMT_TRUE@ units/proc-sys-fs-binfmt_misc.mount + +@ENABLE_BINFMT_TRUE@am__append_41 = \ +@ENABLE_BINFMT_TRUE@ units/systemd-binfmt.service + +@ENABLE_BINFMT_TRUE@am__append_42 = \ +@ENABLE_BINFMT_TRUE@ binfmt-install-data-hook + +@ENABLE_BINFMT_TRUE@am__append_43 = \ +@ENABLE_BINFMT_TRUE@ man/binfmt.d.5 + +@ENABLE_BINFMT_TRUE@am__append_44 = \ +@ENABLE_BINFMT_TRUE@ units/systemd-binfmt.service.in + +@ENABLE_VCONSOLE_TRUE@am__append_45 = \ +@ENABLE_VCONSOLE_TRUE@ systemd-vconsole-setup + +@ENABLE_VCONSOLE_TRUE@am__append_46 = \ +@ENABLE_VCONSOLE_TRUE@ units/systemd-vconsole-setup.service + +@ENABLE_VCONSOLE_TRUE@am__append_47 = \ +@ENABLE_VCONSOLE_TRUE@ vconsole-install-data-hook + +@ENABLE_VCONSOLE_TRUE@am__append_48 = \ +@ENABLE_VCONSOLE_TRUE@ man/vconsole.conf.5 + +@ENABLE_VCONSOLE_TRUE@am__append_49 = \ +@ENABLE_VCONSOLE_TRUE@ units/systemd-vconsole-setup.service.in + +@ENABLE_READAHEAD_TRUE@am__append_50 = \ +@ENABLE_READAHEAD_TRUE@ systemd-readahead-collect \ +@ENABLE_READAHEAD_TRUE@ systemd-readahead-replay + +@ENABLE_READAHEAD_TRUE@am__append_51 = \ +@ENABLE_READAHEAD_TRUE@ units/systemd-readahead-done.timer + +@ENABLE_READAHEAD_TRUE@am__append_52 = \ +@ENABLE_READAHEAD_TRUE@ units/systemd-readahead-collect.service \ +@ENABLE_READAHEAD_TRUE@ units/systemd-readahead-replay.service \ +@ENABLE_READAHEAD_TRUE@ units/systemd-readahead-done.service + +@ENABLE_READAHEAD_TRUE@am__append_53 = \ +@ENABLE_READAHEAD_TRUE@ src/systemd/sd-readahead.h \ +@ENABLE_READAHEAD_TRUE@ src/readahead/readahead-common.h \ +@ENABLE_READAHEAD_TRUE@ units/systemd-readahead-collect.service.in \ +@ENABLE_READAHEAD_TRUE@ units/systemd-readahead-replay.service.in \ +@ENABLE_READAHEAD_TRUE@ units/systemd-readahead-done.service.in + +@ENABLE_READAHEAD_TRUE@am__append_54 = \ +@ENABLE_READAHEAD_TRUE@ man/sd_readahead.3 \ +@ENABLE_READAHEAD_TRUE@ man/sd-readahead.7 + + +# ------------------------------------------------------------------------------ +@ENABLE_QUOTACHECK_TRUE@am__append_55 = \ +@ENABLE_QUOTACHECK_TRUE@ systemd-quotacheck + +@ENABLE_QUOTACHECK_TRUE@am__append_56 = \ +@ENABLE_QUOTACHECK_TRUE@ units/quotacheck.service + +@ENABLE_QUOTACHECK_TRUE@am__append_57 = \ +@ENABLE_QUOTACHECK_TRUE@ units/quotacheck.service.in + + +# ------------------------------------------------------------------------------ +@ENABLE_RANDOMSEED_TRUE@am__append_58 = \ +@ENABLE_RANDOMSEED_TRUE@ systemd-random-seed + +@ENABLE_RANDOMSEED_TRUE@am__append_59 = \ +@ENABLE_RANDOMSEED_TRUE@ units/systemd-random-seed-save.service \ +@ENABLE_RANDOMSEED_TRUE@ units/systemd-random-seed-load.service + +@ENABLE_RANDOMSEED_TRUE@am__append_60 = \ +@ENABLE_RANDOMSEED_TRUE@ units/systemd-random-seed-save.service.in \ +@ENABLE_RANDOMSEED_TRUE@ units/systemd-random-seed-load.service.in + +@ENABLE_RANDOMSEED_TRUE@am__append_61 = \ +@ENABLE_RANDOMSEED_TRUE@ randomseed-install-data-hook + + +# ------------------------------------------------------------------------------ +@HAVE_LIBCRYPTSETUP_TRUE@am__append_62 = \ +@HAVE_LIBCRYPTSETUP_TRUE@ systemd-cryptsetup + +@HAVE_LIBCRYPTSETUP_TRUE@am__append_63 = \ +@HAVE_LIBCRYPTSETUP_TRUE@ systemd-cryptsetup-generator + +@HAVE_LIBCRYPTSETUP_TRUE@am__append_64 = \ +@HAVE_LIBCRYPTSETUP_TRUE@ units/cryptsetup.target + +@HAVE_LIBCRYPTSETUP_TRUE@am__append_65 = \ +@HAVE_LIBCRYPTSETUP_TRUE@ cryptsetup-install-data-hook + +@ENABLE_HOSTNAMED_TRUE@am__append_66 = \ +@ENABLE_HOSTNAMED_TRUE@ systemd-hostnamed + +@ENABLE_HOSTNAMED_TRUE@am__append_67 = \ +@ENABLE_HOSTNAMED_TRUE@ units/systemd-hostnamed.service + +@ENABLE_HOSTNAMED_TRUE@am__append_68 = \ +@ENABLE_HOSTNAMED_TRUE@ src/hostname/org.freedesktop.hostname1.conf + +@ENABLE_HOSTNAMED_TRUE@am__append_69 = \ +@ENABLE_HOSTNAMED_TRUE@ src/hostname/org.freedesktop.hostname1.service + +@ENABLE_HOSTNAMED_TRUE@am__append_70 = \ +@ENABLE_HOSTNAMED_TRUE@ src/hostname/org.freedesktop.hostname1.policy.in + +@ENABLE_HOSTNAMED_TRUE@am__append_71 = \ +@ENABLE_HOSTNAMED_TRUE@ org.freedesktop.hostname1.xml + +@ENABLE_HOSTNAMED_TRUE@am__append_72 = \ +@ENABLE_HOSTNAMED_TRUE@ hostnamed-install-data-hook + +@ENABLE_HOSTNAMED_TRUE@am__append_73 = \ +@ENABLE_HOSTNAMED_TRUE@ units/systemd-hostnamed.service.in + +@ENABLE_LOCALED_TRUE@am__append_74 = \ +@ENABLE_LOCALED_TRUE@ units/systemd-localed.service + +@ENABLE_LOCALED_TRUE@am__append_75 = \ +@ENABLE_LOCALED_TRUE@ systemd-localed + +@ENABLE_LOCALED_TRUE@am__append_76 = \ +@ENABLE_LOCALED_TRUE@ src/locale/org.freedesktop.locale1.conf + +@ENABLE_LOCALED_TRUE@am__append_77 = \ +@ENABLE_LOCALED_TRUE@ src/locale/org.freedesktop.locale1.service + +@ENABLE_LOCALED_TRUE@am__append_78 = \ +@ENABLE_LOCALED_TRUE@ src/locale/org.freedesktop.locale1.policy.in + +@ENABLE_LOCALED_TRUE@am__append_79 = \ +@ENABLE_LOCALED_TRUE@ org.freedesktop.locale1.xml + +@ENABLE_LOCALED_TRUE@am__append_80 = \ +@ENABLE_LOCALED_TRUE@ localed-install-data-hook + +@ENABLE_LOCALED_TRUE@am__append_81 = \ +@ENABLE_LOCALED_TRUE@ units/systemd-localed.service.in + +@ENABLE_TIMEDATED_TRUE@am__append_82 = \ +@ENABLE_TIMEDATED_TRUE@ systemd-timedated + +@ENABLE_TIMEDATED_TRUE@am__append_83 = \ +@ENABLE_TIMEDATED_TRUE@ src/timedate/org.freedesktop.timedate1.service + +@ENABLE_TIMEDATED_TRUE@am__append_84 = \ +@ENABLE_TIMEDATED_TRUE@ src/timedate/org.freedesktop.timedate1.conf + +@ENABLE_TIMEDATED_TRUE@am__append_85 = \ +@ENABLE_TIMEDATED_TRUE@ units/systemd-timedated.service + +@ENABLE_TIMEDATED_TRUE@am__append_86 = \ +@ENABLE_TIMEDATED_TRUE@ src/timedate/org.freedesktop.timedate1.policy.in + +@ENABLE_TIMEDATED_TRUE@am__append_87 = \ +@ENABLE_TIMEDATED_TRUE@ org.freedesktop.timedate1.xml + +@ENABLE_TIMEDATED_TRUE@am__append_88 = \ +@ENABLE_TIMEDATED_TRUE@ timedated-install-data-hook + +@ENABLE_TIMEDATED_TRUE@am__append_89 = \ +@ENABLE_TIMEDATED_TRUE@ units/systemd-timedated.service.in + +@ENABLE_LOGIND_TRUE@@HAVE_ACL_TRUE@am__append_90 = \ +@ENABLE_LOGIND_TRUE@@HAVE_ACL_TRUE@ src/login/logind-acl.c \ +@ENABLE_LOGIND_TRUE@@HAVE_ACL_TRUE@ src/acl-util.c + +@ENABLE_LOGIND_TRUE@am__append_91 = systemd-logind \ +@ENABLE_LOGIND_TRUE@ systemd-user-sessions systemd-multi-seat-x \ +@ENABLE_LOGIND_TRUE@ systemd-uaccess +@ENABLE_LOGIND_TRUE@am__append_92 = \ +@ENABLE_LOGIND_TRUE@ systemd-loginctl + +@ENABLE_LOGIND_TRUE@am__append_93 = \ +@ENABLE_LOGIND_TRUE@ test-login + +@ENABLE_LOGIND_TRUE@am__append_94 = \ +@ENABLE_LOGIND_TRUE@ libsystemd-login-install-hook + +@ENABLE_LOGIND_TRUE@am__append_95 = \ +@ENABLE_LOGIND_TRUE@ libsystemd-login-uninstall-hook + +@ENABLE_LOGIND_TRUE@am__append_96 = \ +@ENABLE_LOGIND_TRUE@ units/systemd-logind.service \ +@ENABLE_LOGIND_TRUE@ units/systemd-user-sessions.service + +@ENABLE_LOGIND_TRUE@am__append_97 = \ +@ENABLE_LOGIND_TRUE@ src/login/org.freedesktop.login1.service + +@ENABLE_LOGIND_TRUE@am__append_98 = \ +@ENABLE_LOGIND_TRUE@ src/login/org.freedesktop.login1.conf + +@ENABLE_LOGIND_TRUE@am__append_99 = \ +@ENABLE_LOGIND_TRUE@ src/login/systemd-logind.conf + +@ENABLE_LOGIND_TRUE@am__append_100 = \ +@ENABLE_LOGIND_TRUE@ src/systemd/sd-login.h + +@ENABLE_LOGIND_TRUE@am__append_101 = \ +@ENABLE_LOGIND_TRUE@ libsystemd-login.la + +@ENABLE_LOGIND_TRUE@am__append_102 = \ +@ENABLE_LOGIND_TRUE@ src/login/libsystemd-login.pc + +@ENABLE_LOGIND_TRUE@am__append_103 = \ +@ENABLE_LOGIND_TRUE@ src/login/org.freedesktop.login1.policy.in + +@ENABLE_LOGIND_TRUE@am__append_104 = \ +@ENABLE_LOGIND_TRUE@ logind-install-data-hook + +@ENABLE_LOGIND_TRUE@@HAVE_ACL_TRUE@am__append_105 = \ +@ENABLE_LOGIND_TRUE@@HAVE_ACL_TRUE@ src/login/logind-acl.c \ +@ENABLE_LOGIND_TRUE@@HAVE_ACL_TRUE@ src/acl-util.c + +@ENABLE_LOGIND_TRUE@am__append_106 = src/login/70-uaccess.rules \ +@ENABLE_LOGIND_TRUE@ src/login/71-seat.rules +@ENABLE_LOGIND_TRUE@am__append_107 = \ +@ENABLE_LOGIND_TRUE@ src/login/73-seat-late.rules + +@ENABLE_LOGIND_TRUE@am__append_108 = \ +@ENABLE_LOGIND_TRUE@ man/systemd-logind.conf.5 \ +@ENABLE_LOGIND_TRUE@ man/sd-login.7 \ +@ENABLE_LOGIND_TRUE@ man/systemd-loginctl.1 \ +@ENABLE_LOGIND_TRUE@ man/sd_login_monitor_new.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_pid_get_session.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_uid_get_state.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_session_is_active.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_seat_get_active.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_get_seats.3 + +@ENABLE_LOGIND_TRUE@am__append_109 = \ +@ENABLE_LOGIND_TRUE@ man/sd_login_monitor_unref.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_login_monitor_flush.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_login_monitor_get_fd.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_session_get_uid.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_session_get_seat.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_pid_get_owner_uid.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_pid_get_unit.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_uid_is_on_seat.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_uid_get_sessions.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_uid_get_seats.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_seat_get_sessions.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_seat_can_multi_session.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_get_sessions.3 \ +@ENABLE_LOGIND_TRUE@ man/sd_get_uids.3 + +@ENABLE_LOGIND_TRUE@am__append_110 = \ +@ENABLE_LOGIND_TRUE@ src/login/logind-gperf.gperf \ +@ENABLE_LOGIND_TRUE@ src/login/libsystemd-login.pc.in \ +@ENABLE_LOGIND_TRUE@ src/login/libsystemd-login.sym \ +@ENABLE_LOGIND_TRUE@ src/login/logind.h \ +@ENABLE_LOGIND_TRUE@ src/login/logind-device.h \ +@ENABLE_LOGIND_TRUE@ src/login/logind-seat.h \ +@ENABLE_LOGIND_TRUE@ src/login/logind-session.h \ +@ENABLE_LOGIND_TRUE@ src/login/logind-user.h \ +@ENABLE_LOGIND_TRUE@ src/login/logind-acl.h \ +@ENABLE_LOGIND_TRUE@ src/login/73-seat-late.rules.in \ +@ENABLE_LOGIND_TRUE@ units/systemd-logind.service.in \ +@ENABLE_LOGIND_TRUE@ units/systemd-user-sessions.service.in + +@ENABLE_LOGIND_TRUE@am__append_111 = \ +@ENABLE_LOGIND_TRUE@ src/login/logind-gperf.c \ +@ENABLE_LOGIND_TRUE@ src/login/73-seat-late.rules + +@HAVE_VALAC_TRUE@am__append_112 = \ +@HAVE_VALAC_TRUE@ ${systemadm_SOURCES:.vala=.c} + +@HAVE_XSLTPROC_TRUE@am__append_113 = \ +@HAVE_XSLTPROC_TRUE@ $(dist_man_MANS) \ +@HAVE_XSLTPROC_TRUE@ ${nodist_man_MANS:=.in} \ +@HAVE_XSLTPROC_TRUE@ ${XML_FILES:.xml=.html} \ +@HAVE_XSLTPROC_TRUE@ ${XML_IN_FILES:.xml.in=.html.in} + +subdir = . +DIST_COMMON = README $(am__configure_deps) \ + $(am__dist_dbuspolicy_DATA_DIST) \ + $(am__dist_dbussystemservice_DATA_DIST) \ + $(am__dist_noinst_DATA_DIST) $(am__dist_pkgdata_DATA_DIST) \ + $(am__dist_pkgsysconf_DATA_DIST) \ + $(am__dist_systemunit_DATA_DIST) \ + $(am__dist_tmpfiles_DATA_DIST) $(am__dist_udevrules_DATA_DIST) \ + $(am__pkginclude_HEADERS_DIST) $(dist_bashcompletion_DATA) \ + $(dist_bin_SCRIPTS) $(dist_doc_DATA) $(dist_man_MANS) \ + $(dist_userunit_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/configure NEWS TODO compile config.guess \ + config.sub depcomp install-sh libsystemd_basic_la_vala.stamp \ + libsystemd_core_la_vala.stamp libsystemd_daemon_la_vala.stamp \ + libsystemd_id128_la_vala.stamp \ + libsystemd_journal_la_vala.stamp \ + libsystemd_login_la_vala.stamp ltmain.sh missing \ + pam_systemd_la_vala.stamp src/gnome-ask-password-agent.c \ + src/systemadm.c src/systemd-interfaces.c src/wraplabel.c \ + systemadm_vala.stamp systemctl_vala.stamp \ + systemd_ac_power_vala.stamp systemd_ask_password_vala.stamp \ + systemd_binfmt_vala.stamp systemd_cat_vala.stamp \ + systemd_cgls_vala.stamp systemd_cgroups_agent_vala.stamp \ + systemd_cgtop_vala.stamp systemd_coredump_vala.stamp \ + systemd_cryptsetup_generator_vala.stamp \ + systemd_cryptsetup_vala.stamp systemd_detect_virt_vala.stamp \ + systemd_fsck_vala.stamp systemd_getty_generator_vala.stamp \ + systemd_gnome_ask_password_agent_vala.stamp \ + systemd_hostnamed_vala.stamp systemd_initctl_vala.stamp \ + systemd_journalctl_vala.stamp systemd_journald_vala.stamp \ + systemd_localed_vala.stamp systemd_loginctl_vala.stamp \ + systemd_logind_vala.stamp systemd_machine_id_setup_vala.stamp \ + systemd_modules_load_vala.stamp \ + systemd_multi_seat_x_vala.stamp systemd_notify_vala.stamp \ + systemd_nspawn_vala.stamp systemd_quotacheck_vala.stamp \ + systemd_random_seed_vala.stamp \ + systemd_rc_local_generator_vala.stamp \ + systemd_readahead_collect_vala.stamp \ + systemd_readahead_replay_vala.stamp \ + systemd_remount_api_vfs_vala.stamp \ + systemd_reply_password_vala.stamp systemd_shutdown_vala.stamp \ + systemd_shutdownd_vala.stamp systemd_stdio_bridge_vala.stamp \ + systemd_sysctl_vala.stamp systemd_timedated_vala.stamp \ + systemd_timestamp_vala.stamp systemd_tmpfiles_vala.stamp \ + systemd_tty_ask_password_agent_vala.stamp \ + systemd_uaccess_vala.stamp systemd_update_utmp_vala.stamp \ + systemd_user_sessions_vala.stamp systemd_vala.stamp \ + systemd_vconsole_setup_vala.stamp test_cgroup_vala.stamp \ + test_daemon_vala.stamp test_engine_vala.stamp \ + test_env_replace_vala.stamp test_hostname_vala.stamp \ + test_id128_vala.stamp test_install_vala.stamp \ + test_job_type_vala.stamp test_journal_vala.stamp \ + test_login_vala.stamp test_loopback_vala.stamp \ + test_ns_vala.stamp test_strv_vala.stamp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acx_libwrap.m4 \ + $(top_srcdir)/m4/attributes.m4 $(top_srcdir)/m4/intltool.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pamlibdir)" \ + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(rootbindir)" \ + "$(DESTDIR)$(rootlibexecdir)" \ + "$(DESTDIR)$(systemgeneratordir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" \ + "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man7dir)" \ + "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(dbusinterfacedir)" \ + "$(DESTDIR)$(bashcompletiondir)" "$(DESTDIR)$(dbuspolicydir)" \ + "$(DESTDIR)$(dbussystemservicedir)" "$(DESTDIR)$(docdir)" \ + "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgsysconfdir)" \ + "$(DESTDIR)$(systemunitdir)" "$(DESTDIR)$(tmpfilesdir)" \ + "$(DESTDIR)$(udevrulesdir)" "$(DESTDIR)$(userunitdir)" \ + "$(DESTDIR)$(polkitpolicydir)" "$(DESTDIR)$(systemunitdir)" \ + "$(DESTDIR)$(udevrulesdir)" "$(DESTDIR)$(userunitdir)" \ + "$(DESTDIR)$(pkgconfigdatadir)" "$(DESTDIR)$(pkgconfiglibdir)" \ + "$(DESTDIR)$(sysctldir)" "$(DESTDIR)$(pkgincludedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) \ + $(pamlib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libsystemd_basic_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__dirstamp = $(am__leading_dot)dirstamp +am_libsystemd_basic_la_OBJECTS = src/libsystemd_basic_la-util.lo \ + src/libsystemd_basic_la-virt.lo \ + src/libsystemd_basic_la-label.lo \ + src/libsystemd_basic_la-hashmap.lo \ + src/libsystemd_basic_la-set.lo src/libsystemd_basic_la-strv.lo \ + src/libsystemd_basic_la-conf-parser.lo \ + src/libsystemd_basic_la-socket-util.lo \ + src/libsystemd_basic_la-log.lo \ + src/libsystemd_basic_la-ratelimit.lo \ + src/libsystemd_basic_la-exit-status.lo +libsystemd_basic_la_OBJECTS = $(am_libsystemd_basic_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +libsystemd_basic_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libsystemd_basic_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +libsystemd_core_la_DEPENDENCIES = libsystemd-basic.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_libsystemd_core_la_OBJECTS = src/libsystemd_core_la-unit.lo \ + src/libsystemd_core_la-job.lo \ + src/libsystemd_core_la-manager.lo \ + src/libsystemd_core_la-path-lookup.lo \ + src/libsystemd_core_la-load-fragment.lo \ + src/libsystemd_core_la-service.lo \ + src/libsystemd_core_la-automount.lo \ + src/libsystemd_core_la-mount.lo src/libsystemd_core_la-swap.lo \ + src/libsystemd_core_la-device.lo \ + src/libsystemd_core_la-target.lo \ + src/libsystemd_core_la-snapshot.lo \ + src/libsystemd_core_la-socket.lo \ + src/libsystemd_core_la-timer.lo src/libsystemd_core_la-path.lo \ + src/libsystemd_core_la-load-dropin.lo \ + src/libsystemd_core_la-execute.lo \ + src/libsystemd_core_la-utmp-wtmp.lo \ + src/libsystemd_core_la-dbus.lo \ + src/libsystemd_core_la-dbus-manager.lo \ + src/libsystemd_core_la-dbus-unit.lo \ + src/libsystemd_core_la-dbus-job.lo \ + src/libsystemd_core_la-dbus-service.lo \ + src/libsystemd_core_la-dbus-socket.lo \ + src/libsystemd_core_la-dbus-timer.lo \ + src/libsystemd_core_la-dbus-target.lo \ + src/libsystemd_core_la-dbus-mount.lo \ + src/libsystemd_core_la-dbus-automount.lo \ + src/libsystemd_core_la-dbus-swap.lo \ + src/libsystemd_core_la-dbus-snapshot.lo \ + src/libsystemd_core_la-dbus-device.lo \ + src/libsystemd_core_la-dbus-execute.lo \ + src/libsystemd_core_la-dbus-path.lo \ + src/libsystemd_core_la-cgroup.lo \ + src/libsystemd_core_la-mount-setup.lo \ + src/libsystemd_core_la-hostname-setup.lo \ + src/libsystemd_core_la-selinux-setup.lo \ + src/libsystemd_core_la-loopback-setup.lo \ + src/libsystemd_core_la-kmod-setup.lo \ + src/libsystemd_core_la-locale-setup.lo \ + src/libsystemd_core_la-machine-id-setup.lo \ + src/libsystemd_core_la-specifier.lo \ + src/libsystemd_core_la-unit-name.lo \ + src/libsystemd_core_la-fdset.lo \ + src/libsystemd_core_la-namespace.lo \ + src/libsystemd_core_la-tcpwrap.lo \ + src/libsystemd_core_la-cgroup-util.lo \ + src/libsystemd_core_la-condition.lo \ + src/libsystemd_core_la-dbus-common.lo \ + src/libsystemd_core_la-sd-daemon.lo \ + src/libsystemd_core_la-install.lo \ + src/libsystemd_core_la-cgroup-attr.lo \ + src/libsystemd_core_la-sd-id128.lo +nodist_libsystemd_core_la_OBJECTS = \ + src/libsystemd_core_la-load-fragment-gperf.lo \ + src/libsystemd_core_la-load-fragment-gperf-nulstr.lo +libsystemd_core_la_OBJECTS = $(am_libsystemd_core_la_OBJECTS) \ + $(nodist_libsystemd_core_la_OBJECTS) +libsystemd_core_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libsystemd_core_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +libsystemd_daemon_la_LIBADD = +am_libsystemd_daemon_la_OBJECTS = \ + src/libsystemd_daemon_la-sd-daemon.lo +libsystemd_daemon_la_OBJECTS = $(am_libsystemd_daemon_la_OBJECTS) +libsystemd_daemon_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libsystemd_daemon_la_CFLAGS) $(CFLAGS) \ + $(libsystemd_daemon_la_LDFLAGS) $(LDFLAGS) -o $@ +libsystemd_id128_la_DEPENDENCIES = libsystemd-basic.la +am_libsystemd_id128_la_OBJECTS = src/libsystemd_id128_la-sd-id128.lo +libsystemd_id128_la_OBJECTS = $(am_libsystemd_id128_la_OBJECTS) +libsystemd_id128_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libsystemd_id128_la_CFLAGS) $(CFLAGS) \ + $(libsystemd_id128_la_LDFLAGS) $(LDFLAGS) -o $@ +@HAVE_XZ_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +libsystemd_journal_la_DEPENDENCIES = libsystemd-basic.la \ + libsystemd-id128.la $(am__DEPENDENCIES_2) +am__libsystemd_journal_la_SOURCES_DIST = src/journal/sd-journal.c \ + src/journal/journal-file.c src/journal/lookup3.c \ + src/journal/journal-send.c src/journal/compress.c +@HAVE_XZ_TRUE@am__objects_1 = \ +@HAVE_XZ_TRUE@ src/journal/libsystemd_journal_la-compress.lo +am_libsystemd_journal_la_OBJECTS = \ + src/journal/libsystemd_journal_la-sd-journal.lo \ + src/journal/libsystemd_journal_la-journal-file.lo \ + src/journal/libsystemd_journal_la-lookup3.lo \ + src/journal/libsystemd_journal_la-journal-send.lo \ + $(am__objects_1) +libsystemd_journal_la_OBJECTS = $(am_libsystemd_journal_la_OBJECTS) +libsystemd_journal_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libsystemd_journal_la_CFLAGS) $(CFLAGS) \ + $(libsystemd_journal_la_LDFLAGS) $(LDFLAGS) -o $@ +@ENABLE_LOGIND_TRUE@libsystemd_login_la_DEPENDENCIES = \ +@ENABLE_LOGIND_TRUE@ libsystemd-basic.la +am__libsystemd_login_la_SOURCES_DIST = src/login/sd-login.c \ + src/cgroup-util.c +@ENABLE_LOGIND_TRUE@am_libsystemd_login_la_OBJECTS = \ +@ENABLE_LOGIND_TRUE@ src/login/libsystemd_login_la-sd-login.lo \ +@ENABLE_LOGIND_TRUE@ src/libsystemd_login_la-cgroup-util.lo +libsystemd_login_la_OBJECTS = $(am_libsystemd_login_la_OBJECTS) +libsystemd_login_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libsystemd_login_la_CFLAGS) $(CFLAGS) \ + $(libsystemd_login_la_LDFLAGS) $(LDFLAGS) -o $@ +@ENABLE_LOGIND_TRUE@am_libsystemd_login_la_rpath = -rpath $(libdir) +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@pam_systemd_la_DEPENDENCIES = \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ libsystemd-basic.la \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ libsystemd-daemon.la \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ $(am__DEPENDENCIES_1) \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ $(am__DEPENDENCIES_1) +am__pam_systemd_la_SOURCES_DIST = src/login/pam-module.c \ + src/dbus-common.c +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@am_pam_systemd_la_OBJECTS = src/login/pam_systemd_la-pam-module.lo \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ src/pam_systemd_la-dbus-common.lo +pam_systemd_la_OBJECTS = $(am_pam_systemd_la_OBJECTS) +pam_systemd_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(pam_systemd_la_CFLAGS) $(CFLAGS) $(pam_systemd_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@am_pam_systemd_la_rpath = -rpath \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ $(pamlibdir) +@HAVE_GTK_TRUE@am__EXEEXT_1 = systemadm$(EXEEXT) \ +@HAVE_GTK_TRUE@ systemd-gnome-ask-password-agent$(EXEEXT) +@ENABLE_LOGIND_TRUE@am__EXEEXT_2 = test-login$(EXEEXT) +@ENABLE_LOGIND_TRUE@am__EXEEXT_3 = systemd-loginctl$(EXEEXT) +@ENABLE_COREDUMP_TRUE@am__EXEEXT_4 = systemd-coredump$(EXEEXT) +@ENABLE_BINFMT_TRUE@am__EXEEXT_5 = systemd-binfmt$(EXEEXT) +@ENABLE_VCONSOLE_TRUE@am__EXEEXT_6 = systemd-vconsole-setup$(EXEEXT) +@ENABLE_READAHEAD_TRUE@am__EXEEXT_7 = \ +@ENABLE_READAHEAD_TRUE@ systemd-readahead-collect$(EXEEXT) \ +@ENABLE_READAHEAD_TRUE@ systemd-readahead-replay$(EXEEXT) +@ENABLE_QUOTACHECK_TRUE@am__EXEEXT_8 = systemd-quotacheck$(EXEEXT) +@ENABLE_RANDOMSEED_TRUE@am__EXEEXT_9 = systemd-random-seed$(EXEEXT) +@HAVE_LIBCRYPTSETUP_TRUE@am__EXEEXT_10 = systemd-cryptsetup$(EXEEXT) +@ENABLE_HOSTNAMED_TRUE@am__EXEEXT_11 = systemd-hostnamed$(EXEEXT) +@ENABLE_LOCALED_TRUE@am__EXEEXT_12 = systemd-localed$(EXEEXT) +@ENABLE_TIMEDATED_TRUE@am__EXEEXT_13 = systemd-timedated$(EXEEXT) +@ENABLE_LOGIND_TRUE@am__EXEEXT_14 = systemd-logind$(EXEEXT) \ +@ENABLE_LOGIND_TRUE@ systemd-user-sessions$(EXEEXT) \ +@ENABLE_LOGIND_TRUE@ systemd-multi-seat-x$(EXEEXT) \ +@ENABLE_LOGIND_TRUE@ systemd-uaccess$(EXEEXT) +@TARGET_FEDORA_TRUE@am__EXEEXT_15 = \ +@TARGET_FEDORA_TRUE@ systemd-rc-local-generator$(EXEEXT) +@TARGET_MANDRIVA_TRUE@am__EXEEXT_16 = \ +@TARGET_MANDRIVA_TRUE@ systemd-rc-local-generator$(EXEEXT) +@TARGET_SUSE_TRUE@am__EXEEXT_17 = systemd-rc-local-generator$(EXEEXT) +@TARGET_MAGEIA_TRUE@am__EXEEXT_18 = \ +@TARGET_MAGEIA_TRUE@ systemd-rc-local-generator$(EXEEXT) +@HAVE_LIBCRYPTSETUP_TRUE@am__EXEEXT_19 = systemd-cryptsetup-generator$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(rootbin_PROGRAMS) \ + $(rootlibexec_PROGRAMS) $(systemgenerator_PROGRAMS) +am_systemadm_OBJECTS = src/systemadm-systemadm.$(OBJEXT) \ + src/systemadm-systemd-interfaces.$(OBJEXT) \ + src/systemadm-wraplabel.$(OBJEXT) +systemadm_OBJECTS = $(am_systemadm_OBJECTS) +systemadm_DEPENDENCIES = $(am__DEPENDENCIES_1) +systemadm_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(systemadm_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am_systemctl_OBJECTS = src/systemctl-systemctl.$(OBJEXT) \ + src/systemctl-utmp-wtmp.$(OBJEXT) \ + src/systemctl-dbus-common.$(OBJEXT) \ + src/systemctl-path-lookup.$(OBJEXT) \ + src/systemctl-cgroup-show.$(OBJEXT) \ + src/systemctl-cgroup-util.$(OBJEXT) \ + src/systemctl-exit-status.$(OBJEXT) \ + src/systemctl-unit-name.$(OBJEXT) \ + src/systemctl-pager.$(OBJEXT) src/systemctl-install.$(OBJEXT) \ + src/systemctl-spawn-agent.$(OBJEXT) \ + src/systemctl-logs-show.$(OBJEXT) +systemctl_OBJECTS = $(am_systemctl_OBJECTS) +systemctl_DEPENDENCIES = libsystemd-basic.la libsystemd-daemon.la \ + libsystemd-journal.la libsystemd-id128.la \ + $(am__DEPENDENCIES_1) +systemctl_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(systemctl_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am_systemd_OBJECTS = src/systemd-main.$(OBJEXT) +systemd_OBJECTS = $(am_systemd_OBJECTS) +systemd_DEPENDENCIES = libsystemd-core.la +systemd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(systemd_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am_systemd_ac_power_OBJECTS = src/systemd_ac_power-ac-power.$(OBJEXT) +systemd_ac_power_OBJECTS = $(am_systemd_ac_power_OBJECTS) +systemd_ac_power_DEPENDENCIES = libsystemd-basic.la \ + $(am__DEPENDENCIES_1) +systemd_ac_power_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_ac_power_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +am_systemd_ask_password_OBJECTS = src/ask-password.$(OBJEXT) \ + src/ask-password-api.$(OBJEXT) +systemd_ask_password_OBJECTS = $(am_systemd_ask_password_OBJECTS) +systemd_ask_password_DEPENDENCIES = libsystemd-basic.la +am__systemd_binfmt_SOURCES_DIST = src/binfmt/binfmt.c +@ENABLE_BINFMT_TRUE@am_systemd_binfmt_OBJECTS = \ +@ENABLE_BINFMT_TRUE@ src/binfmt/binfmt.$(OBJEXT) +systemd_binfmt_OBJECTS = $(am_systemd_binfmt_OBJECTS) +@ENABLE_BINFMT_TRUE@systemd_binfmt_DEPENDENCIES = libsystemd-basic.la +am_systemd_cat_OBJECTS = src/journal/cat.$(OBJEXT) +systemd_cat_OBJECTS = $(am_systemd_cat_OBJECTS) +systemd_cat_DEPENDENCIES = libsystemd-basic.la libsystemd-journal.la +am_systemd_cgls_OBJECTS = src/cgls.$(OBJEXT) src/cgroup-show.$(OBJEXT) \ + src/cgroup-util.$(OBJEXT) src/pager.$(OBJEXT) +systemd_cgls_OBJECTS = $(am_systemd_cgls_OBJECTS) +systemd_cgls_DEPENDENCIES = libsystemd-basic.la +am_systemd_cgroups_agent_OBJECTS = \ + src/systemd_cgroups_agent-cgroups-agent.$(OBJEXT) \ + src/systemd_cgroups_agent-dbus-common.$(OBJEXT) +systemd_cgroups_agent_OBJECTS = $(am_systemd_cgroups_agent_OBJECTS) +systemd_cgroups_agent_DEPENDENCIES = libsystemd-basic.la \ + $(am__DEPENDENCIES_1) +systemd_cgroups_agent_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_cgroups_agent_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_systemd_cgtop_OBJECTS = src/cgtop.$(OBJEXT) \ + src/cgroup-util.$(OBJEXT) +systemd_cgtop_OBJECTS = $(am_systemd_cgtop_OBJECTS) +systemd_cgtop_DEPENDENCIES = libsystemd-basic.la +am__systemd_coredump_SOURCES_DIST = src/journal/coredump.c +@ENABLE_COREDUMP_TRUE@am_systemd_coredump_OBJECTS = \ +@ENABLE_COREDUMP_TRUE@ src/journal/coredump.$(OBJEXT) +systemd_coredump_OBJECTS = $(am_systemd_coredump_OBJECTS) +@ENABLE_COREDUMP_TRUE@systemd_coredump_DEPENDENCIES = \ +@ENABLE_COREDUMP_TRUE@ libsystemd-basic.la \ +@ENABLE_COREDUMP_TRUE@ libsystemd-journal.la \ +@ENABLE_COREDUMP_TRUE@ libsystemd-login.la +am__systemd_cryptsetup_SOURCES_DIST = src/cryptsetup/cryptsetup.c \ + src/ask-password-api.c +@HAVE_LIBCRYPTSETUP_TRUE@am_systemd_cryptsetup_OBJECTS = src/cryptsetup/systemd_cryptsetup-cryptsetup.$(OBJEXT) \ +@HAVE_LIBCRYPTSETUP_TRUE@ src/systemd_cryptsetup-ask-password-api.$(OBJEXT) +systemd_cryptsetup_OBJECTS = $(am_systemd_cryptsetup_OBJECTS) +@HAVE_LIBCRYPTSETUP_TRUE@systemd_cryptsetup_DEPENDENCIES = \ +@HAVE_LIBCRYPTSETUP_TRUE@ $(am__DEPENDENCIES_1) \ +@HAVE_LIBCRYPTSETUP_TRUE@ $(am__DEPENDENCIES_1) \ +@HAVE_LIBCRYPTSETUP_TRUE@ libsystemd-basic.la +systemd_cryptsetup_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_cryptsetup_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +am__systemd_cryptsetup_generator_SOURCES_DIST = \ + src/cryptsetup/cryptsetup-generator.c src/unit-name.c +@HAVE_LIBCRYPTSETUP_TRUE@am_systemd_cryptsetup_generator_OBJECTS = src/cryptsetup/cryptsetup-generator.$(OBJEXT) \ +@HAVE_LIBCRYPTSETUP_TRUE@ src/unit-name.$(OBJEXT) +systemd_cryptsetup_generator_OBJECTS = \ + $(am_systemd_cryptsetup_generator_OBJECTS) +@HAVE_LIBCRYPTSETUP_TRUE@systemd_cryptsetup_generator_DEPENDENCIES = \ +@HAVE_LIBCRYPTSETUP_TRUE@ libsystemd-basic.la +am_systemd_detect_virt_OBJECTS = src/detect-virt.$(OBJEXT) +systemd_detect_virt_OBJECTS = $(am_systemd_detect_virt_OBJECTS) +systemd_detect_virt_DEPENDENCIES = libsystemd-basic.la +am_systemd_fsck_OBJECTS = src/systemd_fsck-fsck.$(OBJEXT) \ + src/systemd_fsck-dbus-common.$(OBJEXT) +systemd_fsck_OBJECTS = $(am_systemd_fsck_OBJECTS) +systemd_fsck_DEPENDENCIES = libsystemd-basic.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +systemd_fsck_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(systemd_fsck_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am_systemd_getty_generator_OBJECTS = src/getty-generator.$(OBJEXT) \ + src/unit-name.$(OBJEXT) +systemd_getty_generator_OBJECTS = \ + $(am_systemd_getty_generator_OBJECTS) +systemd_getty_generator_DEPENDENCIES = libsystemd-basic.la +am_systemd_gnome_ask_password_agent_OBJECTS = src/systemd_gnome_ask_password_agent-gnome-ask-password-agent.$(OBJEXT) +systemd_gnome_ask_password_agent_OBJECTS = \ + $(am_systemd_gnome_ask_password_agent_OBJECTS) +systemd_gnome_ask_password_agent_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +systemd_gnome_ask_password_agent_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_gnome_ask_password_agent_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am__systemd_hostnamed_SOURCES_DIST = src/hostname/hostnamed.c \ + src/dbus-common.c src/polkit.c +@ENABLE_HOSTNAMED_TRUE@am_systemd_hostnamed_OBJECTS = src/hostname/systemd_hostnamed-hostnamed.$(OBJEXT) \ +@ENABLE_HOSTNAMED_TRUE@ src/systemd_hostnamed-dbus-common.$(OBJEXT) \ +@ENABLE_HOSTNAMED_TRUE@ src/systemd_hostnamed-polkit.$(OBJEXT) +systemd_hostnamed_OBJECTS = $(am_systemd_hostnamed_OBJECTS) +@ENABLE_HOSTNAMED_TRUE@systemd_hostnamed_DEPENDENCIES = \ +@ENABLE_HOSTNAMED_TRUE@ libsystemd-basic.la \ +@ENABLE_HOSTNAMED_TRUE@ libsystemd-daemon.la \ +@ENABLE_HOSTNAMED_TRUE@ $(am__DEPENDENCIES_1) +systemd_hostnamed_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_hostnamed_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +am_systemd_initctl_OBJECTS = src/systemd_initctl-initctl.$(OBJEXT) \ + src/systemd_initctl-dbus-common.$(OBJEXT) +systemd_initctl_OBJECTS = $(am_systemd_initctl_OBJECTS) +systemd_initctl_DEPENDENCIES = libsystemd-basic.la \ + libsystemd-daemon.la $(am__DEPENDENCIES_1) +systemd_initctl_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_initctl_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +am__systemd_journalctl_SOURCES_DIST = src/journal/journalctl.c \ + src/pager.c src/logs-show.c src/journal/compress.c +@HAVE_XZ_TRUE@am__objects_2 = src/journal/systemd_journalctl-compress.$(OBJEXT) +am_systemd_journalctl_OBJECTS = \ + src/journal/systemd_journalctl-journalctl.$(OBJEXT) \ + src/systemd_journalctl-pager.$(OBJEXT) \ + src/systemd_journalctl-logs-show.$(OBJEXT) $(am__objects_2) +systemd_journalctl_OBJECTS = $(am_systemd_journalctl_OBJECTS) +systemd_journalctl_DEPENDENCIES = libsystemd-basic.la \ + libsystemd-journal.la libsystemd-id128.la \ + $(am__DEPENDENCIES_2) +systemd_journalctl_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_journalctl_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +am__systemd_journald_SOURCES_DIST = src/journal/journald.c \ + src/journal/sd-journal.c src/journal/journal-file.c \ + src/journal/lookup3.c src/journal/journal-rate-limit.c \ + src/sd-id128.c src/cgroup-util.c src/acl-util.c \ + src/journal/compress.c +@HAVE_ACL_TRUE@am__objects_3 = \ +@HAVE_ACL_TRUE@ src/systemd_journald-acl-util.$(OBJEXT) +@HAVE_XZ_TRUE@am__objects_4 = \ +@HAVE_XZ_TRUE@ src/journal/systemd_journald-compress.$(OBJEXT) +am_systemd_journald_OBJECTS = \ + src/journal/systemd_journald-journald.$(OBJEXT) \ + src/journal/systemd_journald-sd-journal.$(OBJEXT) \ + src/journal/systemd_journald-journal-file.$(OBJEXT) \ + src/journal/systemd_journald-lookup3.$(OBJEXT) \ + src/journal/systemd_journald-journal-rate-limit.$(OBJEXT) \ + src/systemd_journald-sd-id128.$(OBJEXT) \ + src/systemd_journald-cgroup-util.$(OBJEXT) $(am__objects_3) \ + $(am__objects_4) +nodist_systemd_journald_OBJECTS = \ + src/journal/systemd_journald-journald-gperf.$(OBJEXT) +systemd_journald_OBJECTS = $(am_systemd_journald_OBJECTS) \ + $(nodist_systemd_journald_OBJECTS) +systemd_journald_DEPENDENCIES = libsystemd-basic.la \ + libsystemd-daemon.la libsystemd-login.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_2) +systemd_journald_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_journald_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +am__systemd_localed_SOURCES_DIST = src/locale/localed.c \ + src/dbus-common.c src/polkit.c +@ENABLE_LOCALED_TRUE@am_systemd_localed_OBJECTS = src/locale/systemd_localed-localed.$(OBJEXT) \ +@ENABLE_LOCALED_TRUE@ src/systemd_localed-dbus-common.$(OBJEXT) \ +@ENABLE_LOCALED_TRUE@ src/systemd_localed-polkit.$(OBJEXT) +systemd_localed_OBJECTS = $(am_systemd_localed_OBJECTS) +@ENABLE_LOCALED_TRUE@systemd_localed_DEPENDENCIES = \ +@ENABLE_LOCALED_TRUE@ libsystemd-basic.la libsystemd-daemon.la \ +@ENABLE_LOCALED_TRUE@ $(am__DEPENDENCIES_1) +systemd_localed_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_localed_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +am__systemd_loginctl_SOURCES_DIST = src/login/loginctl.c \ + src/login/sysfs-show.c src/dbus-common.c src/cgroup-show.c \ + src/cgroup-util.c src/pager.c +@ENABLE_LOGIND_TRUE@am_systemd_loginctl_OBJECTS = src/login/systemd_loginctl-loginctl.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/login/systemd_loginctl-sysfs-show.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/systemd_loginctl-dbus-common.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/systemd_loginctl-cgroup-show.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/systemd_loginctl-cgroup-util.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/systemd_loginctl-pager.$(OBJEXT) +systemd_loginctl_OBJECTS = $(am_systemd_loginctl_OBJECTS) +@ENABLE_LOGIND_TRUE@systemd_loginctl_DEPENDENCIES = \ +@ENABLE_LOGIND_TRUE@ libsystemd-basic.la $(am__DEPENDENCIES_1) \ +@ENABLE_LOGIND_TRUE@ $(am__DEPENDENCIES_1) +systemd_loginctl_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_loginctl_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +am__systemd_logind_SOURCES_DIST = src/login/logind.c \ + src/login/logind-dbus.c src/login/logind-device.c \ + src/login/logind-seat.c src/login/logind-seat-dbus.c \ + src/login/logind-session.c src/login/logind-session-dbus.c \ + src/login/logind-user.c src/login/logind-user-dbus.c \ + src/dbus-common.c src/dbus-loop.c src/cgroup-util.c \ + src/polkit.c src/login/logind-acl.c src/acl-util.c +@ENABLE_LOGIND_TRUE@@HAVE_ACL_TRUE@am__objects_5 = src/login/systemd_logind-logind-acl.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@@HAVE_ACL_TRUE@ src/systemd_logind-acl-util.$(OBJEXT) +@ENABLE_LOGIND_TRUE@am_systemd_logind_OBJECTS = \ +@ENABLE_LOGIND_TRUE@ src/login/systemd_logind-logind.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/login/systemd_logind-logind-dbus.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/login/systemd_logind-logind-device.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/login/systemd_logind-logind-seat.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/login/systemd_logind-logind-seat-dbus.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/login/systemd_logind-logind-session.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/login/systemd_logind-logind-session-dbus.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/login/systemd_logind-logind-user.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/login/systemd_logind-logind-user-dbus.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/systemd_logind-dbus-common.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/systemd_logind-dbus-loop.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/systemd_logind-cgroup-util.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/systemd_logind-polkit.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ $(am__objects_5) +@ENABLE_LOGIND_TRUE@nodist_systemd_logind_OBJECTS = src/login/systemd_logind-logind-gperf.$(OBJEXT) +systemd_logind_OBJECTS = $(am_systemd_logind_OBJECTS) \ + $(nodist_systemd_logind_OBJECTS) +@ENABLE_LOGIND_TRUE@systemd_logind_DEPENDENCIES = libsystemd-basic.la \ +@ENABLE_LOGIND_TRUE@ libsystemd-daemon.la $(am__DEPENDENCIES_1) \ +@ENABLE_LOGIND_TRUE@ $(am__DEPENDENCIES_1) \ +@ENABLE_LOGIND_TRUE@ $(am__DEPENDENCIES_1) +systemd_logind_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_logind_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ + $@ +am_systemd_machine_id_setup_OBJECTS = src/machine-id-setup.$(OBJEXT) \ + src/machine-id-main.$(OBJEXT) src/sd-id128.$(OBJEXT) +systemd_machine_id_setup_OBJECTS = \ + $(am_systemd_machine_id_setup_OBJECTS) +systemd_machine_id_setup_DEPENDENCIES = libsystemd-basic.la +am_systemd_modules_load_OBJECTS = \ + src/systemd_modules_load-modules-load.$(OBJEXT) +systemd_modules_load_OBJECTS = $(am_systemd_modules_load_OBJECTS) +systemd_modules_load_DEPENDENCIES = libsystemd-basic.la \ + $(am__DEPENDENCIES_1) +systemd_modules_load_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_modules_load_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +am__systemd_multi_seat_x_SOURCES_DIST = src/login/multi-seat-x.c +@ENABLE_LOGIND_TRUE@am_systemd_multi_seat_x_OBJECTS = src/login/systemd_multi_seat_x-multi-seat-x.$(OBJEXT) +systemd_multi_seat_x_OBJECTS = $(am_systemd_multi_seat_x_OBJECTS) +@ENABLE_LOGIND_TRUE@systemd_multi_seat_x_DEPENDENCIES = \ +@ENABLE_LOGIND_TRUE@ libsystemd-basic.la $(am__DEPENDENCIES_1) +systemd_multi_seat_x_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_multi_seat_x_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_systemd_notify_OBJECTS = src/notify.$(OBJEXT) \ + src/readahead/sd-readahead.$(OBJEXT) +systemd_notify_OBJECTS = $(am_systemd_notify_OBJECTS) +systemd_notify_DEPENDENCIES = libsystemd-basic.la libsystemd-daemon.la +am_systemd_nspawn_OBJECTS = src/nspawn.$(OBJEXT) \ + src/cgroup-util.$(OBJEXT) src/loopback-setup.$(OBJEXT) +systemd_nspawn_OBJECTS = $(am_systemd_nspawn_OBJECTS) +systemd_nspawn_DEPENDENCIES = libsystemd-basic.la libsystemd-daemon.la +am__systemd_quotacheck_SOURCES_DIST = src/quotacheck.c +@ENABLE_QUOTACHECK_TRUE@am_systemd_quotacheck_OBJECTS = \ +@ENABLE_QUOTACHECK_TRUE@ src/quotacheck.$(OBJEXT) +systemd_quotacheck_OBJECTS = $(am_systemd_quotacheck_OBJECTS) +@ENABLE_QUOTACHECK_TRUE@systemd_quotacheck_DEPENDENCIES = \ +@ENABLE_QUOTACHECK_TRUE@ libsystemd-basic.la +am__systemd_random_seed_SOURCES_DIST = src/random-seed.c +@ENABLE_RANDOMSEED_TRUE@am_systemd_random_seed_OBJECTS = \ +@ENABLE_RANDOMSEED_TRUE@ src/random-seed.$(OBJEXT) +systemd_random_seed_OBJECTS = $(am_systemd_random_seed_OBJECTS) +@ENABLE_RANDOMSEED_TRUE@systemd_random_seed_DEPENDENCIES = \ +@ENABLE_RANDOMSEED_TRUE@ libsystemd-basic.la +am_systemd_rc_local_generator_OBJECTS = \ + src/rc-local-generator.$(OBJEXT) +systemd_rc_local_generator_OBJECTS = \ + $(am_systemd_rc_local_generator_OBJECTS) +systemd_rc_local_generator_DEPENDENCIES = libsystemd-basic.la +am__systemd_readahead_collect_SOURCES_DIST = \ + src/readahead/readahead-collect.c \ + src/readahead/readahead-common.c +@ENABLE_READAHEAD_TRUE@am_systemd_readahead_collect_OBJECTS = src/readahead/systemd_readahead_collect-readahead-collect.$(OBJEXT) \ +@ENABLE_READAHEAD_TRUE@ src/readahead/systemd_readahead_collect-readahead-common.$(OBJEXT) +systemd_readahead_collect_OBJECTS = \ + $(am_systemd_readahead_collect_OBJECTS) +@ENABLE_READAHEAD_TRUE@systemd_readahead_collect_DEPENDENCIES = \ +@ENABLE_READAHEAD_TRUE@ libsystemd-basic.la \ +@ENABLE_READAHEAD_TRUE@ libsystemd-daemon.la \ +@ENABLE_READAHEAD_TRUE@ $(am__DEPENDENCIES_1) +systemd_readahead_collect_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_readahead_collect_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +am__systemd_readahead_replay_SOURCES_DIST = \ + src/readahead/readahead-replay.c \ + src/readahead/readahead-common.c +@ENABLE_READAHEAD_TRUE@am_systemd_readahead_replay_OBJECTS = src/readahead/systemd_readahead_replay-readahead-replay.$(OBJEXT) \ +@ENABLE_READAHEAD_TRUE@ src/readahead/systemd_readahead_replay-readahead-common.$(OBJEXT) +systemd_readahead_replay_OBJECTS = \ + $(am_systemd_readahead_replay_OBJECTS) +@ENABLE_READAHEAD_TRUE@systemd_readahead_replay_DEPENDENCIES = \ +@ENABLE_READAHEAD_TRUE@ libsystemd-basic.la \ +@ENABLE_READAHEAD_TRUE@ libsystemd-daemon.la \ +@ENABLE_READAHEAD_TRUE@ $(am__DEPENDENCIES_1) +systemd_readahead_replay_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_readahead_replay_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +am_systemd_remount_api_vfs_OBJECTS = src/remount-api-vfs.$(OBJEXT) \ + src/mount-setup.$(OBJEXT) src/exit-status.$(OBJEXT) +systemd_remount_api_vfs_OBJECTS = \ + $(am_systemd_remount_api_vfs_OBJECTS) +systemd_remount_api_vfs_DEPENDENCIES = libsystemd-basic.la +am_systemd_reply_password_OBJECTS = src/reply-password.$(OBJEXT) +systemd_reply_password_OBJECTS = $(am_systemd_reply_password_OBJECTS) +systemd_reply_password_DEPENDENCIES = libsystemd-basic.la +am_systemd_shutdown_OBJECTS = \ + src/systemd_shutdown-mount-setup.$(OBJEXT) \ + src/systemd_shutdown-umount.$(OBJEXT) \ + src/systemd_shutdown-shutdown.$(OBJEXT) +systemd_shutdown_OBJECTS = $(am_systemd_shutdown_OBJECTS) +systemd_shutdown_DEPENDENCIES = libsystemd-basic.la \ + $(am__DEPENDENCIES_1) +systemd_shutdown_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_shutdown_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +am_systemd_shutdownd_OBJECTS = \ + src/systemd_shutdownd-utmp-wtmp.$(OBJEXT) \ + src/systemd_shutdownd-shutdownd.$(OBJEXT) +systemd_shutdownd_OBJECTS = $(am_systemd_shutdownd_OBJECTS) +systemd_shutdownd_DEPENDENCIES = libsystemd-basic.la \ + libsystemd-daemon.la +systemd_shutdownd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_shutdownd_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +am_systemd_stdio_bridge_OBJECTS = src/bridge.$(OBJEXT) +systemd_stdio_bridge_OBJECTS = $(am_systemd_stdio_bridge_OBJECTS) +systemd_stdio_bridge_DEPENDENCIES = libsystemd-basic.la +am_systemd_sysctl_OBJECTS = src/sysctl.$(OBJEXT) +systemd_sysctl_OBJECTS = $(am_systemd_sysctl_OBJECTS) +systemd_sysctl_DEPENDENCIES = libsystemd-basic.la +am__systemd_timedated_SOURCES_DIST = src/timedate/timedated.c \ + src/dbus-common.c src/polkit.c +@ENABLE_TIMEDATED_TRUE@am_systemd_timedated_OBJECTS = src/timedate/systemd_timedated-timedated.$(OBJEXT) \ +@ENABLE_TIMEDATED_TRUE@ src/systemd_timedated-dbus-common.$(OBJEXT) \ +@ENABLE_TIMEDATED_TRUE@ src/systemd_timedated-polkit.$(OBJEXT) +systemd_timedated_OBJECTS = $(am_systemd_timedated_OBJECTS) +@ENABLE_TIMEDATED_TRUE@systemd_timedated_DEPENDENCIES = \ +@ENABLE_TIMEDATED_TRUE@ libsystemd-basic.la \ +@ENABLE_TIMEDATED_TRUE@ libsystemd-daemon.la \ +@ENABLE_TIMEDATED_TRUE@ $(am__DEPENDENCIES_1) +systemd_timedated_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_timedated_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +am_systemd_timestamp_OBJECTS = src/timestamp.$(OBJEXT) +systemd_timestamp_OBJECTS = $(am_systemd_timestamp_OBJECTS) +systemd_timestamp_DEPENDENCIES = libsystemd-basic.la +am_systemd_tmpfiles_OBJECTS = src/tmpfiles.$(OBJEXT) +systemd_tmpfiles_OBJECTS = $(am_systemd_tmpfiles_OBJECTS) +systemd_tmpfiles_DEPENDENCIES = libsystemd-basic.la +am_systemd_tty_ask_password_agent_OBJECTS = \ + src/tty-ask-password-agent.$(OBJEXT) \ + src/ask-password-api.$(OBJEXT) src/utmp-wtmp.$(OBJEXT) +systemd_tty_ask_password_agent_OBJECTS = \ + $(am_systemd_tty_ask_password_agent_OBJECTS) +systemd_tty_ask_password_agent_DEPENDENCIES = libsystemd-basic.la +am__systemd_uaccess_SOURCES_DIST = src/login/uaccess.c \ + src/login/logind-acl.c src/acl-util.c +@ENABLE_LOGIND_TRUE@@HAVE_ACL_TRUE@am__objects_6 = src/login/systemd_uaccess-logind-acl.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@@HAVE_ACL_TRUE@ src/systemd_uaccess-acl-util.$(OBJEXT) +@ENABLE_LOGIND_TRUE@am_systemd_uaccess_OBJECTS = src/login/systemd_uaccess-uaccess.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ $(am__objects_6) +systemd_uaccess_OBJECTS = $(am_systemd_uaccess_OBJECTS) +@ENABLE_LOGIND_TRUE@systemd_uaccess_DEPENDENCIES = \ +@ENABLE_LOGIND_TRUE@ libsystemd-basic.la libsystemd-daemon.la \ +@ENABLE_LOGIND_TRUE@ libsystemd-login.la $(am__DEPENDENCIES_1) \ +@ENABLE_LOGIND_TRUE@ $(am__DEPENDENCIES_1) +systemd_uaccess_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_uaccess_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +am_systemd_update_utmp_OBJECTS = \ + src/systemd_update_utmp-update-utmp.$(OBJEXT) \ + src/systemd_update_utmp-dbus-common.$(OBJEXT) \ + src/systemd_update_utmp-utmp-wtmp.$(OBJEXT) +systemd_update_utmp_OBJECTS = $(am_systemd_update_utmp_OBJECTS) +systemd_update_utmp_DEPENDENCIES = libsystemd-basic.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +systemd_update_utmp_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(systemd_update_utmp_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +am__systemd_user_sessions_SOURCES_DIST = src/login/user-sessions.c \ + src/cgroup-util.c +@ENABLE_LOGIND_TRUE@am_systemd_user_sessions_OBJECTS = \ +@ENABLE_LOGIND_TRUE@ src/login/user-sessions.$(OBJEXT) \ +@ENABLE_LOGIND_TRUE@ src/cgroup-util.$(OBJEXT) +systemd_user_sessions_OBJECTS = $(am_systemd_user_sessions_OBJECTS) +@ENABLE_LOGIND_TRUE@systemd_user_sessions_DEPENDENCIES = \ +@ENABLE_LOGIND_TRUE@ libsystemd-basic.la +am__systemd_vconsole_setup_SOURCES_DIST = \ + src/vconsole/vconsole-setup.c +@ENABLE_VCONSOLE_TRUE@am_systemd_vconsole_setup_OBJECTS = \ +@ENABLE_VCONSOLE_TRUE@ src/vconsole/vconsole-setup.$(OBJEXT) +systemd_vconsole_setup_OBJECTS = $(am_systemd_vconsole_setup_OBJECTS) +@ENABLE_VCONSOLE_TRUE@systemd_vconsole_setup_DEPENDENCIES = \ +@ENABLE_VCONSOLE_TRUE@ libsystemd-basic.la +am_test_cgroup_OBJECTS = src/test-cgroup.$(OBJEXT) \ + src/cgroup-util.$(OBJEXT) +test_cgroup_OBJECTS = $(am_test_cgroup_OBJECTS) +test_cgroup_DEPENDENCIES = libsystemd-basic.la +am_test_daemon_OBJECTS = src/test-daemon.$(OBJEXT) +test_daemon_OBJECTS = $(am_test_daemon_OBJECTS) +test_daemon_DEPENDENCIES = libsystemd-basic.la libsystemd-daemon.la +am_test_engine_OBJECTS = src/test_engine-test-engine.$(OBJEXT) +test_engine_OBJECTS = $(am_test_engine_OBJECTS) +test_engine_DEPENDENCIES = $(systemd_LDADD) +test_engine_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_engine_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am_test_env_replace_OBJECTS = src/test-env-replace.$(OBJEXT) +test_env_replace_OBJECTS = $(am_test_env_replace_OBJECTS) +test_env_replace_DEPENDENCIES = libsystemd-basic.la +am_test_hostname_OBJECTS = src/test-hostname.$(OBJEXT) \ + src/hostname-setup.$(OBJEXT) +test_hostname_OBJECTS = $(am_test_hostname_OBJECTS) +test_hostname_DEPENDENCIES = libsystemd-basic.la +am_test_id128_OBJECTS = src/test-id128.$(OBJEXT) \ + src/sd-id128.$(OBJEXT) +test_id128_OBJECTS = $(am_test_id128_OBJECTS) +test_id128_DEPENDENCIES = libsystemd-basic.la +am_test_install_OBJECTS = src/test_install-test-install.$(OBJEXT) \ + src/test_install-install.$(OBJEXT) \ + src/test_install-path-lookup.$(OBJEXT) \ + src/test_install-unit-name.$(OBJEXT) +test_install_OBJECTS = $(am_test_install_OBJECTS) +test_install_DEPENDENCIES = libsystemd-basic.la +test_install_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_install_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am_test_job_type_OBJECTS = src/test_job_type-test-job-type.$(OBJEXT) +test_job_type_OBJECTS = $(am_test_job_type_OBJECTS) +test_job_type_DEPENDENCIES = $(systemd_LDADD) +test_job_type_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_job_type_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am__test_journal_SOURCES_DIST = src/journal/test-journal.c \ + src/journal/sd-journal.c src/journal/journal-file.c \ + src/journal/lookup3.c src/journal/journal-send.c \ + src/sd-id128.c src/journal/compress.c +@HAVE_XZ_TRUE@am__objects_7 = \ +@HAVE_XZ_TRUE@ src/journal/test_journal-compress.$(OBJEXT) +am_test_journal_OBJECTS = \ + src/journal/test_journal-test-journal.$(OBJEXT) \ + src/journal/test_journal-sd-journal.$(OBJEXT) \ + src/journal/test_journal-journal-file.$(OBJEXT) \ + src/journal/test_journal-lookup3.$(OBJEXT) \ + src/journal/test_journal-journal-send.$(OBJEXT) \ + src/test_journal-sd-id128.$(OBJEXT) $(am__objects_7) +test_journal_OBJECTS = $(am_test_journal_OBJECTS) +test_journal_DEPENDENCIES = libsystemd-basic.la $(am__DEPENDENCIES_2) +test_journal_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_journal_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am__test_login_SOURCES_DIST = src/login/test-login.c +@ENABLE_LOGIND_TRUE@am_test_login_OBJECTS = \ +@ENABLE_LOGIND_TRUE@ src/login/test-login.$(OBJEXT) +test_login_OBJECTS = $(am_test_login_OBJECTS) +@ENABLE_LOGIND_TRUE@test_login_DEPENDENCIES = libsystemd-basic.la \ +@ENABLE_LOGIND_TRUE@ libsystemd-login.la +am_test_loopback_OBJECTS = src/test-loopback.$(OBJEXT) \ + src/loopback-setup.$(OBJEXT) +test_loopback_OBJECTS = $(am_test_loopback_OBJECTS) +test_loopback_DEPENDENCIES = libsystemd-basic.la +am_test_ns_OBJECTS = src/test_ns-test-ns.$(OBJEXT) +test_ns_OBJECTS = $(am_test_ns_OBJECTS) +test_ns_DEPENDENCIES = $(systemd_LDADD) +test_ns_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_ns_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am_test_strv_OBJECTS = src/test-strv.$(OBJEXT) src/specifier.$(OBJEXT) +test_strv_OBJECTS = $(am_test_strv_OBJECTS) +test_strv_DEPENDENCIES = libsystemd-basic.la +SCRIPTS = $(dist_bin_SCRIPTS) +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +VALACOMPILE = $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) +LTVALACOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(VALAC) $(AM_VALAFLAGS) \ + $(VALAFLAGS) +AM_V_VALAC = $(am__v_VALAC_@AM_V@) +am__v_VALAC_ = $(am__v_VALAC_@AM_DEFAULT_V@) +am__v_VALAC_0 = @echo " VALAC " $@; +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libsystemd_basic_la_SOURCES) $(libsystemd_core_la_SOURCES) \ + $(nodist_libsystemd_core_la_SOURCES) \ + $(libsystemd_daemon_la_SOURCES) $(libsystemd_id128_la_SOURCES) \ + $(libsystemd_journal_la_SOURCES) \ + $(libsystemd_login_la_SOURCES) $(pam_systemd_la_SOURCES) \ + $(systemadm_SOURCES) $(systemctl_SOURCES) $(systemd_SOURCES) \ + $(systemd_ac_power_SOURCES) $(systemd_ask_password_SOURCES) \ + $(systemd_binfmt_SOURCES) $(systemd_cat_SOURCES) \ + $(systemd_cgls_SOURCES) $(systemd_cgroups_agent_SOURCES) \ + $(systemd_cgtop_SOURCES) $(systemd_coredump_SOURCES) \ + $(systemd_cryptsetup_SOURCES) \ + $(systemd_cryptsetup_generator_SOURCES) \ + $(systemd_detect_virt_SOURCES) $(systemd_fsck_SOURCES) \ + $(systemd_getty_generator_SOURCES) \ + $(systemd_gnome_ask_password_agent_SOURCES) \ + $(systemd_hostnamed_SOURCES) $(systemd_initctl_SOURCES) \ + $(systemd_journalctl_SOURCES) $(systemd_journald_SOURCES) \ + $(nodist_systemd_journald_SOURCES) $(systemd_localed_SOURCES) \ + $(systemd_loginctl_SOURCES) $(systemd_logind_SOURCES) \ + $(nodist_systemd_logind_SOURCES) \ + $(systemd_machine_id_setup_SOURCES) \ + $(systemd_modules_load_SOURCES) \ + $(systemd_multi_seat_x_SOURCES) $(systemd_notify_SOURCES) \ + $(systemd_nspawn_SOURCES) $(systemd_quotacheck_SOURCES) \ + $(systemd_random_seed_SOURCES) \ + $(systemd_rc_local_generator_SOURCES) \ + $(systemd_readahead_collect_SOURCES) \ + $(systemd_readahead_replay_SOURCES) \ + $(systemd_remount_api_vfs_SOURCES) \ + $(systemd_reply_password_SOURCES) $(systemd_shutdown_SOURCES) \ + $(systemd_shutdownd_SOURCES) $(systemd_stdio_bridge_SOURCES) \ + $(systemd_sysctl_SOURCES) $(systemd_timedated_SOURCES) \ + $(systemd_timestamp_SOURCES) $(systemd_tmpfiles_SOURCES) \ + $(systemd_tty_ask_password_agent_SOURCES) \ + $(systemd_uaccess_SOURCES) $(systemd_update_utmp_SOURCES) \ + $(systemd_user_sessions_SOURCES) \ + $(systemd_vconsole_setup_SOURCES) $(test_cgroup_SOURCES) \ + $(test_daemon_SOURCES) $(test_engine_SOURCES) \ + $(test_env_replace_SOURCES) $(test_hostname_SOURCES) \ + $(test_id128_SOURCES) $(test_install_SOURCES) \ + $(test_job_type_SOURCES) $(test_journal_SOURCES) \ + $(test_login_SOURCES) $(test_loopback_SOURCES) \ + $(test_ns_SOURCES) $(test_strv_SOURCES) +DIST_SOURCES = $(libsystemd_basic_la_SOURCES) \ + $(libsystemd_core_la_SOURCES) $(libsystemd_daemon_la_SOURCES) \ + $(libsystemd_id128_la_SOURCES) \ + $(am__libsystemd_journal_la_SOURCES_DIST) \ + $(am__libsystemd_login_la_SOURCES_DIST) \ + $(am__pam_systemd_la_SOURCES_DIST) $(systemadm_SOURCES) \ + $(systemctl_SOURCES) $(systemd_SOURCES) \ + $(systemd_ac_power_SOURCES) $(systemd_ask_password_SOURCES) \ + $(am__systemd_binfmt_SOURCES_DIST) $(systemd_cat_SOURCES) \ + $(systemd_cgls_SOURCES) $(systemd_cgroups_agent_SOURCES) \ + $(systemd_cgtop_SOURCES) $(am__systemd_coredump_SOURCES_DIST) \ + $(am__systemd_cryptsetup_SOURCES_DIST) \ + $(am__systemd_cryptsetup_generator_SOURCES_DIST) \ + $(systemd_detect_virt_SOURCES) $(systemd_fsck_SOURCES) \ + $(systemd_getty_generator_SOURCES) \ + $(systemd_gnome_ask_password_agent_SOURCES) \ + $(am__systemd_hostnamed_SOURCES_DIST) \ + $(systemd_initctl_SOURCES) \ + $(am__systemd_journalctl_SOURCES_DIST) \ + $(am__systemd_journald_SOURCES_DIST) \ + $(am__systemd_localed_SOURCES_DIST) \ + $(am__systemd_loginctl_SOURCES_DIST) \ + $(am__systemd_logind_SOURCES_DIST) \ + $(systemd_machine_id_setup_SOURCES) \ + $(systemd_modules_load_SOURCES) \ + $(am__systemd_multi_seat_x_SOURCES_DIST) \ + $(systemd_notify_SOURCES) $(systemd_nspawn_SOURCES) \ + $(am__systemd_quotacheck_SOURCES_DIST) \ + $(am__systemd_random_seed_SOURCES_DIST) \ + $(systemd_rc_local_generator_SOURCES) \ + $(am__systemd_readahead_collect_SOURCES_DIST) \ + $(am__systemd_readahead_replay_SOURCES_DIST) \ + $(systemd_remount_api_vfs_SOURCES) \ + $(systemd_reply_password_SOURCES) $(systemd_shutdown_SOURCES) \ + $(systemd_shutdownd_SOURCES) $(systemd_stdio_bridge_SOURCES) \ + $(systemd_sysctl_SOURCES) \ + $(am__systemd_timedated_SOURCES_DIST) \ + $(systemd_timestamp_SOURCES) $(systemd_tmpfiles_SOURCES) \ + $(systemd_tty_ask_password_agent_SOURCES) \ + $(am__systemd_uaccess_SOURCES_DIST) \ + $(systemd_update_utmp_SOURCES) \ + $(am__systemd_user_sessions_SOURCES_DIST) \ + $(am__systemd_vconsole_setup_SOURCES_DIST) \ + $(test_cgroup_SOURCES) $(test_daemon_SOURCES) \ + $(test_engine_SOURCES) $(test_env_replace_SOURCES) \ + $(test_hostname_SOURCES) $(test_id128_SOURCES) \ + $(test_install_SOURCES) $(test_job_type_SOURCES) \ + $(am__test_journal_SOURCES_DIST) \ + $(am__test_login_SOURCES_DIST) $(test_loopback_SOURCES) \ + $(test_ns_SOURCES) $(test_strv_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +man1dir = $(mandir)/man1 +man3dir = $(mandir)/man3 +man5dir = $(mandir)/man5 +man7dir = $(mandir)/man7 +man8dir = $(mandir)/man8 +NROFF = nroff +MANS = $(dist_man_MANS) $(nodist_man_MANS) +am__dist_dbuspolicy_DATA_DIST = src/org.freedesktop.systemd1.conf \ + src/hostname/org.freedesktop.hostname1.conf \ + src/locale/org.freedesktop.locale1.conf \ + src/timedate/org.freedesktop.timedate1.conf \ + src/login/org.freedesktop.login1.conf +am__dist_dbussystemservice_DATA_DIST = \ + src/org.freedesktop.systemd1.service \ + src/hostname/org.freedesktop.hostname1.service \ + src/locale/org.freedesktop.locale1.service \ + src/timedate/org.freedesktop.timedate1.service \ + src/login/org.freedesktop.login1.service +am__dist_noinst_DATA_DIST = ${patsubst %.1,%.xml,${patsubst \ + %.3,%.xml,${patsubst %.5,%.xml,${patsubst %.7,%.xml,${patsubst \ + %.8,%.xml,$(MANPAGES)}}}}} +am__dist_pkgdata_DATA_DIST = src/locale/kbd-model-map +am__dist_pkgsysconf_DATA_DIST = src/system.conf src/user.conf \ + src/journal/systemd-journald.conf \ + src/login/systemd-logind.conf +am__dist_systemunit_DATA_DIST = units/graphical.target \ + units/multi-user.target units/emergency.service \ + units/emergency.target units/sysinit.target units/basic.target \ + units/getty.target units/halt.target units/kexec.target \ + units/local-fs.target units/local-fs-pre.target \ + units/remote-fs.target units/remote-fs-pre.target \ + units/network.target units/nss-lookup.target \ + units/mail-transfer-agent.target units/http-daemon.target \ + units/poweroff.target units/reboot.target units/rescue.target \ + units/rpcbind.target units/time-sync.target \ + units/shutdown.target units/final.target units/umount.target \ + units/sigpwr.target units/sockets.target units/swap.target \ + units/systemd-initctl.socket units/systemd-shutdownd.socket \ + units/syslog.socket units/dev-hugepages.mount \ + units/dev-mqueue.mount units/sys-kernel-config.mount \ + units/sys-kernel-debug.mount units/sys-kernel-security.mount \ + units/sys-fs-fuse-connections.mount units/var-run.mount \ + units/media.mount units/remount-rootfs.service \ + units/printer.target units/sound.target units/bluetooth.target \ + units/smartcard.target units/systemd-tmpfiles-clean.timer \ + units/quotaon.service units/systemd-ask-password-wall.path \ + units/systemd-ask-password-console.path units/syslog.target \ + units/var-lock.mount units/fedora/prefdm.service \ + units/fedora/rc-local.service units/fedora/halt-local.service \ + units/mandriva/prefdm.service \ + units/frugalware/display-manager.service \ + units/suse/rc-local.service units/suse/halt-local.service \ + units/mageia/prefdm.service units/plymouth-start.service \ + units/plymouth-read-write.service units/plymouth-quit.service \ + units/plymouth-quit-wait.service units/plymouth-reboot.service \ + units/plymouth-kexec.service units/plymouth-poweroff.service \ + units/plymouth-halt.service \ + units/systemd-ask-password-plymouth.path \ + units/systemd-journald.socket \ + units/proc-sys-fs-binfmt_misc.automount \ + units/proc-sys-fs-binfmt_misc.mount \ + units/systemd-readahead-done.timer units/cryptsetup.target +am__dist_tmpfiles_DATA_DIST = tmpfiles.d/systemd.conf \ + tmpfiles.d/tmp.conf tmpfiles.d/x11.conf tmpfiles.d/legacy.conf +am__dist_udevrules_DATA_DIST = src/login/70-uaccess.rules \ + src/login/71-seat.rules +DATA = $(dbusinterface_DATA) $(dist_bashcompletion_DATA) \ + $(dist_dbuspolicy_DATA) $(dist_dbussystemservice_DATA) \ + $(dist_doc_DATA) $(dist_noinst_DATA) $(dist_pkgdata_DATA) \ + $(dist_pkgsysconf_DATA) $(dist_systemunit_DATA) \ + $(dist_tmpfiles_DATA) $(dist_udevrules_DATA) \ + $(dist_userunit_DATA) $(nodist_noinst_DATA) \ + $(nodist_polkitpolicy_DATA) $(nodist_systemunit_DATA) \ + $(nodist_udevrules_DATA) $(nodist_userunit_DATA) \ + $(pkgconfigdata_DATA) $(pkgconfiglib_DATA) $(sysctl_DATA) +am__pkginclude_HEADERS_DIST = src/systemd/sd-daemon.h \ + src/systemd/sd-id128.h src/systemd/sd-journal.h \ + src/systemd/sd-messages.h src/systemd/sd-login.h +HEADERS = $(pkginclude_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +GZIP_ENV = --best +DIST_ARCHIVES = $(distdir).tar.xz +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +pkgincludedir = $(includedir)/systemd +ACLOCAL = @ACLOCAL@ +ACL_LIBS = @ACL_LIBS@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUDIT_LIBS = @AUDIT_LIBS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CAP_LIBS = @CAP_LIBS@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GMSGFMT = @GMSGFMT@ +GPERF = @GPERF@ +GREP = @GREP@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +KMOD_CFLAGS = @KMOD_CFLAGS@ +KMOD_LIBS = @KMOD_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCRYPTSETUP_CFLAGS = @LIBCRYPTSETUP_CFLAGS@ +LIBCRYPTSETUP_LIBS = @LIBCRYPTSETUP_LIBS@ +LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ +LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBWRAP_LIBS = @LIBWRAP_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +M4 = @M4@ +M4_DEFINES = @M4_DEFINES@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJCOPY = @OBJCOPY@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PAM_LIBS = @PAM_LIBS@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRINGS = @STRINGS@ +STRIP = @STRIP@ +SYSTEM_SYSVINIT_PATH = @SYSTEM_SYSVINIT_PATH@ +SYSTEM_SYSVRCND_PATH = @SYSTEM_SYSVRCND_PATH@ +UDEV_CFLAGS = @UDEV_CFLAGS@ +UDEV_LIBS = @UDEV_LIBS@ +USE_NLS = @USE_NLS@ +VALAC = @VALAC@ +VAPIDIR = @VAPIDIR@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XSLTPROC = @XSLTPROC@ +XZ_CFLAGS = @XZ_CFLAGS@ +XZ_LIBS = @XZ_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusinterfacedir = @dbusinterfacedir@ + +# Dirs of external packages +dbuspolicydir = @dbuspolicydir@ +dbussessionservicedir = @dbussessionservicedir@ +dbussystemservicedir = @dbussystemservicedir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pamlibdir = @pamlibdir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +rootlibdir = @rootlibdir@ + +# And these are the special ones for / +rootprefix = @rootprefix@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +udevrulesdir = @udevrulesdir@ +ACLOCAL_AMFLAGS = -I m4 +SUBDIRS = po +LIBSYSTEMD_LOGIN_CURRENT = 2 +LIBSYSTEMD_LOGIN_REVISION = 0 +LIBSYSTEMD_LOGIN_AGE = 2 +LIBSYSTEMD_DAEMON_CURRENT = 0 +LIBSYSTEMD_DAEMON_REVISION = 1 +LIBSYSTEMD_DAEMON_AGE = 0 +LIBSYSTEMD_ID128_CURRENT = 0 +LIBSYSTEMD_ID128_REVISION = 2 +LIBSYSTEMD_ID128_AGE = 0 +LIBSYSTEMD_JOURNAL_CURRENT = 0 +LIBSYSTEMD_JOURNAL_REVISION = 2 +LIBSYSTEMD_JOURNAL_AGE = 0 +pkgconfigdatadir = $(datadir)/pkgconfig +pkgconfiglibdir = $(libdir)/pkgconfig +polkitpolicydir = $(datadir)/polkit-1/actions +bashcompletiondir = $(sysconfdir)/bash_completion.d + +# Our own, non-special dirs +pkgsysconfdir = $(sysconfdir)/systemd +userunitdir = $(prefix)/lib/systemd/user +tmpfilesdir = $(prefix)/lib/tmpfiles.d +sysctldir = $(prefix)/lib/sysctl.d +usergeneratordir = $(pkglibexecdir)/user-generators +rootbindir = $(rootprefix)/bin +rootlibexecdir = $(rootprefix)/lib/systemd +systemgeneratordir = $(rootlibexecdir)/system-generators +systemshutdowndir = $(rootlibexecdir)/system-shutdown +systemunitdir = $(rootprefix)/lib/systemd/system +CLEANFILES = src/journal/journald-gperf.c $(am__append_38) \ + $(am__append_111) $(nodist_systemunit_DATA) \ + $(nodist_userunit_DATA) $(nodist_man_MANS) \ + ${XML_IN_FILES:.xml.in=.html} $(pkgconfigdata_DATA) \ + $(pkgconfiglib_DATA) $(nodist_polkitpolicy_DATA) \ + src/load-fragment-gperf.gperf src/load-fragment-gperf.c \ + src/load-fragment-gperf-nulstr.c src/99-systemd.rules \ + $(am__append_112) $(am__append_113) $(dbusinterface_DATA) + +# This is needed because automake is buggy in how it generates the +# rules for C programs, but not Vala programs. We therefore can't +# list the .h files as dependencies if we want make dist to work. +EXTRA_DIST = units/getty@.service.m4 units/serial-getty@.service.m4 \ + units/console-shell.service.m4 units/rescue.service.m4 \ + units/systemd-initctl.service.in \ + units/systemd-shutdownd.service.in \ + units/systemd-modules-load.service.in \ + units/systemd-remount-api-vfs.service.in \ + units/systemd-update-utmp-runlevel.service.in \ + units/systemd-update-utmp-shutdown.service.in \ + units/systemd-tmpfiles-setup.service.in \ + units/systemd-tmpfiles-clean.service.in \ + units/systemd-ask-password-wall.service.in \ + units/systemd-ask-password-console.service.in \ + units/systemd-sysctl.service.in units/halt.service.in \ + units/poweroff.service.in units/reboot.service.in \ + units/kexec.service.in units/user/exit.service.in \ + units/fsck@.service.in units/fsck-root.service.in \ + units/user@.service.in src/systemd.pc.in introspect.awk \ + src/99-systemd.rules.in man/custom-html.xsl $(am__append_23) \ + $(polkitpolicy_in_files) $(polkitpolicy_in_in_files) \ + src/load-fragment-gperf.gperf.m4 src/util.h src/virt.h \ + src/label.h src/hashmap.h src/set.h src/strv.h \ + src/conf-parser.h src/socket-util.h src/log.h src/ratelimit.h \ + src/exit-status.h src/unit.h src/job.h src/manager.h \ + src/path-lookup.h src/load-fragment.h src/service.h \ + src/automount.h src/mount.h src/swap.h src/device.h \ + src/target.h src/snapshot.h src/socket.h src/timer.h \ + src/path.h src/load-dropin.h src/execute.h src/utmp-wtmp.h \ + src/dbus.h src/dbus-manager.h src/dbus-unit.h src/dbus-job.h \ + src/dbus-service.h src/dbus-socket.h src/dbus-timer.h \ + src/dbus-target.h src/dbus-mount.h src/dbus-automount.h \ + src/dbus-swap.h src/dbus-snapshot.h src/dbus-device.h \ + src/dbus-execute.h src/dbus-path.h src/cgroup.h \ + src/mount-setup.h src/hostname-setup.h src/selinux-setup.h \ + src/loopback-setup.h src/kmod-setup.h src/locale-setup.h \ + src/machine-id-setup.h src/specifier.h src/unit-name.h \ + src/fdset.h src/namespace.h src/tcpwrap.h src/cgroup-util.h \ + src/condition.h src/dbus-common.h src/install.h \ + src/cgroup-attr.h src/macro.h src/def.h src/ioprio.h \ + src/missing.h src/list.h src/securebits.h \ + src/linux/auto_dev-ioctl.h src/linux/fanotify.h src/initreq.h \ + src/special.h src/dbus-common.h src/bus-errors.h \ + src/cgroup-show.h src/build.h src/shutdownd.h src/umount.h \ + src/ask-password-api.h src/pager.h src/sysfs-show.h \ + src/polkit.h src/dbus-loop.h src/spawn-agent.h src/acl-util.h \ + src/logs-show.h $(am__append_24) src/libsystemd-daemon.pc.in \ + src/libsystemd-daemon.sym src/libsystemd-id128.pc.in \ + src/libsystemd-id128.sym src/journal/journald.h \ + src/journal/journal-def.h src/journal/journal-internal.h \ + src/journal/journal-file.h src/journal/lookup3.h \ + src/journal/compress.h src/journal/journal-rate-limit.h \ + src/journal/libsystemd-journal.pc.in \ + src/journal/libsystemd-journal.sym \ + units/systemd-journald.service.in \ + src/journal/journald-gperf.gperf $(am__append_37) \ + $(am__append_44) $(am__append_49) $(am__append_53) \ + $(am__append_57) $(am__append_60) $(am__append_73) \ + $(am__append_81) $(am__append_89) $(am__append_110) +INSTALL_EXEC_HOOKS = libsystemd-daemon-install-hook \ + libsystemd-id128-install-hook libsystemd-journal-install-hook \ + $(am__append_94) +UNINSTALL_EXEC_HOOKS = libsystemd-daemon-uninstall-hook \ + libsystemd-id128-uninstall-hook \ + libsystemd-journal-uninstall-hook $(am__append_95) +INSTALL_DATA_HOOKS = journal-install-data-hook $(am__append_42) \ + $(am__append_47) $(am__append_61) $(am__append_65) \ + $(am__append_72) $(am__append_80) $(am__append_88) \ + $(am__append_104) +pkginclude_HEADERS = src/systemd/sd-daemon.h src/systemd/sd-id128.h \ + src/systemd/sd-journal.h src/systemd/sd-messages.h \ + $(am__append_100) +lib_LTLIBRARIES = libsystemd-daemon.la libsystemd-id128.la \ + libsystemd-journal.la $(am__append_101) +pkgconfiglib_DATA = src/libsystemd-daemon.pc src/libsystemd-id128.pc \ + src/journal/libsystemd-journal.pc $(am__append_102) +polkitpolicy_in_files = $(am__append_70) $(am__append_78) \ + $(am__append_86) $(am__append_103) +dist_udevrules_DATA = $(am__append_106) +AM_CPPFLAGS = -include $(top_builddir)/config.h \ + -DSYSTEM_CONFIG_FILE=\"$(pkgsysconfdir)/system.conf\" \ + -DSYSTEM_CONFIG_UNIT_PATH=\"$(pkgsysconfdir)/system\" \ + -DSYSTEM_DATA_UNIT_PATH=\"$(systemunitdir)\" \ + -DSYSTEM_SYSVINIT_PATH=\"$(SYSTEM_SYSVINIT_PATH)\" \ + -DSYSTEM_SYSVRCND_PATH=\"$(SYSTEM_SYSVRCND_PATH)\" \ + -DUSER_CONFIG_FILE=\"$(pkgsysconfdir)/user.conf\" \ + -DUSER_CONFIG_UNIT_PATH=\"$(pkgsysconfdir)/user\" \ + -DUSER_DATA_UNIT_PATH=\"$(userunitdir)\" \ + -DSYSTEMD_CGROUP_AGENT_PATH=\"$(rootlibexecdir)/systemd-cgroups-agent\" \ + -DSYSTEMD_BINARY_PATH=\"$(rootlibexecdir)/systemd\" \ + -DSYSTEMD_SHUTDOWN_BINARY_PATH=\"$(rootlibexecdir)/systemd-shutdown\" \ + -DSYSTEMCTL_BINARY_PATH=\"$(rootbindir)/systemctl\" \ + -DSYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH=\"$(rootbindir)/systemd-tty-ask-password-agent\" \ + -DSYSTEMD_STDIO_BRIDGE_BINARY_PATH=\"$(bindir)/systemd-stdio-bridge\" \ + -DROOTPREFIX=\"$(rootprefix)\" -DRUNTIME_DIR=\"/run\" \ + -DRANDOM_SEED=\"$(localstatedir)/lib/random-seed\" \ + -DSYSTEMD_CRYPTSETUP_PATH=\"$(rootlibexecdir)/systemd-cryptsetup\" \ + -DSYSTEM_GENERATOR_PATH=\"$(systemgeneratordir)\" \ + -DUSER_GENERATOR_PATH=\"$(usergeneratordir)\" \ + -DSYSTEM_SHUTDOWN_PATH=\"$(systemshutdowndir)\" \ + -DSYSTEMD_KBD_MODEL_MAP=\"$(pkgdatadir)/kbd-model-map\" \ + -DX_SERVER=\"$(bindir)/X\" -I $(top_srcdir)/src -I \ + $(top_srcdir)/src/readahead -I $(top_srcdir)/src/login -I \ + $(top_srcdir)/src/journal -I $(top_srcdir)/src/systemd \ + $(am__append_1) $(am__append_2) $(am__append_3) \ + $(am__append_4) $(am__append_5) $(am__append_6) \ + $(am__append_7) $(am__append_8) +dist_bin_SCRIPTS = \ + src/systemd-analyze + +dist_pkgsysconf_DATA = src/system.conf src/user.conf \ + src/journal/systemd-journald.conf $(am__append_99) +dist_dbuspolicy_DATA = src/org.freedesktop.systemd1.conf \ + $(am__append_68) $(am__append_76) $(am__append_84) \ + $(am__append_98) +dist_dbussystemservice_DATA = src/org.freedesktop.systemd1.service \ + $(am__append_69) $(am__append_77) $(am__append_83) \ + $(am__append_97) +nodist_udevrules_DATA = src/99-systemd.rules $(am__append_107) +dbusinterface_DATA = org.freedesktop.systemd1.Manager.xml \ + org.freedesktop.systemd1.Job.xml \ + org.freedesktop.systemd1.Unit.xml \ + org.freedesktop.systemd1.Service.xml \ + org.freedesktop.systemd1.Socket.xml \ + org.freedesktop.systemd1.Timer.xml \ + org.freedesktop.systemd1.Target.xml \ + org.freedesktop.systemd1.Device.xml \ + org.freedesktop.systemd1.Mount.xml \ + org.freedesktop.systemd1.Automount.xml \ + org.freedesktop.systemd1.Snapshot.xml \ + org.freedesktop.systemd1.Swap.xml \ + org.freedesktop.systemd1.Path.xml $(am__append_71) \ + $(am__append_79) $(am__append_87) +dist_bashcompletion_DATA = \ + src/systemd-bash-completion.sh + +dist_tmpfiles_DATA = tmpfiles.d/systemd.conf tmpfiles.d/tmp.conf \ + tmpfiles.d/x11.conf $(am__append_10) +dist_systemunit_DATA = units/graphical.target units/multi-user.target \ + units/emergency.service units/emergency.target \ + units/sysinit.target units/basic.target units/getty.target \ + units/halt.target units/kexec.target units/local-fs.target \ + units/local-fs-pre.target units/remote-fs.target \ + units/remote-fs-pre.target units/network.target \ + units/nss-lookup.target units/mail-transfer-agent.target \ + units/http-daemon.target units/poweroff.target \ + units/reboot.target units/rescue.target units/rpcbind.target \ + units/time-sync.target units/shutdown.target \ + units/final.target units/umount.target units/sigpwr.target \ + units/sockets.target units/swap.target \ + units/systemd-initctl.socket units/systemd-shutdownd.socket \ + units/syslog.socket units/dev-hugepages.mount \ + units/dev-mqueue.mount units/sys-kernel-config.mount \ + units/sys-kernel-debug.mount units/sys-kernel-security.mount \ + units/sys-fs-fuse-connections.mount units/var-run.mount \ + units/media.mount units/remount-rootfs.service \ + units/printer.target units/sound.target units/bluetooth.target \ + units/smartcard.target units/systemd-tmpfiles-clean.timer \ + units/quotaon.service units/systemd-ask-password-wall.path \ + units/systemd-ask-password-console.path units/syslog.target \ + $(am__append_11) $(am__append_12) $(am__append_14) \ + $(am__append_16) $(am__append_17) $(am__append_19) \ + $(am__append_21) units/systemd-journald.socket \ + $(am__append_40) $(am__append_51) $(am__append_64) +nodist_systemunit_DATA = units/getty@.service \ + units/serial-getty@.service units/console-shell.service \ + units/systemd-initctl.service units/systemd-shutdownd.service \ + units/systemd-modules-load.service \ + units/systemd-remount-api-vfs.service \ + units/systemd-update-utmp-runlevel.service \ + units/systemd-update-utmp-shutdown.service \ + units/systemd-tmpfiles-setup.service \ + units/systemd-tmpfiles-clean.service \ + units/systemd-ask-password-wall.service \ + units/systemd-ask-password-console.service \ + units/systemd-sysctl.service units/halt.service \ + units/poweroff.service units/reboot.service \ + units/kexec.service units/fsck@.service \ + units/fsck-root.service units/rescue.service \ + units/user@.service $(am__append_22) \ + units/systemd-journald.service $(am__append_41) \ + $(am__append_46) $(am__append_52) $(am__append_56) \ + $(am__append_59) $(am__append_67) $(am__append_74) \ + $(am__append_85) $(am__append_96) +dist_userunit_DATA = \ + units/user/default.target \ + units/user/exit.target + +nodist_userunit_DATA = \ + units/user/exit.service + +dist_doc_DATA = \ + README \ + NEWS \ + LICENSE \ + DISTRO_PORTING + +pkgconfigdata_DATA = \ + src/systemd.pc + + +# First passed through sed, followed by intltool +polkitpolicy_in_in_files = \ + src/org.freedesktop.systemd1.policy.in.in + +nodist_polkitpolicy_DATA = \ + $(polkitpolicy_in_files:.policy.in=.policy) \ + $(polkitpolicy_in_in_files:.policy.in.in=.policy) + +noinst_LTLIBRARIES = \ + libsystemd-basic.la \ + libsystemd-core.la + +libsystemd_basic_la_SOURCES = \ + src/util.c \ + src/virt.c \ + src/label.c \ + src/hashmap.c \ + src/set.c \ + src/strv.c \ + src/conf-parser.c \ + src/socket-util.c \ + src/log.c \ + src/ratelimit.c \ + src/exit-status.c + +libsystemd_basic_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(SELINUX_CFLAGS) + +libsystemd_basic_la_LIBADD = \ + $(SELINUX_LIBS) \ + $(CAP_LIBS) + +libsystemd_core_la_SOURCES = \ + src/unit.c \ + src/job.c \ + src/manager.c \ + src/path-lookup.c \ + src/load-fragment.c \ + src/service.c \ + src/automount.c \ + src/mount.c \ + src/swap.c \ + src/device.c \ + src/target.c \ + src/snapshot.c \ + src/socket.c \ + src/timer.c \ + src/path.c \ + src/load-dropin.c \ + src/execute.c \ + src/utmp-wtmp.c \ + src/dbus.c \ + src/dbus-manager.c \ + src/dbus-unit.c \ + src/dbus-job.c \ + src/dbus-service.c \ + src/dbus-socket.c \ + src/dbus-timer.c \ + src/dbus-target.c \ + src/dbus-mount.c \ + src/dbus-automount.c \ + src/dbus-swap.c \ + src/dbus-snapshot.c \ + src/dbus-device.c \ + src/dbus-execute.c \ + src/dbus-path.c \ + src/cgroup.c \ + src/mount-setup.c \ + src/hostname-setup.c \ + src/selinux-setup.c \ + src/loopback-setup.c \ + src/kmod-setup.c \ + src/locale-setup.c \ + src/machine-id-setup.c \ + src/specifier.c \ + src/unit-name.c \ + src/fdset.c \ + src/namespace.c \ + src/tcpwrap.c \ + src/cgroup-util.c \ + src/condition.c \ + src/dbus-common.c \ + src/sd-daemon.c \ + src/install.c \ + src/cgroup-attr.c \ + src/sd-id128.c + +nodist_libsystemd_core_la_SOURCES = \ + src/load-fragment-gperf.c \ + src/load-fragment-gperf-nulstr.c + +libsystemd_core_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(UDEV_CFLAGS) \ + $(LIBWRAP_CFLAGS) \ + $(PAM_CFLAGS) \ + $(AUDIT_CFLAGS) \ + $(KMOD_CFLAGS) + +libsystemd_core_la_LIBADD = \ + libsystemd-basic.la \ + $(DBUS_LIBS) \ + $(UDEV_LIBS) \ + $(LIBWRAP_LIBS) \ + $(PAM_LIBS) \ + $(AUDIT_LIBS) \ + $(CAP_LIBS) \ + $(KMOD_LIBS) + +MANPAGES = man/systemd.1 man/systemctl.1 man/systemadm.1 \ + man/systemd-cgls.1 man/systemd-cgtop.1 man/systemd-nspawn.1 \ + man/systemd-tmpfiles.8 man/systemd-notify.1 man/systemd.unit.5 \ + man/systemd.service.5 man/systemd.socket.5 man/systemd.mount.5 \ + man/systemd.automount.5 man/systemd.swap.5 man/systemd.timer.5 \ + man/systemd.path.5 man/systemd.target.5 man/systemd.device.5 \ + man/systemd.snapshot.5 man/systemd.exec.5 man/daemon.7 \ + man/runlevel.8 man/telinit.8 man/halt.8 man/shutdown.8 \ + man/pam_systemd.8 man/systemd.conf.5 man/tmpfiles.d.5 \ + man/hostname.5 man/timezone.5 man/machine-id.5 \ + man/locale.conf.5 man/os-release.5 man/machine-info.5 \ + man/modules-load.d.5 man/sysctl.d.5 man/systemd-ask-password.1 \ + man/sd-daemon.7 man/sd_notify.3 man/sd_listen_fds.3 \ + man/sd_is_fifo.3 man/sd_booted.3 $(am__append_43) \ + $(am__append_48) $(am__append_54) $(am__append_108) +MANPAGES_ALIAS = man/reboot.8 man/poweroff.8 man/init.1 \ + man/sd_is_socket.3 man/sd_is_socket_unix.3 \ + man/sd_is_socket_inet.3 man/sd_is_mq.3 man/sd_notifyf.3 \ + $(am__append_109) +@ENABLE_MANPAGES_TRUE@dist_man_MANS = \ +@ENABLE_MANPAGES_TRUE@ $(MANPAGES) \ +@ENABLE_MANPAGES_TRUE@ $(MANPAGES_ALIAS) + +@ENABLE_MANPAGES_TRUE@nodist_man_MANS = \ +@ENABLE_MANPAGES_TRUE@ man/systemd.special.7 + +@ENABLE_MANPAGES_TRUE@XML_FILES = \ +@ENABLE_MANPAGES_TRUE@ ${patsubst %.1,%.xml,${patsubst %.3,%.xml,${patsubst %.5,%.xml,${patsubst %.7,%.xml,${patsubst %.8,%.xml,$(MANPAGES)}}}}} + +@ENABLE_MANPAGES_TRUE@XML_IN_FILES = \ +@ENABLE_MANPAGES_TRUE@ ${patsubst %.1,%.xml.in,${patsubst %.3,%.xml.in,${patsubst %.5,%.xml.in,${patsubst %.7,%.xml.in,${patsubst %.8,%.xml.in,$(nodist_man_MANS)}}}}} + +@ENABLE_MANPAGES_TRUE@dist_noinst_DATA = \ +@ENABLE_MANPAGES_TRUE@ ${XML_FILES:.xml=.html} + +@ENABLE_MANPAGES_TRUE@nodist_noinst_DATA = \ +@ENABLE_MANPAGES_TRUE@ ${XML_IN_FILES:.xml.in=.html} + +systemd_SOURCES = \ + src/main.c + +systemd_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(UDEV_CFLAGS) + +systemd_LDADD = \ + libsystemd-core.la + +test_engine_SOURCES = \ + src/test-engine.c + +test_engine_CFLAGS = $(systemd_CFLAGS) +test_engine_LDADD = $(systemd_LDADD) +test_job_type_SOURCES = \ + src/test-job-type.c + +test_job_type_CFLAGS = $(systemd_CFLAGS) +test_job_type_LDADD = $(systemd_LDADD) +test_ns_SOURCES = \ + src/test-ns.c + +test_ns_CFLAGS = $(systemd_CFLAGS) +test_ns_LDADD = $(systemd_LDADD) +test_loopback_SOURCES = \ + src/test-loopback.c \ + src/loopback-setup.c + +test_loopback_LDADD = \ + libsystemd-basic.la + +test_hostname_SOURCES = \ + src/test-hostname.c \ + src/hostname-setup.c + +test_hostname_LDADD = \ + libsystemd-basic.la + +test_daemon_SOURCES = \ + src/test-daemon.c + +test_daemon_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la + +test_cgroup_SOURCES = \ + src/test-cgroup.c \ + src/cgroup-util.c + +test_cgroup_LDADD = \ + libsystemd-basic.la + +test_env_replace_SOURCES = \ + src/test-env-replace.c + +test_env_replace_LDADD = \ + libsystemd-basic.la + +test_strv_SOURCES = \ + src/test-strv.c \ + src/specifier.c + +test_strv_LDADD = \ + libsystemd-basic.la + +test_install_SOURCES = \ + src/test-install.c \ + src/install.c \ + src/path-lookup.c \ + src/unit-name.c + +test_install_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +test_install_LDADD = \ + libsystemd-basic.la + +systemd_initctl_SOURCES = \ + src/initctl.c \ + src/dbus-common.c + +systemd_initctl_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_initctl_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la \ + $(DBUS_LIBS) + +systemd_update_utmp_SOURCES = \ + src/update-utmp.c \ + src/dbus-common.c \ + src/utmp-wtmp.c + +systemd_update_utmp_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(AUDIT_CFLAGS) + +systemd_update_utmp_LDADD = \ + libsystemd-basic.la \ + $(DBUS_LIBS) \ + $(AUDIT_LIBS) + +systemd_shutdownd_SOURCES = \ + src/utmp-wtmp.c \ + src/shutdownd.c + +systemd_shutdownd_CFLAGS = \ + $(AM_CFLAGS) + +systemd_shutdownd_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la + +systemd_shutdown_SOURCES = \ + src/mount-setup.c \ + src/umount.c \ + src/shutdown.c + +systemd_shutdown_CFLAGS = \ + $(AM_CFLAGS) \ + $(UDEV_CFLAGS) + +systemd_shutdown_LDADD = \ + libsystemd-basic.la \ + $(UDEV_LIBS) + +systemd_modules_load_SOURCES = \ + src/modules-load.c + +systemd_modules_load_CFLAGS = \ + $(KMOD_CFLAGS) + +systemd_modules_load_LDADD = \ + libsystemd-basic.la \ + $(KMOD_LIBS) + +systemd_tmpfiles_SOURCES = \ + src/tmpfiles.c + +systemd_tmpfiles_LDADD = \ + libsystemd-basic.la + +systemd_machine_id_setup_SOURCES = \ + src/machine-id-setup.c \ + src/machine-id-main.c \ + src/sd-id128.c + +systemd_machine_id_setup_LDADD = \ + libsystemd-basic.la + +systemd_sysctl_SOURCES = \ + src/sysctl.c + +systemd_sysctl_LDADD = \ + libsystemd-basic.la + +systemd_fsck_SOURCES = \ + src/fsck.c \ + src/dbus-common.c + +systemd_fsck_CFLAGS = \ + $(AM_CFLAGS) \ + $(UDEV_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_fsck_LDADD = \ + libsystemd-basic.la \ + $(UDEV_LIBS) \ + $(DBUS_LIBS) + +systemd_timestamp_SOURCES = \ + src/timestamp.c + +systemd_timestamp_LDADD = \ + libsystemd-basic.la + +systemd_ac_power_SOURCES = \ + src/ac-power.c + +systemd_ac_power_CFLAGS = \ + $(AM_CFLAGS) \ + $(UDEV_CFLAGS) + +systemd_ac_power_LDADD = \ + libsystemd-basic.la \ + $(UDEV_LIBS) + +systemd_detect_virt_SOURCES = \ + src/detect-virt.c + +systemd_detect_virt_LDADD = \ + libsystemd-basic.la + +systemd_getty_generator_SOURCES = \ + src/getty-generator.c \ + src/unit-name.c + +systemd_getty_generator_LDADD = \ + libsystemd-basic.la + +systemd_rc_local_generator_SOURCES = \ + src/rc-local-generator.c + +systemd_rc_local_generator_LDADD = \ + libsystemd-basic.la + +systemd_remount_api_vfs_SOURCES = \ + src/remount-api-vfs.c \ + src/mount-setup.c \ + src/exit-status.c + +systemd_remount_api_vfs_LDADD = \ + libsystemd-basic.la + +systemd_cgroups_agent_SOURCES = \ + src/cgroups-agent.c \ + src/dbus-common.c + +systemd_cgroups_agent_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemd_cgroups_agent_LDADD = \ + libsystemd-basic.la \ + $(DBUS_LIBS) + +systemctl_SOURCES = \ + src/systemctl.c \ + src/utmp-wtmp.c \ + src/dbus-common.c \ + src/path-lookup.c \ + src/cgroup-show.c \ + src/cgroup-util.c \ + src/exit-status.c \ + src/unit-name.c \ + src/pager.c \ + src/install.c \ + src/spawn-agent.c \ + src/logs-show.c + +systemctl_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) + +systemctl_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la \ + libsystemd-journal.la \ + libsystemd-id128.la \ + $(DBUS_LIBS) + +systemd_notify_SOURCES = \ + src/notify.c \ + src/readahead/sd-readahead.c + +systemd_notify_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la + +systemd_ask_password_SOURCES = \ + src/ask-password.c \ + src/ask-password-api.c + +systemd_ask_password_LDADD = \ + libsystemd-basic.la + +systemd_reply_password_SOURCES = \ + src/reply-password.c + +systemd_reply_password_LDADD = \ + libsystemd-basic.la + +systemd_cgls_SOURCES = \ + src/cgls.c \ + src/cgroup-show.c \ + src/cgroup-util.c \ + src/pager.c + +systemd_cgls_LDADD = \ + libsystemd-basic.la + +systemd_cgtop_SOURCES = \ + src/cgtop.c \ + src/cgroup-util.c + +systemd_cgtop_LDADD = \ + libsystemd-basic.la + +systemd_nspawn_SOURCES = \ + src/nspawn.c \ + src/cgroup-util.c \ + src/loopback-setup.c + +systemd_nspawn_LDADD = \ + libsystemd-basic.la \ + libsystemd-daemon.la + +systemd_stdio_bridge_SOURCES = \ + src/bridge.c + +systemd_stdio_bridge_LDADD = \ + libsystemd-basic.la + +systemadm_SOURCES = \ + src/systemadm.vala \ + src/systemd-interfaces.vala \ + src/wraplabel.vala + +systemadm_CFLAGS = \ + $(AM_CFLAGS) \ + $(GTK_CFLAGS) \ + -Wno-unused-variable \ + -Wno-unused-function \ + -Wno-shadow \ + -Wno-format-nonliteral + +systemadm_VALAFLAGS = \ + --pkg=posix \ + --pkg=gtk+-2.0 \ + --pkg=gee-1.0 \ + -g + +systemadm_LDADD = \ + $(GTK_LIBS) + +systemd_gnome_ask_password_agent_SOURCES = \ + src/gnome-ask-password-agent.vala + +systemd_gnome_ask_password_agent_CFLAGS = \ + $(AM_CFLAGS) \ + $(LIBNOTIFY_CFLAGS) \ + $(GTK_CFLAGS) \ + -Wno-unused-variable \ + -Wno-unused-function \ + -Wno-shadow \ + -Wno-format-nonliteral + +systemd_gnome_ask_password_agent_VALAFLAGS = \ + --pkg=posix \ + --pkg=gtk+-2.0 \ + --pkg=linux \ + --pkg=gio-unix-2.0 \ + --pkg=libnotify \ + -g + +systemd_gnome_ask_password_agent_LDADD = \ + $(LIBNOTIFY_LIBS) \ + $(GTK_LIBS) + +systemd_tty_ask_password_agent_SOURCES = \ + src/tty-ask-password-agent.c \ + src/ask-password-api.c \ + src/utmp-wtmp.c + +systemd_tty_ask_password_agent_LDADD = \ + libsystemd-basic.la + + +# ------------------------------------------------------------------------------ +libsystemd_daemon_la_SOURCES = \ + src/sd-daemon.c + +libsystemd_daemon_la_CFLAGS = \ + $(AM_CFLAGS) \ + -fvisibility=hidden \ + -DSD_EXPORT_SYMBOLS + +libsystemd_daemon_la_LDFLAGS = \ + -shared \ + -version-info $(LIBSYSTEMD_DAEMON_CURRENT):$(LIBSYSTEMD_DAEMON_REVISION):$(LIBSYSTEMD_DAEMON_AGE) \ + -Wl,--version-script=$(top_srcdir)/src/libsystemd-daemon.sym + + +# ------------------------------------------------------------------------------ +libsystemd_id128_la_SOURCES = \ + src/sd-id128.c + +libsystemd_id128_la_CFLAGS = \ + $(AM_CFLAGS) \ + -fvisibility=hidden + +libsystemd_id128_la_LDFLAGS = \ + -shared \ + -version-info $(LIBSYSTEMD_ID128_CURRENT):$(LIBSYSTEMD_ID128_REVISION):$(LIBSYSTEMD_ID128_AGE) \ + -Wl,--version-script=$(top_srcdir)/src/libsystemd-id128.sym + +libsystemd_id128_la_LIBADD = \ + libsystemd-basic.la + +test_id128_SOURCES = \ + src/test-id128.c \ + src/sd-id128.c + +test_id128_LDADD = \ + libsystemd-basic.la + + +# ------------------------------------------------------------------------------ +systemd_journald_SOURCES = src/journal/journald.c \ + src/journal/sd-journal.c src/journal/journal-file.c \ + src/journal/lookup3.c src/journal/journal-rate-limit.c \ + src/sd-id128.c src/cgroup-util.c $(am__append_25) \ + $(am__append_26) +nodist_systemd_journald_SOURCES = \ + src/journal/journald-gperf.c + +systemd_journald_CFLAGS = $(AM_CFLAGS) $(ACL_CFLAGS) $(am__append_27) +systemd_journald_LDADD = libsystemd-basic.la libsystemd-daemon.la \ + libsystemd-login.la $(ACL_LIBS) $(am__append_28) +systemd_cat_SOURCES = \ + src/journal/cat.c + +systemd_cat_LDADD = \ + libsystemd-basic.la \ + libsystemd-journal.la + +systemd_journalctl_SOURCES = src/journal/journalctl.c src/pager.c \ + src/logs-show.c $(am__append_29) +systemd_journalctl_LDADD = libsystemd-basic.la libsystemd-journal.la \ + libsystemd-id128.la $(am__append_30) +@HAVE_XZ_TRUE@systemd_journalctl_CFLAGS = \ +@HAVE_XZ_TRUE@ $(AM_CFLAGS) \ +@HAVE_XZ_TRUE@ $(XZ_CFLAGS) + +test_journal_SOURCES = src/journal/test-journal.c \ + src/journal/sd-journal.c src/journal/journal-file.c \ + src/journal/lookup3.c src/journal/journal-send.c \ + src/sd-id128.c $(am__append_31) +test_journal_LDADD = libsystemd-basic.la $(am__append_32) +@HAVE_XZ_TRUE@test_journal_CFLAGS = \ +@HAVE_XZ_TRUE@ $(AM_CFLAGS) \ +@HAVE_XZ_TRUE@ $(XZ_CFLAGS) + +libsystemd_journal_la_SOURCES = src/journal/sd-journal.c \ + src/journal/journal-file.c src/journal/lookup3.c \ + src/journal/journal-send.c $(am__append_33) +libsystemd_journal_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden \ + $(am__append_34) +libsystemd_journal_la_LDFLAGS = \ + -shared \ + -version-info $(LIBSYSTEMD_JOURNAL_CURRENT):$(LIBSYSTEMD_JOURNAL_REVISION):$(LIBSYSTEMD_JOURNAL_AGE) \ + -Wl,--version-script=$(top_srcdir)/src/journal/libsystemd-journal.sym + +libsystemd_journal_la_LIBADD = libsystemd-basic.la libsystemd-id128.la \ + $(am__append_35) + +# ------------------------------------------------------------------------------ +@ENABLE_COREDUMP_TRUE@systemd_coredump_SOURCES = \ +@ENABLE_COREDUMP_TRUE@ src/journal/coredump.c + +@ENABLE_COREDUMP_TRUE@systemd_coredump_LDADD = \ +@ENABLE_COREDUMP_TRUE@ libsystemd-basic.la \ +@ENABLE_COREDUMP_TRUE@ libsystemd-journal.la \ +@ENABLE_COREDUMP_TRUE@ libsystemd-login.la + +@ENABLE_COREDUMP_TRUE@sysctl_DATA = \ +@ENABLE_COREDUMP_TRUE@ sysctl.d/coredump.conf + + +# ------------------------------------------------------------------------------ +@ENABLE_BINFMT_TRUE@systemd_binfmt_SOURCES = \ +@ENABLE_BINFMT_TRUE@ src/binfmt/binfmt.c + +@ENABLE_BINFMT_TRUE@systemd_binfmt_LDADD = \ +@ENABLE_BINFMT_TRUE@ libsystemd-basic.la + + +# ------------------------------------------------------------------------------ +@ENABLE_VCONSOLE_TRUE@systemd_vconsole_setup_SOURCES = \ +@ENABLE_VCONSOLE_TRUE@ src/vconsole/vconsole-setup.c + +@ENABLE_VCONSOLE_TRUE@systemd_vconsole_setup_LDADD = \ +@ENABLE_VCONSOLE_TRUE@ libsystemd-basic.la + + +# ------------------------------------------------------------------------------ +@ENABLE_READAHEAD_TRUE@systemd_readahead_collect_SOURCES = \ +@ENABLE_READAHEAD_TRUE@ src/readahead/readahead-collect.c \ +@ENABLE_READAHEAD_TRUE@ src/readahead/readahead-common.c + +@ENABLE_READAHEAD_TRUE@systemd_readahead_collect_LDADD = \ +@ENABLE_READAHEAD_TRUE@ libsystemd-basic.la \ +@ENABLE_READAHEAD_TRUE@ libsystemd-daemon.la \ +@ENABLE_READAHEAD_TRUE@ $(UDEV_LIBS) + +@ENABLE_READAHEAD_TRUE@systemd_readahead_collect_CFLAGS = \ +@ENABLE_READAHEAD_TRUE@ $(AM_CFLAGS) \ +@ENABLE_READAHEAD_TRUE@ $(UDEV_CFLAGS) + +@ENABLE_READAHEAD_TRUE@systemd_readahead_replay_SOURCES = \ +@ENABLE_READAHEAD_TRUE@ src/readahead/readahead-replay.c \ +@ENABLE_READAHEAD_TRUE@ src/readahead/readahead-common.c + +@ENABLE_READAHEAD_TRUE@systemd_readahead_replay_CFLAGS = \ +@ENABLE_READAHEAD_TRUE@ $(AM_CFLAGS) \ +@ENABLE_READAHEAD_TRUE@ $(UDEV_CFLAGS) + +@ENABLE_READAHEAD_TRUE@systemd_readahead_replay_LDADD = \ +@ENABLE_READAHEAD_TRUE@ libsystemd-basic.la \ +@ENABLE_READAHEAD_TRUE@ libsystemd-daemon.la \ +@ENABLE_READAHEAD_TRUE@ $(UDEV_LIBS) + +@ENABLE_QUOTACHECK_TRUE@systemd_quotacheck_SOURCES = \ +@ENABLE_QUOTACHECK_TRUE@ src/quotacheck.c + +@ENABLE_QUOTACHECK_TRUE@systemd_quotacheck_LDADD = \ +@ENABLE_QUOTACHECK_TRUE@ libsystemd-basic.la + +@ENABLE_RANDOMSEED_TRUE@systemd_random_seed_SOURCES = \ +@ENABLE_RANDOMSEED_TRUE@ src/random-seed.c + +@ENABLE_RANDOMSEED_TRUE@systemd_random_seed_LDADD = \ +@ENABLE_RANDOMSEED_TRUE@ libsystemd-basic.la + +@HAVE_LIBCRYPTSETUP_TRUE@systemd_cryptsetup_SOURCES = \ +@HAVE_LIBCRYPTSETUP_TRUE@ src/cryptsetup/cryptsetup.c \ +@HAVE_LIBCRYPTSETUP_TRUE@ src/ask-password-api.c + +@HAVE_LIBCRYPTSETUP_TRUE@systemd_cryptsetup_CFLAGS = \ +@HAVE_LIBCRYPTSETUP_TRUE@ $(AM_CFLAGS) \ +@HAVE_LIBCRYPTSETUP_TRUE@ $(LIBCRYPTSETUP_CFLAGS) \ +@HAVE_LIBCRYPTSETUP_TRUE@ $(UDEV_CFLAGS) + +@HAVE_LIBCRYPTSETUP_TRUE@systemd_cryptsetup_LDADD = \ +@HAVE_LIBCRYPTSETUP_TRUE@ $(LIBCRYPTSETUP_LIBS) \ +@HAVE_LIBCRYPTSETUP_TRUE@ $(UDEV_LIBS) \ +@HAVE_LIBCRYPTSETUP_TRUE@ libsystemd-basic.la + +@HAVE_LIBCRYPTSETUP_TRUE@systemd_cryptsetup_generator_SOURCES = \ +@HAVE_LIBCRYPTSETUP_TRUE@ src/cryptsetup/cryptsetup-generator.c \ +@HAVE_LIBCRYPTSETUP_TRUE@ src/unit-name.c + +@HAVE_LIBCRYPTSETUP_TRUE@systemd_cryptsetup_generator_LDADD = \ +@HAVE_LIBCRYPTSETUP_TRUE@ libsystemd-basic.la + + +# ------------------------------------------------------------------------------ +@ENABLE_HOSTNAMED_TRUE@systemd_hostnamed_SOURCES = \ +@ENABLE_HOSTNAMED_TRUE@ src/hostname/hostnamed.c \ +@ENABLE_HOSTNAMED_TRUE@ src/dbus-common.c \ +@ENABLE_HOSTNAMED_TRUE@ src/polkit.c + +@ENABLE_HOSTNAMED_TRUE@systemd_hostnamed_CFLAGS = \ +@ENABLE_HOSTNAMED_TRUE@ $(AM_CFLAGS) \ +@ENABLE_HOSTNAMED_TRUE@ $(DBUS_CFLAGS) + +@ENABLE_HOSTNAMED_TRUE@systemd_hostnamed_LDADD = \ +@ENABLE_HOSTNAMED_TRUE@ libsystemd-basic.la \ +@ENABLE_HOSTNAMED_TRUE@ libsystemd-daemon.la \ +@ENABLE_HOSTNAMED_TRUE@ $(DBUS_LIBS) + + +# ------------------------------------------------------------------------------ +@ENABLE_LOCALED_TRUE@systemd_localed_SOURCES = \ +@ENABLE_LOCALED_TRUE@ src/locale/localed.c \ +@ENABLE_LOCALED_TRUE@ src/dbus-common.c \ +@ENABLE_LOCALED_TRUE@ src/polkit.c + +@ENABLE_LOCALED_TRUE@systemd_localed_CFLAGS = \ +@ENABLE_LOCALED_TRUE@ $(AM_CFLAGS) \ +@ENABLE_LOCALED_TRUE@ $(DBUS_CFLAGS) + +@ENABLE_LOCALED_TRUE@systemd_localed_LDADD = \ +@ENABLE_LOCALED_TRUE@ libsystemd-basic.la \ +@ENABLE_LOCALED_TRUE@ libsystemd-daemon.la \ +@ENABLE_LOCALED_TRUE@ $(DBUS_LIBS) + +@ENABLE_LOCALED_TRUE@dist_pkgdata_DATA = \ +@ENABLE_LOCALED_TRUE@ src/locale/kbd-model-map + +@ENABLE_LOCALED_TRUE@dist_noinst_SCRIPT = \ +@ENABLE_LOCALED_TRUE@ src/locale/generate-kbd-model-map + + +# ------------------------------------------------------------------------------ +@ENABLE_TIMEDATED_TRUE@systemd_timedated_SOURCES = \ +@ENABLE_TIMEDATED_TRUE@ src/timedate/timedated.c \ +@ENABLE_TIMEDATED_TRUE@ src/dbus-common.c \ +@ENABLE_TIMEDATED_TRUE@ src/polkit.c + +@ENABLE_TIMEDATED_TRUE@systemd_timedated_CFLAGS = \ +@ENABLE_TIMEDATED_TRUE@ $(AM_CFLAGS) \ +@ENABLE_TIMEDATED_TRUE@ $(DBUS_CFLAGS) + +@ENABLE_TIMEDATED_TRUE@systemd_timedated_LDADD = \ +@ENABLE_TIMEDATED_TRUE@ libsystemd-basic.la \ +@ENABLE_TIMEDATED_TRUE@ libsystemd-daemon.la \ +@ENABLE_TIMEDATED_TRUE@ $(DBUS_LIBS) + + +# ------------------------------------------------------------------------------ +@ENABLE_LOGIND_TRUE@systemd_logind_SOURCES = src/login/logind.c \ +@ENABLE_LOGIND_TRUE@ src/login/logind-dbus.c \ +@ENABLE_LOGIND_TRUE@ src/login/logind-device.c \ +@ENABLE_LOGIND_TRUE@ src/login/logind-seat.c \ +@ENABLE_LOGIND_TRUE@ src/login/logind-seat-dbus.c \ +@ENABLE_LOGIND_TRUE@ src/login/logind-session.c \ +@ENABLE_LOGIND_TRUE@ src/login/logind-session-dbus.c \ +@ENABLE_LOGIND_TRUE@ src/login/logind-user.c \ +@ENABLE_LOGIND_TRUE@ src/login/logind-user-dbus.c \ +@ENABLE_LOGIND_TRUE@ src/dbus-common.c src/dbus-loop.c \ +@ENABLE_LOGIND_TRUE@ src/cgroup-util.c src/polkit.c \ +@ENABLE_LOGIND_TRUE@ $(am__append_90) +@ENABLE_LOGIND_TRUE@nodist_systemd_logind_SOURCES = \ +@ENABLE_LOGIND_TRUE@ src/login/logind-gperf.c + +@ENABLE_LOGIND_TRUE@systemd_logind_CFLAGS = \ +@ENABLE_LOGIND_TRUE@ $(AM_CFLAGS) \ +@ENABLE_LOGIND_TRUE@ $(DBUS_CFLAGS) \ +@ENABLE_LOGIND_TRUE@ $(UDEV_CFLAGS) \ +@ENABLE_LOGIND_TRUE@ $(ACL_CFLAGS) + +@ENABLE_LOGIND_TRUE@systemd_logind_LDADD = \ +@ENABLE_LOGIND_TRUE@ libsystemd-basic.la \ +@ENABLE_LOGIND_TRUE@ libsystemd-daemon.la \ +@ENABLE_LOGIND_TRUE@ $(DBUS_LIBS) \ +@ENABLE_LOGIND_TRUE@ $(UDEV_LIBS) \ +@ENABLE_LOGIND_TRUE@ $(ACL_LIBS) + +@ENABLE_LOGIND_TRUE@systemd_user_sessions_SOURCES = \ +@ENABLE_LOGIND_TRUE@ src/login/user-sessions.c \ +@ENABLE_LOGIND_TRUE@ src/cgroup-util.c + +@ENABLE_LOGIND_TRUE@systemd_user_sessions_LDADD = \ +@ENABLE_LOGIND_TRUE@ libsystemd-basic.la + +@ENABLE_LOGIND_TRUE@systemd_loginctl_SOURCES = \ +@ENABLE_LOGIND_TRUE@ src/login/loginctl.c \ +@ENABLE_LOGIND_TRUE@ src/login/sysfs-show.c \ +@ENABLE_LOGIND_TRUE@ src/dbus-common.c \ +@ENABLE_LOGIND_TRUE@ src/cgroup-show.c \ +@ENABLE_LOGIND_TRUE@ src/cgroup-util.c \ +@ENABLE_LOGIND_TRUE@ src/pager.c + +@ENABLE_LOGIND_TRUE@systemd_loginctl_CFLAGS = \ +@ENABLE_LOGIND_TRUE@ $(AM_CFLAGS) \ +@ENABLE_LOGIND_TRUE@ $(DBUS_CFLAGS) \ +@ENABLE_LOGIND_TRUE@ $(UDEV_CFLAGS) + +@ENABLE_LOGIND_TRUE@systemd_loginctl_LDADD = \ +@ENABLE_LOGIND_TRUE@ libsystemd-basic.la \ +@ENABLE_LOGIND_TRUE@ $(DBUS_LIBS) \ +@ENABLE_LOGIND_TRUE@ $(UDEV_LIBS) + +@ENABLE_LOGIND_TRUE@test_login_SOURCES = \ +@ENABLE_LOGIND_TRUE@ src/login/test-login.c + +@ENABLE_LOGIND_TRUE@test_login_LDADD = \ +@ENABLE_LOGIND_TRUE@ libsystemd-basic.la \ +@ENABLE_LOGIND_TRUE@ libsystemd-login.la + +@ENABLE_LOGIND_TRUE@libsystemd_login_la_SOURCES = \ +@ENABLE_LOGIND_TRUE@ src/login/sd-login.c \ +@ENABLE_LOGIND_TRUE@ src/cgroup-util.c + +@ENABLE_LOGIND_TRUE@libsystemd_login_la_CFLAGS = \ +@ENABLE_LOGIND_TRUE@ $(AM_CFLAGS) \ +@ENABLE_LOGIND_TRUE@ -fvisibility=hidden + +@ENABLE_LOGIND_TRUE@libsystemd_login_la_LDFLAGS = \ +@ENABLE_LOGIND_TRUE@ -shared \ +@ENABLE_LOGIND_TRUE@ -version-info $(LIBSYSTEMD_LOGIN_CURRENT):$(LIBSYSTEMD_LOGIN_REVISION):$(LIBSYSTEMD_LOGIN_AGE) \ +@ENABLE_LOGIND_TRUE@ -Wl,--version-script=$(top_srcdir)/src/login/libsystemd-login.sym + +@ENABLE_LOGIND_TRUE@libsystemd_login_la_LIBADD = \ +@ENABLE_LOGIND_TRUE@ libsystemd-basic.la + +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@pam_systemd_la_SOURCES = \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ src/login/pam-module.c \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ src/dbus-common.c + +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@pam_systemd_la_CFLAGS = \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ $(AM_CFLAGS) \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ $(PAM_CFLAGS) \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ $(DBUS_CFLAGS) \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ -fvisibility=hidden + +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@pam_systemd_la_LDFLAGS = \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ -module \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ -export-dynamic \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ -avoid-version \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ -shared \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ -export-symbols-regex '^pam_sm_.*' + +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@pam_systemd_la_LIBADD = \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ libsystemd-basic.la \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ libsystemd-daemon.la \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ $(PAM_LIBS) \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ $(DBUS_LIBS) + +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@pamlib_LTLIBRARIES = \ +@ENABLE_LOGIND_TRUE@@HAVE_PAM_TRUE@ pam_systemd.la + +@ENABLE_LOGIND_TRUE@systemd_multi_seat_x_SOURCES = \ +@ENABLE_LOGIND_TRUE@ src/login/multi-seat-x.c + +@ENABLE_LOGIND_TRUE@systemd_multi_seat_x_CFLAGS = \ +@ENABLE_LOGIND_TRUE@ $(AM_CFLAGS) \ +@ENABLE_LOGIND_TRUE@ $(UDEV_CFLAGS) + +@ENABLE_LOGIND_TRUE@systemd_multi_seat_x_LDADD = \ +@ENABLE_LOGIND_TRUE@ libsystemd-basic.la \ +@ENABLE_LOGIND_TRUE@ $(UDEV_LIBS) + +@ENABLE_LOGIND_TRUE@systemd_uaccess_SOURCES = src/login/uaccess.c \ +@ENABLE_LOGIND_TRUE@ $(am__append_105) +@ENABLE_LOGIND_TRUE@systemd_uaccess_CFLAGS = \ +@ENABLE_LOGIND_TRUE@ $(AM_CFLAGS) \ +@ENABLE_LOGIND_TRUE@ $(UDEV_CFLAGS) \ +@ENABLE_LOGIND_TRUE@ $(ACL_CFLAGS) + +@ENABLE_LOGIND_TRUE@systemd_uaccess_LDADD = \ +@ENABLE_LOGIND_TRUE@ libsystemd-basic.la \ +@ENABLE_LOGIND_TRUE@ libsystemd-daemon.la \ +@ENABLE_LOGIND_TRUE@ libsystemd-login.la \ +@ENABLE_LOGIND_TRUE@ $(UDEV_LIBS) \ +@ENABLE_LOGIND_TRUE@ $(ACL_LIBS) + +# ------------------------------------------------------------------------------ +SED_PROCESS = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(SED) -e 's,@rootlibexecdir\@,$(rootlibexecdir),g' \ + -e 's,@rootbindir\@,$(rootbindir),g' \ + -e 's,@bindir\@,$(bindir),g' \ + -e 's,@SYSTEMCTL\@,$(rootbindir)/systemctl,g' \ + -e 's,@SYSTEMD_NOTIFY\@,$(rootbindir)/systemd-notify,g' \ + -e 's,@pkgsysconfdir\@,$(pkgsysconfdir),g' \ + -e 's,@pkgdatadir\@,$(pkgdatadir),g' \ + -e 's,@pkglibexecdir\@,$(pkglibexecdir),g' \ + -e 's,@systemunitdir\@,$(systemunitdir),g' \ + -e 's,@userunitdir\@,$(userunitdir),g' \ + -e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \ + -e 's,@PACKAGE_NAME\@,$(PACKAGE_NAME),g' \ + -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' \ + -e 's,@prefix\@,$(prefix),g' \ + -e 's,@exec_prefix\@,$(exec_prefix),g' \ + -e 's,@libdir\@,$(libdir),g' \ + -e 's,@includedir\@,$(includedir),g' \ + < $< > $@ || rm $@ + +M4_PROCESS_SYSTEM = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(M4) -P $(M4_DEFINES) -DFOR_SYSTEM=1 < $< > $@ || rm $@ + +M4_PROCESS_USER = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(M4) -P $(M4_DEFINES) -DFOR_USER=1 < $< > $@ || rm $@ + +@HAVE_XSLTPROC_TRUE@XSLTPROC_FLAGS = \ +@HAVE_XSLTPROC_TRUE@ --nonet \ +@HAVE_XSLTPROC_TRUE@ --stringparam funcsynopsis.style ansi + +@HAVE_XSLTPROC_TRUE@XSLTPROC_PROCESS_MAN = \ +@HAVE_XSLTPROC_TRUE@ $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< + +@HAVE_XSLTPROC_TRUE@XSLTPROC_PROCESS_MAN_IN = \ +@HAVE_XSLTPROC_TRUE@ $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC) -o ${@:.in=} $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< && \ +@HAVE_XSLTPROC_TRUE@ mv ${@:.in=} $@ + +@HAVE_XSLTPROC_TRUE@XSLTPROC_PROCESS_HTML = \ +@HAVE_XSLTPROC_TRUE@ $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(srcdir)/man/custom-html.xsl $< + +@HAVE_XSLTPROC_TRUE@XSLTPROC_PROCESS_HTML_IN = \ +@HAVE_XSLTPROC_TRUE@ $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC) -o ${@:.in=} $(XSLTPROC_FLAGS) $(srcdir)/man/custom-html.xsl $< && \ +@HAVE_XSLTPROC_TRUE@ mv ${@:.in=} $@ + +DBUS_PREPROCESS = $(CPP) -P $(DBUS_CFLAGS) -imacros dbus/dbus-protocol.h +DISTCHECK_CONFIGURE_FLAGS = \ + --with-dbuspolicydir=$$dc_install_base/$(dbuspolicydir) \ + --with-dbussessionservicedir=$$dc_install_base/$(dbussessionservicedir) \ + --with-dbussystemservicedir=$$dc_install_base/$(dbussystemservicedir) \ + --with-dbusinterfacedir=$$dc_install_base/$(dbusinterfacedir) \ + --with-udevrulesdir=$$dc_install_base/$(udevrulesdir) \ + --with-pamlibdir=$$dc_install_base/$(pamlibdir) \ + --with-rootprefix=$$dc_install_base/$(prefix) + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then rm -f stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +install-pamlibLTLIBRARIES: $(pamlib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(pamlibdir)" || $(MKDIR_P) "$(DESTDIR)$(pamlibdir)" + @list='$(pamlib_LTLIBRARIES)'; test -n "$(pamlibdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pamlibdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pamlibdir)"; \ + } + +uninstall-pamlibLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(pamlib_LTLIBRARIES)'; test -n "$(pamlibdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pamlibdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pamlibdir)/$$f"; \ + done + +clean-pamlibLTLIBRARIES: + -test -z "$(pamlib_LTLIBRARIES)" || rm -f $(pamlib_LTLIBRARIES) + @list='$(pamlib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +src/$(am__dirstamp): + @$(MKDIR_P) src + @: > src/$(am__dirstamp) +src/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/$(DEPDIR) + @: > src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_basic_la-util.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_basic_la-virt.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_basic_la-label.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_basic_la-hashmap.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_basic_la-set.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_basic_la-strv.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_basic_la-conf-parser.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_basic_la-socket-util.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_basic_la-log.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_basic_la-ratelimit.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_basic_la-exit-status.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +libsystemd-basic.la: $(libsystemd_basic_la_OBJECTS) $(libsystemd_basic_la_DEPENDENCIES) $(EXTRA_libsystemd_basic_la_DEPENDENCIES) + $(AM_V_CCLD)$(libsystemd_basic_la_LINK) $(libsystemd_basic_la_OBJECTS) $(libsystemd_basic_la_LIBADD) $(LIBS) +src/libsystemd_core_la-unit.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-job.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-manager.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-path-lookup.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-load-fragment.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-service.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-automount.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-mount.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-swap.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-device.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-target.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-snapshot.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-socket.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-timer.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-path.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-load-dropin.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-execute.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-utmp-wtmp.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-manager.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-unit.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-job.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-service.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-socket.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-timer.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-target.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-mount.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-automount.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-swap.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-snapshot.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-device.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-execute.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-path.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-cgroup.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-mount-setup.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-hostname-setup.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-selinux-setup.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-loopback-setup.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-kmod-setup.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-locale-setup.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-machine-id-setup.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-specifier.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-unit-name.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-fdset.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-namespace.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-tcpwrap.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-cgroup-util.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-condition.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-dbus-common.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-sd-daemon.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-install.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-cgroup-attr.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-sd-id128.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-load-fragment-gperf.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_core_la-load-fragment-gperf-nulstr.lo: \ + src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +libsystemd-core.la: $(libsystemd_core_la_OBJECTS) $(libsystemd_core_la_DEPENDENCIES) $(EXTRA_libsystemd_core_la_DEPENDENCIES) + $(AM_V_CCLD)$(libsystemd_core_la_LINK) $(libsystemd_core_la_OBJECTS) $(libsystemd_core_la_LIBADD) $(LIBS) +src/libsystemd_daemon_la-sd-daemon.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +libsystemd-daemon.la: $(libsystemd_daemon_la_OBJECTS) $(libsystemd_daemon_la_DEPENDENCIES) $(EXTRA_libsystemd_daemon_la_DEPENDENCIES) + $(AM_V_CCLD)$(libsystemd_daemon_la_LINK) -rpath $(libdir) $(libsystemd_daemon_la_OBJECTS) $(libsystemd_daemon_la_LIBADD) $(LIBS) +src/libsystemd_id128_la-sd-id128.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +libsystemd-id128.la: $(libsystemd_id128_la_OBJECTS) $(libsystemd_id128_la_DEPENDENCIES) $(EXTRA_libsystemd_id128_la_DEPENDENCIES) + $(AM_V_CCLD)$(libsystemd_id128_la_LINK) -rpath $(libdir) $(libsystemd_id128_la_OBJECTS) $(libsystemd_id128_la_LIBADD) $(LIBS) +src/journal/$(am__dirstamp): + @$(MKDIR_P) src/journal + @: > src/journal/$(am__dirstamp) +src/journal/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/journal/$(DEPDIR) + @: > src/journal/$(DEPDIR)/$(am__dirstamp) +src/journal/libsystemd_journal_la-sd-journal.lo: \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/journal/libsystemd_journal_la-journal-file.lo: \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/journal/libsystemd_journal_la-lookup3.lo: \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/journal/libsystemd_journal_la-journal-send.lo: \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/journal/libsystemd_journal_la-compress.lo: \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +libsystemd-journal.la: $(libsystemd_journal_la_OBJECTS) $(libsystemd_journal_la_DEPENDENCIES) $(EXTRA_libsystemd_journal_la_DEPENDENCIES) + $(AM_V_CCLD)$(libsystemd_journal_la_LINK) -rpath $(libdir) $(libsystemd_journal_la_OBJECTS) $(libsystemd_journal_la_LIBADD) $(LIBS) +src/login/$(am__dirstamp): + @$(MKDIR_P) src/login + @: > src/login/$(am__dirstamp) +src/login/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/login/$(DEPDIR) + @: > src/login/$(DEPDIR)/$(am__dirstamp) +src/login/libsystemd_login_la-sd-login.lo: src/login/$(am__dirstamp) \ + src/login/$(DEPDIR)/$(am__dirstamp) +src/libsystemd_login_la-cgroup-util.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +libsystemd-login.la: $(libsystemd_login_la_OBJECTS) $(libsystemd_login_la_DEPENDENCIES) $(EXTRA_libsystemd_login_la_DEPENDENCIES) + $(AM_V_CCLD)$(libsystemd_login_la_LINK) $(am_libsystemd_login_la_rpath) $(libsystemd_login_la_OBJECTS) $(libsystemd_login_la_LIBADD) $(LIBS) +src/login/pam_systemd_la-pam-module.lo: src/login/$(am__dirstamp) \ + src/login/$(DEPDIR)/$(am__dirstamp) +src/pam_systemd_la-dbus-common.lo: src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +pam_systemd.la: $(pam_systemd_la_OBJECTS) $(pam_systemd_la_DEPENDENCIES) $(EXTRA_pam_systemd_la_DEPENDENCIES) + $(AM_V_CCLD)$(pam_systemd_la_LINK) $(am_pam_systemd_la_rpath) $(pam_systemd_la_OBJECTS) $(pam_systemd_la_LIBADD) $(LIBS) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +install-rootbinPROGRAMS: $(rootbin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(rootbindir)" || $(MKDIR_P) "$(DESTDIR)$(rootbindir)" + @list='$(rootbin_PROGRAMS)'; test -n "$(rootbindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(rootbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(rootbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-rootbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(rootbin_PROGRAMS)'; test -n "$(rootbindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(rootbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(rootbindir)" && rm -f $$files + +clean-rootbinPROGRAMS: + @list='$(rootbin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +install-rootlibexecPROGRAMS: $(rootlibexec_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(rootlibexecdir)" || $(MKDIR_P) "$(DESTDIR)$(rootlibexecdir)" + @list='$(rootlibexec_PROGRAMS)'; test -n "$(rootlibexecdir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(rootlibexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(rootlibexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-rootlibexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(rootlibexec_PROGRAMS)'; test -n "$(rootlibexecdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(rootlibexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(rootlibexecdir)" && rm -f $$files + +clean-rootlibexecPROGRAMS: + @list='$(rootlibexec_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +install-systemgeneratorPROGRAMS: $(systemgenerator_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(systemgeneratordir)" || $(MKDIR_P) "$(DESTDIR)$(systemgeneratordir)" + @list='$(systemgenerator_PROGRAMS)'; test -n "$(systemgeneratordir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(systemgeneratordir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(systemgeneratordir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-systemgeneratorPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(systemgenerator_PROGRAMS)'; test -n "$(systemgeneratordir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(systemgeneratordir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(systemgeneratordir)" && rm -f $$files + +clean-systemgeneratorPROGRAMS: + @list='$(systemgenerator_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +src/systemadm-systemadm.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemadm-systemd-interfaces.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemadm-wraplabel.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemadm$(EXEEXT): $(systemadm_OBJECTS) $(systemadm_DEPENDENCIES) $(EXTRA_systemadm_DEPENDENCIES) + @rm -f systemadm$(EXEEXT) + $(AM_V_CCLD)$(systemadm_LINK) $(systemadm_OBJECTS) $(systemadm_LDADD) $(LIBS) +src/systemctl-systemctl.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemctl-utmp-wtmp.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemctl-dbus-common.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemctl-path-lookup.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemctl-cgroup-show.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemctl-cgroup-util.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemctl-exit-status.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemctl-unit-name.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemctl-pager.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemctl-install.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemctl-spawn-agent.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemctl-logs-show.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemctl$(EXEEXT): $(systemctl_OBJECTS) $(systemctl_DEPENDENCIES) $(EXTRA_systemctl_DEPENDENCIES) + @rm -f systemctl$(EXEEXT) + $(AM_V_CCLD)$(systemctl_LINK) $(systemctl_OBJECTS) $(systemctl_LDADD) $(LIBS) +src/systemd-main.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd$(EXEEXT): $(systemd_OBJECTS) $(systemd_DEPENDENCIES) $(EXTRA_systemd_DEPENDENCIES) + @rm -f systemd$(EXEEXT) + $(AM_V_CCLD)$(systemd_LINK) $(systemd_OBJECTS) $(systemd_LDADD) $(LIBS) +src/systemd_ac_power-ac-power.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-ac-power$(EXEEXT): $(systemd_ac_power_OBJECTS) $(systemd_ac_power_DEPENDENCIES) $(EXTRA_systemd_ac_power_DEPENDENCIES) + @rm -f systemd-ac-power$(EXEEXT) + $(AM_V_CCLD)$(systemd_ac_power_LINK) $(systemd_ac_power_OBJECTS) $(systemd_ac_power_LDADD) $(LIBS) +src/ask-password.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/ask-password-api.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-ask-password$(EXEEXT): $(systemd_ask_password_OBJECTS) $(systemd_ask_password_DEPENDENCIES) $(EXTRA_systemd_ask_password_DEPENDENCIES) + @rm -f systemd-ask-password$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_ask_password_OBJECTS) $(systemd_ask_password_LDADD) $(LIBS) +src/binfmt/$(am__dirstamp): + @$(MKDIR_P) src/binfmt + @: > src/binfmt/$(am__dirstamp) +src/binfmt/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/binfmt/$(DEPDIR) + @: > src/binfmt/$(DEPDIR)/$(am__dirstamp) +src/binfmt/binfmt.$(OBJEXT): src/binfmt/$(am__dirstamp) \ + src/binfmt/$(DEPDIR)/$(am__dirstamp) +systemd-binfmt$(EXEEXT): $(systemd_binfmt_OBJECTS) $(systemd_binfmt_DEPENDENCIES) $(EXTRA_systemd_binfmt_DEPENDENCIES) + @rm -f systemd-binfmt$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_binfmt_OBJECTS) $(systemd_binfmt_LDADD) $(LIBS) +src/journal/cat.$(OBJEXT): src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +systemd-cat$(EXEEXT): $(systemd_cat_OBJECTS) $(systemd_cat_DEPENDENCIES) $(EXTRA_systemd_cat_DEPENDENCIES) + @rm -f systemd-cat$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_cat_OBJECTS) $(systemd_cat_LDADD) $(LIBS) +src/cgls.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/cgroup-show.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/cgroup-util.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/pager.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +systemd-cgls$(EXEEXT): $(systemd_cgls_OBJECTS) $(systemd_cgls_DEPENDENCIES) $(EXTRA_systemd_cgls_DEPENDENCIES) + @rm -f systemd-cgls$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_cgls_OBJECTS) $(systemd_cgls_LDADD) $(LIBS) +src/systemd_cgroups_agent-cgroups-agent.$(OBJEXT): \ + src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/systemd_cgroups_agent-dbus-common.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-cgroups-agent$(EXEEXT): $(systemd_cgroups_agent_OBJECTS) $(systemd_cgroups_agent_DEPENDENCIES) $(EXTRA_systemd_cgroups_agent_DEPENDENCIES) + @rm -f systemd-cgroups-agent$(EXEEXT) + $(AM_V_CCLD)$(systemd_cgroups_agent_LINK) $(systemd_cgroups_agent_OBJECTS) $(systemd_cgroups_agent_LDADD) $(LIBS) +src/cgtop.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +systemd-cgtop$(EXEEXT): $(systemd_cgtop_OBJECTS) $(systemd_cgtop_DEPENDENCIES) $(EXTRA_systemd_cgtop_DEPENDENCIES) + @rm -f systemd-cgtop$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_cgtop_OBJECTS) $(systemd_cgtop_LDADD) $(LIBS) +src/journal/coredump.$(OBJEXT): src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +systemd-coredump$(EXEEXT): $(systemd_coredump_OBJECTS) $(systemd_coredump_DEPENDENCIES) $(EXTRA_systemd_coredump_DEPENDENCIES) + @rm -f systemd-coredump$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_coredump_OBJECTS) $(systemd_coredump_LDADD) $(LIBS) +src/cryptsetup/$(am__dirstamp): + @$(MKDIR_P) src/cryptsetup + @: > src/cryptsetup/$(am__dirstamp) +src/cryptsetup/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/cryptsetup/$(DEPDIR) + @: > src/cryptsetup/$(DEPDIR)/$(am__dirstamp) +src/cryptsetup/systemd_cryptsetup-cryptsetup.$(OBJEXT): \ + src/cryptsetup/$(am__dirstamp) \ + src/cryptsetup/$(DEPDIR)/$(am__dirstamp) +src/systemd_cryptsetup-ask-password-api.$(OBJEXT): \ + src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +systemd-cryptsetup$(EXEEXT): $(systemd_cryptsetup_OBJECTS) $(systemd_cryptsetup_DEPENDENCIES) $(EXTRA_systemd_cryptsetup_DEPENDENCIES) + @rm -f systemd-cryptsetup$(EXEEXT) + $(AM_V_CCLD)$(systemd_cryptsetup_LINK) $(systemd_cryptsetup_OBJECTS) $(systemd_cryptsetup_LDADD) $(LIBS) +src/cryptsetup/cryptsetup-generator.$(OBJEXT): \ + src/cryptsetup/$(am__dirstamp) \ + src/cryptsetup/$(DEPDIR)/$(am__dirstamp) +src/unit-name.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-cryptsetup-generator$(EXEEXT): $(systemd_cryptsetup_generator_OBJECTS) $(systemd_cryptsetup_generator_DEPENDENCIES) $(EXTRA_systemd_cryptsetup_generator_DEPENDENCIES) + @rm -f systemd-cryptsetup-generator$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_cryptsetup_generator_OBJECTS) $(systemd_cryptsetup_generator_LDADD) $(LIBS) +src/detect-virt.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-detect-virt$(EXEEXT): $(systemd_detect_virt_OBJECTS) $(systemd_detect_virt_DEPENDENCIES) $(EXTRA_systemd_detect_virt_DEPENDENCIES) + @rm -f systemd-detect-virt$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_detect_virt_OBJECTS) $(systemd_detect_virt_LDADD) $(LIBS) +src/systemd_fsck-fsck.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_fsck-dbus-common.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-fsck$(EXEEXT): $(systemd_fsck_OBJECTS) $(systemd_fsck_DEPENDENCIES) $(EXTRA_systemd_fsck_DEPENDENCIES) + @rm -f systemd-fsck$(EXEEXT) + $(AM_V_CCLD)$(systemd_fsck_LINK) $(systemd_fsck_OBJECTS) $(systemd_fsck_LDADD) $(LIBS) +src/getty-generator.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-getty-generator$(EXEEXT): $(systemd_getty_generator_OBJECTS) $(systemd_getty_generator_DEPENDENCIES) $(EXTRA_systemd_getty_generator_DEPENDENCIES) + @rm -f systemd-getty-generator$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_getty_generator_OBJECTS) $(systemd_getty_generator_LDADD) $(LIBS) +src/systemd_gnome_ask_password_agent-gnome-ask-password-agent.$(OBJEXT): \ + src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +systemd-gnome-ask-password-agent$(EXEEXT): $(systemd_gnome_ask_password_agent_OBJECTS) $(systemd_gnome_ask_password_agent_DEPENDENCIES) $(EXTRA_systemd_gnome_ask_password_agent_DEPENDENCIES) + @rm -f systemd-gnome-ask-password-agent$(EXEEXT) + $(AM_V_CCLD)$(systemd_gnome_ask_password_agent_LINK) $(systemd_gnome_ask_password_agent_OBJECTS) $(systemd_gnome_ask_password_agent_LDADD) $(LIBS) +src/hostname/$(am__dirstamp): + @$(MKDIR_P) src/hostname + @: > src/hostname/$(am__dirstamp) +src/hostname/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/hostname/$(DEPDIR) + @: > src/hostname/$(DEPDIR)/$(am__dirstamp) +src/hostname/systemd_hostnamed-hostnamed.$(OBJEXT): \ + src/hostname/$(am__dirstamp) \ + src/hostname/$(DEPDIR)/$(am__dirstamp) +src/systemd_hostnamed-dbus-common.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_hostnamed-polkit.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-hostnamed$(EXEEXT): $(systemd_hostnamed_OBJECTS) $(systemd_hostnamed_DEPENDENCIES) $(EXTRA_systemd_hostnamed_DEPENDENCIES) + @rm -f systemd-hostnamed$(EXEEXT) + $(AM_V_CCLD)$(systemd_hostnamed_LINK) $(systemd_hostnamed_OBJECTS) $(systemd_hostnamed_LDADD) $(LIBS) +src/systemd_initctl-initctl.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_initctl-dbus-common.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-initctl$(EXEEXT): $(systemd_initctl_OBJECTS) $(systemd_initctl_DEPENDENCIES) $(EXTRA_systemd_initctl_DEPENDENCIES) + @rm -f systemd-initctl$(EXEEXT) + $(AM_V_CCLD)$(systemd_initctl_LINK) $(systemd_initctl_OBJECTS) $(systemd_initctl_LDADD) $(LIBS) +src/journal/systemd_journalctl-journalctl.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/systemd_journalctl-pager.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_journalctl-logs-show.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/journal/systemd_journalctl-compress.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +systemd-journalctl$(EXEEXT): $(systemd_journalctl_OBJECTS) $(systemd_journalctl_DEPENDENCIES) $(EXTRA_systemd_journalctl_DEPENDENCIES) + @rm -f systemd-journalctl$(EXEEXT) + $(AM_V_CCLD)$(systemd_journalctl_LINK) $(systemd_journalctl_OBJECTS) $(systemd_journalctl_LDADD) $(LIBS) +src/journal/systemd_journald-journald.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/journal/systemd_journald-sd-journal.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/journal/systemd_journald-journal-file.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/journal/systemd_journald-lookup3.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/journal/systemd_journald-journal-rate-limit.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/systemd_journald-sd-id128.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_journald-cgroup-util.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_journald-acl-util.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/journal/systemd_journald-compress.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/journal/systemd_journald-journald-gperf.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +systemd-journald$(EXEEXT): $(systemd_journald_OBJECTS) $(systemd_journald_DEPENDENCIES) $(EXTRA_systemd_journald_DEPENDENCIES) + @rm -f systemd-journald$(EXEEXT) + $(AM_V_CCLD)$(systemd_journald_LINK) $(systemd_journald_OBJECTS) $(systemd_journald_LDADD) $(LIBS) +src/locale/$(am__dirstamp): + @$(MKDIR_P) src/locale + @: > src/locale/$(am__dirstamp) +src/locale/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/locale/$(DEPDIR) + @: > src/locale/$(DEPDIR)/$(am__dirstamp) +src/locale/systemd_localed-localed.$(OBJEXT): \ + src/locale/$(am__dirstamp) \ + src/locale/$(DEPDIR)/$(am__dirstamp) +src/systemd_localed-dbus-common.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_localed-polkit.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-localed$(EXEEXT): $(systemd_localed_OBJECTS) $(systemd_localed_DEPENDENCIES) $(EXTRA_systemd_localed_DEPENDENCIES) + @rm -f systemd-localed$(EXEEXT) + $(AM_V_CCLD)$(systemd_localed_LINK) $(systemd_localed_OBJECTS) $(systemd_localed_LDADD) $(LIBS) +src/login/systemd_loginctl-loginctl.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +src/login/systemd_loginctl-sysfs-show.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +src/systemd_loginctl-dbus-common.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_loginctl-cgroup-show.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_loginctl-cgroup-util.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_loginctl-pager.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-loginctl$(EXEEXT): $(systemd_loginctl_OBJECTS) $(systemd_loginctl_DEPENDENCIES) $(EXTRA_systemd_loginctl_DEPENDENCIES) + @rm -f systemd-loginctl$(EXEEXT) + $(AM_V_CCLD)$(systemd_loginctl_LINK) $(systemd_loginctl_OBJECTS) $(systemd_loginctl_LDADD) $(LIBS) +src/login/systemd_logind-logind.$(OBJEXT): src/login/$(am__dirstamp) \ + src/login/$(DEPDIR)/$(am__dirstamp) +src/login/systemd_logind-logind-dbus.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +src/login/systemd_logind-logind-device.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +src/login/systemd_logind-logind-seat.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +src/login/systemd_logind-logind-seat-dbus.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +src/login/systemd_logind-logind-session.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +src/login/systemd_logind-logind-session-dbus.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +src/login/systemd_logind-logind-user.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +src/login/systemd_logind-logind-user-dbus.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +src/systemd_logind-dbus-common.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_logind-dbus-loop.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_logind-cgroup-util.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_logind-polkit.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/login/systemd_logind-logind-acl.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +src/systemd_logind-acl-util.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/login/systemd_logind-logind-gperf.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +systemd-logind$(EXEEXT): $(systemd_logind_OBJECTS) $(systemd_logind_DEPENDENCIES) $(EXTRA_systemd_logind_DEPENDENCIES) + @rm -f systemd-logind$(EXEEXT) + $(AM_V_CCLD)$(systemd_logind_LINK) $(systemd_logind_OBJECTS) $(systemd_logind_LDADD) $(LIBS) +src/machine-id-setup.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/machine-id-main.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/sd-id128.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-machine-id-setup$(EXEEXT): $(systemd_machine_id_setup_OBJECTS) $(systemd_machine_id_setup_DEPENDENCIES) $(EXTRA_systemd_machine_id_setup_DEPENDENCIES) + @rm -f systemd-machine-id-setup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_machine_id_setup_OBJECTS) $(systemd_machine_id_setup_LDADD) $(LIBS) +src/systemd_modules_load-modules-load.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-modules-load$(EXEEXT): $(systemd_modules_load_OBJECTS) $(systemd_modules_load_DEPENDENCIES) $(EXTRA_systemd_modules_load_DEPENDENCIES) + @rm -f systemd-modules-load$(EXEEXT) + $(AM_V_CCLD)$(systemd_modules_load_LINK) $(systemd_modules_load_OBJECTS) $(systemd_modules_load_LDADD) $(LIBS) +src/login/systemd_multi_seat_x-multi-seat-x.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +systemd-multi-seat-x$(EXEEXT): $(systemd_multi_seat_x_OBJECTS) $(systemd_multi_seat_x_DEPENDENCIES) $(EXTRA_systemd_multi_seat_x_DEPENDENCIES) + @rm -f systemd-multi-seat-x$(EXEEXT) + $(AM_V_CCLD)$(systemd_multi_seat_x_LINK) $(systemd_multi_seat_x_OBJECTS) $(systemd_multi_seat_x_LDADD) $(LIBS) +src/notify.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/readahead/$(am__dirstamp): + @$(MKDIR_P) src/readahead + @: > src/readahead/$(am__dirstamp) +src/readahead/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/readahead/$(DEPDIR) + @: > src/readahead/$(DEPDIR)/$(am__dirstamp) +src/readahead/sd-readahead.$(OBJEXT): src/readahead/$(am__dirstamp) \ + src/readahead/$(DEPDIR)/$(am__dirstamp) +systemd-notify$(EXEEXT): $(systemd_notify_OBJECTS) $(systemd_notify_DEPENDENCIES) $(EXTRA_systemd_notify_DEPENDENCIES) + @rm -f systemd-notify$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_notify_OBJECTS) $(systemd_notify_LDADD) $(LIBS) +src/nspawn.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/loopback-setup.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-nspawn$(EXEEXT): $(systemd_nspawn_OBJECTS) $(systemd_nspawn_DEPENDENCIES) $(EXTRA_systemd_nspawn_DEPENDENCIES) + @rm -f systemd-nspawn$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_nspawn_OBJECTS) $(systemd_nspawn_LDADD) $(LIBS) +src/quotacheck.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-quotacheck$(EXEEXT): $(systemd_quotacheck_OBJECTS) $(systemd_quotacheck_DEPENDENCIES) $(EXTRA_systemd_quotacheck_DEPENDENCIES) + @rm -f systemd-quotacheck$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_quotacheck_OBJECTS) $(systemd_quotacheck_LDADD) $(LIBS) +src/random-seed.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-random-seed$(EXEEXT): $(systemd_random_seed_OBJECTS) $(systemd_random_seed_DEPENDENCIES) $(EXTRA_systemd_random_seed_DEPENDENCIES) + @rm -f systemd-random-seed$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_random_seed_OBJECTS) $(systemd_random_seed_LDADD) $(LIBS) +src/rc-local-generator.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-rc-local-generator$(EXEEXT): $(systemd_rc_local_generator_OBJECTS) $(systemd_rc_local_generator_DEPENDENCIES) $(EXTRA_systemd_rc_local_generator_DEPENDENCIES) + @rm -f systemd-rc-local-generator$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_rc_local_generator_OBJECTS) $(systemd_rc_local_generator_LDADD) $(LIBS) +src/readahead/systemd_readahead_collect-readahead-collect.$(OBJEXT): \ + src/readahead/$(am__dirstamp) \ + src/readahead/$(DEPDIR)/$(am__dirstamp) +src/readahead/systemd_readahead_collect-readahead-common.$(OBJEXT): \ + src/readahead/$(am__dirstamp) \ + src/readahead/$(DEPDIR)/$(am__dirstamp) +systemd-readahead-collect$(EXEEXT): $(systemd_readahead_collect_OBJECTS) $(systemd_readahead_collect_DEPENDENCIES) $(EXTRA_systemd_readahead_collect_DEPENDENCIES) + @rm -f systemd-readahead-collect$(EXEEXT) + $(AM_V_CCLD)$(systemd_readahead_collect_LINK) $(systemd_readahead_collect_OBJECTS) $(systemd_readahead_collect_LDADD) $(LIBS) +src/readahead/systemd_readahead_replay-readahead-replay.$(OBJEXT): \ + src/readahead/$(am__dirstamp) \ + src/readahead/$(DEPDIR)/$(am__dirstamp) +src/readahead/systemd_readahead_replay-readahead-common.$(OBJEXT): \ + src/readahead/$(am__dirstamp) \ + src/readahead/$(DEPDIR)/$(am__dirstamp) +systemd-readahead-replay$(EXEEXT): $(systemd_readahead_replay_OBJECTS) $(systemd_readahead_replay_DEPENDENCIES) $(EXTRA_systemd_readahead_replay_DEPENDENCIES) + @rm -f systemd-readahead-replay$(EXEEXT) + $(AM_V_CCLD)$(systemd_readahead_replay_LINK) $(systemd_readahead_replay_OBJECTS) $(systemd_readahead_replay_LDADD) $(LIBS) +src/remount-api-vfs.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/mount-setup.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/exit-status.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-remount-api-vfs$(EXEEXT): $(systemd_remount_api_vfs_OBJECTS) $(systemd_remount_api_vfs_DEPENDENCIES) $(EXTRA_systemd_remount_api_vfs_DEPENDENCIES) + @rm -f systemd-remount-api-vfs$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_remount_api_vfs_OBJECTS) $(systemd_remount_api_vfs_LDADD) $(LIBS) +src/reply-password.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-reply-password$(EXEEXT): $(systemd_reply_password_OBJECTS) $(systemd_reply_password_DEPENDENCIES) $(EXTRA_systemd_reply_password_DEPENDENCIES) + @rm -f systemd-reply-password$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_reply_password_OBJECTS) $(systemd_reply_password_LDADD) $(LIBS) +src/systemd_shutdown-mount-setup.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_shutdown-umount.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_shutdown-shutdown.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-shutdown$(EXEEXT): $(systemd_shutdown_OBJECTS) $(systemd_shutdown_DEPENDENCIES) $(EXTRA_systemd_shutdown_DEPENDENCIES) + @rm -f systemd-shutdown$(EXEEXT) + $(AM_V_CCLD)$(systemd_shutdown_LINK) $(systemd_shutdown_OBJECTS) $(systemd_shutdown_LDADD) $(LIBS) +src/systemd_shutdownd-utmp-wtmp.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_shutdownd-shutdownd.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-shutdownd$(EXEEXT): $(systemd_shutdownd_OBJECTS) $(systemd_shutdownd_DEPENDENCIES) $(EXTRA_systemd_shutdownd_DEPENDENCIES) + @rm -f systemd-shutdownd$(EXEEXT) + $(AM_V_CCLD)$(systemd_shutdownd_LINK) $(systemd_shutdownd_OBJECTS) $(systemd_shutdownd_LDADD) $(LIBS) +src/bridge.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-stdio-bridge$(EXEEXT): $(systemd_stdio_bridge_OBJECTS) $(systemd_stdio_bridge_DEPENDENCIES) $(EXTRA_systemd_stdio_bridge_DEPENDENCIES) + @rm -f systemd-stdio-bridge$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_stdio_bridge_OBJECTS) $(systemd_stdio_bridge_LDADD) $(LIBS) +src/sysctl.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-sysctl$(EXEEXT): $(systemd_sysctl_OBJECTS) $(systemd_sysctl_DEPENDENCIES) $(EXTRA_systemd_sysctl_DEPENDENCIES) + @rm -f systemd-sysctl$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_sysctl_OBJECTS) $(systemd_sysctl_LDADD) $(LIBS) +src/timedate/$(am__dirstamp): + @$(MKDIR_P) src/timedate + @: > src/timedate/$(am__dirstamp) +src/timedate/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/timedate/$(DEPDIR) + @: > src/timedate/$(DEPDIR)/$(am__dirstamp) +src/timedate/systemd_timedated-timedated.$(OBJEXT): \ + src/timedate/$(am__dirstamp) \ + src/timedate/$(DEPDIR)/$(am__dirstamp) +src/systemd_timedated-dbus-common.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_timedated-polkit.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-timedated$(EXEEXT): $(systemd_timedated_OBJECTS) $(systemd_timedated_DEPENDENCIES) $(EXTRA_systemd_timedated_DEPENDENCIES) + @rm -f systemd-timedated$(EXEEXT) + $(AM_V_CCLD)$(systemd_timedated_LINK) $(systemd_timedated_OBJECTS) $(systemd_timedated_LDADD) $(LIBS) +src/timestamp.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-timestamp$(EXEEXT): $(systemd_timestamp_OBJECTS) $(systemd_timestamp_DEPENDENCIES) $(EXTRA_systemd_timestamp_DEPENDENCIES) + @rm -f systemd-timestamp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_timestamp_OBJECTS) $(systemd_timestamp_LDADD) $(LIBS) +src/tmpfiles.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-tmpfiles$(EXEEXT): $(systemd_tmpfiles_OBJECTS) $(systemd_tmpfiles_DEPENDENCIES) $(EXTRA_systemd_tmpfiles_DEPENDENCIES) + @rm -f systemd-tmpfiles$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_tmpfiles_OBJECTS) $(systemd_tmpfiles_LDADD) $(LIBS) +src/tty-ask-password-agent.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/utmp-wtmp.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-tty-ask-password-agent$(EXEEXT): $(systemd_tty_ask_password_agent_OBJECTS) $(systemd_tty_ask_password_agent_DEPENDENCIES) $(EXTRA_systemd_tty_ask_password_agent_DEPENDENCIES) + @rm -f systemd-tty-ask-password-agent$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_tty_ask_password_agent_OBJECTS) $(systemd_tty_ask_password_agent_LDADD) $(LIBS) +src/login/systemd_uaccess-uaccess.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +src/login/systemd_uaccess-logind-acl.$(OBJEXT): \ + src/login/$(am__dirstamp) src/login/$(DEPDIR)/$(am__dirstamp) +src/systemd_uaccess-acl-util.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-uaccess$(EXEEXT): $(systemd_uaccess_OBJECTS) $(systemd_uaccess_DEPENDENCIES) $(EXTRA_systemd_uaccess_DEPENDENCIES) + @rm -f systemd-uaccess$(EXEEXT) + $(AM_V_CCLD)$(systemd_uaccess_LINK) $(systemd_uaccess_OBJECTS) $(systemd_uaccess_LDADD) $(LIBS) +src/systemd_update_utmp-update-utmp.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_update_utmp-dbus-common.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/systemd_update_utmp-utmp-wtmp.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +systemd-update-utmp$(EXEEXT): $(systemd_update_utmp_OBJECTS) $(systemd_update_utmp_DEPENDENCIES) $(EXTRA_systemd_update_utmp_DEPENDENCIES) + @rm -f systemd-update-utmp$(EXEEXT) + $(AM_V_CCLD)$(systemd_update_utmp_LINK) $(systemd_update_utmp_OBJECTS) $(systemd_update_utmp_LDADD) $(LIBS) +src/login/user-sessions.$(OBJEXT): src/login/$(am__dirstamp) \ + src/login/$(DEPDIR)/$(am__dirstamp) +systemd-user-sessions$(EXEEXT): $(systemd_user_sessions_OBJECTS) $(systemd_user_sessions_DEPENDENCIES) $(EXTRA_systemd_user_sessions_DEPENDENCIES) + @rm -f systemd-user-sessions$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_user_sessions_OBJECTS) $(systemd_user_sessions_LDADD) $(LIBS) +src/vconsole/$(am__dirstamp): + @$(MKDIR_P) src/vconsole + @: > src/vconsole/$(am__dirstamp) +src/vconsole/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/vconsole/$(DEPDIR) + @: > src/vconsole/$(DEPDIR)/$(am__dirstamp) +src/vconsole/vconsole-setup.$(OBJEXT): src/vconsole/$(am__dirstamp) \ + src/vconsole/$(DEPDIR)/$(am__dirstamp) +systemd-vconsole-setup$(EXEEXT): $(systemd_vconsole_setup_OBJECTS) $(systemd_vconsole_setup_DEPENDENCIES) $(EXTRA_systemd_vconsole_setup_DEPENDENCIES) + @rm -f systemd-vconsole-setup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(systemd_vconsole_setup_OBJECTS) $(systemd_vconsole_setup_LDADD) $(LIBS) +src/test-cgroup.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +test-cgroup$(EXEEXT): $(test_cgroup_OBJECTS) $(test_cgroup_DEPENDENCIES) $(EXTRA_test_cgroup_DEPENDENCIES) + @rm -f test-cgroup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_cgroup_OBJECTS) $(test_cgroup_LDADD) $(LIBS) +src/test-daemon.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +test-daemon$(EXEEXT): $(test_daemon_OBJECTS) $(test_daemon_DEPENDENCIES) $(EXTRA_test_daemon_DEPENDENCIES) + @rm -f test-daemon$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_daemon_OBJECTS) $(test_daemon_LDADD) $(LIBS) +src/test_engine-test-engine.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +test-engine$(EXEEXT): $(test_engine_OBJECTS) $(test_engine_DEPENDENCIES) $(EXTRA_test_engine_DEPENDENCIES) + @rm -f test-engine$(EXEEXT) + $(AM_V_CCLD)$(test_engine_LINK) $(test_engine_OBJECTS) $(test_engine_LDADD) $(LIBS) +src/test-env-replace.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +test-env-replace$(EXEEXT): $(test_env_replace_OBJECTS) $(test_env_replace_DEPENDENCIES) $(EXTRA_test_env_replace_DEPENDENCIES) + @rm -f test-env-replace$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_env_replace_OBJECTS) $(test_env_replace_LDADD) $(LIBS) +src/test-hostname.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/hostname-setup.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +test-hostname$(EXEEXT): $(test_hostname_OBJECTS) $(test_hostname_DEPENDENCIES) $(EXTRA_test_hostname_DEPENDENCIES) + @rm -f test-hostname$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_hostname_OBJECTS) $(test_hostname_LDADD) $(LIBS) +src/test-id128.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +test-id128$(EXEEXT): $(test_id128_OBJECTS) $(test_id128_DEPENDENCIES) $(EXTRA_test_id128_DEPENDENCIES) + @rm -f test-id128$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_id128_OBJECTS) $(test_id128_LDADD) $(LIBS) +src/test_install-test-install.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/test_install-install.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/test_install-path-lookup.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/test_install-unit-name.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +test-install$(EXEEXT): $(test_install_OBJECTS) $(test_install_DEPENDENCIES) $(EXTRA_test_install_DEPENDENCIES) + @rm -f test-install$(EXEEXT) + $(AM_V_CCLD)$(test_install_LINK) $(test_install_OBJECTS) $(test_install_LDADD) $(LIBS) +src/test_job_type-test-job-type.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +test-job-type$(EXEEXT): $(test_job_type_OBJECTS) $(test_job_type_DEPENDENCIES) $(EXTRA_test_job_type_DEPENDENCIES) + @rm -f test-job-type$(EXEEXT) + $(AM_V_CCLD)$(test_job_type_LINK) $(test_job_type_OBJECTS) $(test_job_type_LDADD) $(LIBS) +src/journal/test_journal-test-journal.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/journal/test_journal-sd-journal.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/journal/test_journal-journal-file.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/journal/test_journal-lookup3.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/journal/test_journal-journal-send.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +src/test_journal-sd-id128.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/journal/test_journal-compress.$(OBJEXT): \ + src/journal/$(am__dirstamp) \ + src/journal/$(DEPDIR)/$(am__dirstamp) +test-journal$(EXEEXT): $(test_journal_OBJECTS) $(test_journal_DEPENDENCIES) $(EXTRA_test_journal_DEPENDENCIES) + @rm -f test-journal$(EXEEXT) + $(AM_V_CCLD)$(test_journal_LINK) $(test_journal_OBJECTS) $(test_journal_LDADD) $(LIBS) +src/login/test-login.$(OBJEXT): src/login/$(am__dirstamp) \ + src/login/$(DEPDIR)/$(am__dirstamp) +test-login$(EXEEXT): $(test_login_OBJECTS) $(test_login_DEPENDENCIES) $(EXTRA_test_login_DEPENDENCIES) + @rm -f test-login$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_login_OBJECTS) $(test_login_LDADD) $(LIBS) +src/test-loopback.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +test-loopback$(EXEEXT): $(test_loopback_OBJECTS) $(test_loopback_DEPENDENCIES) $(EXTRA_test_loopback_DEPENDENCIES) + @rm -f test-loopback$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_loopback_OBJECTS) $(test_loopback_LDADD) $(LIBS) +src/test_ns-test-ns.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +test-ns$(EXEEXT): $(test_ns_OBJECTS) $(test_ns_DEPENDENCIES) $(EXTRA_test_ns_DEPENDENCIES) + @rm -f test-ns$(EXEEXT) + $(AM_V_CCLD)$(test_ns_LINK) $(test_ns_OBJECTS) $(test_ns_LDADD) $(LIBS) +src/test-strv.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/specifier.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +test-strv$(EXEEXT): $(test_strv_OBJECTS) $(test_strv_DEPENDENCIES) $(EXTRA_test_strv_DEPENDENCIES) + @rm -f test-strv$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_strv_OBJECTS) $(test_strv_LDADD) $(LIBS) +install-dist_binSCRIPTS: $(dist_bin_SCRIPTS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-dist_binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f src/ask-password-api.$(OBJEXT) + -rm -f src/ask-password.$(OBJEXT) + -rm -f src/binfmt/binfmt.$(OBJEXT) + -rm -f src/bridge.$(OBJEXT) + -rm -f src/cgls.$(OBJEXT) + -rm -f src/cgroup-show.$(OBJEXT) + -rm -f src/cgroup-util.$(OBJEXT) + -rm -f src/cgtop.$(OBJEXT) + -rm -f src/cryptsetup/cryptsetup-generator.$(OBJEXT) + -rm -f src/cryptsetup/systemd_cryptsetup-cryptsetup.$(OBJEXT) + -rm -f src/detect-virt.$(OBJEXT) + -rm -f src/exit-status.$(OBJEXT) + -rm -f src/getty-generator.$(OBJEXT) + -rm -f src/hostname-setup.$(OBJEXT) + -rm -f src/hostname/systemd_hostnamed-hostnamed.$(OBJEXT) + -rm -f src/journal/cat.$(OBJEXT) + -rm -f src/journal/coredump.$(OBJEXT) + -rm -f src/journal/libsystemd_journal_la-compress.$(OBJEXT) + -rm -f src/journal/libsystemd_journal_la-compress.lo + -rm -f src/journal/libsystemd_journal_la-journal-file.$(OBJEXT) + -rm -f src/journal/libsystemd_journal_la-journal-file.lo + -rm -f src/journal/libsystemd_journal_la-journal-send.$(OBJEXT) + -rm -f src/journal/libsystemd_journal_la-journal-send.lo + -rm -f src/journal/libsystemd_journal_la-lookup3.$(OBJEXT) + -rm -f src/journal/libsystemd_journal_la-lookup3.lo + -rm -f src/journal/libsystemd_journal_la-sd-journal.$(OBJEXT) + -rm -f src/journal/libsystemd_journal_la-sd-journal.lo + -rm -f src/journal/systemd_journalctl-compress.$(OBJEXT) + -rm -f src/journal/systemd_journalctl-journalctl.$(OBJEXT) + -rm -f src/journal/systemd_journald-compress.$(OBJEXT) + -rm -f src/journal/systemd_journald-journal-file.$(OBJEXT) + -rm -f src/journal/systemd_journald-journal-rate-limit.$(OBJEXT) + -rm -f src/journal/systemd_journald-journald-gperf.$(OBJEXT) + -rm -f src/journal/systemd_journald-journald.$(OBJEXT) + -rm -f src/journal/systemd_journald-lookup3.$(OBJEXT) + -rm -f src/journal/systemd_journald-sd-journal.$(OBJEXT) + -rm -f src/journal/test_journal-compress.$(OBJEXT) + -rm -f src/journal/test_journal-journal-file.$(OBJEXT) + -rm -f src/journal/test_journal-journal-send.$(OBJEXT) + -rm -f src/journal/test_journal-lookup3.$(OBJEXT) + -rm -f src/journal/test_journal-sd-journal.$(OBJEXT) + -rm -f src/journal/test_journal-test-journal.$(OBJEXT) + -rm -f src/libsystemd_basic_la-conf-parser.$(OBJEXT) + -rm -f src/libsystemd_basic_la-conf-parser.lo + -rm -f src/libsystemd_basic_la-exit-status.$(OBJEXT) + -rm -f src/libsystemd_basic_la-exit-status.lo + -rm -f src/libsystemd_basic_la-hashmap.$(OBJEXT) + -rm -f src/libsystemd_basic_la-hashmap.lo + -rm -f src/libsystemd_basic_la-label.$(OBJEXT) + -rm -f src/libsystemd_basic_la-label.lo + -rm -f src/libsystemd_basic_la-log.$(OBJEXT) + -rm -f src/libsystemd_basic_la-log.lo + -rm -f src/libsystemd_basic_la-ratelimit.$(OBJEXT) + -rm -f src/libsystemd_basic_la-ratelimit.lo + -rm -f src/libsystemd_basic_la-set.$(OBJEXT) + -rm -f src/libsystemd_basic_la-set.lo + -rm -f src/libsystemd_basic_la-socket-util.$(OBJEXT) + -rm -f src/libsystemd_basic_la-socket-util.lo + -rm -f src/libsystemd_basic_la-strv.$(OBJEXT) + -rm -f src/libsystemd_basic_la-strv.lo + -rm -f src/libsystemd_basic_la-util.$(OBJEXT) + -rm -f src/libsystemd_basic_la-util.lo + -rm -f src/libsystemd_basic_la-virt.$(OBJEXT) + -rm -f src/libsystemd_basic_la-virt.lo + -rm -f src/libsystemd_core_la-automount.$(OBJEXT) + -rm -f src/libsystemd_core_la-automount.lo + -rm -f src/libsystemd_core_la-cgroup-attr.$(OBJEXT) + -rm -f src/libsystemd_core_la-cgroup-attr.lo + -rm -f src/libsystemd_core_la-cgroup-util.$(OBJEXT) + -rm -f src/libsystemd_core_la-cgroup-util.lo + -rm -f src/libsystemd_core_la-cgroup.$(OBJEXT) + -rm -f src/libsystemd_core_la-cgroup.lo + -rm -f src/libsystemd_core_la-condition.$(OBJEXT) + -rm -f src/libsystemd_core_la-condition.lo + -rm -f src/libsystemd_core_la-dbus-automount.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-automount.lo + -rm -f src/libsystemd_core_la-dbus-common.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-common.lo + -rm -f src/libsystemd_core_la-dbus-device.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-device.lo + -rm -f src/libsystemd_core_la-dbus-execute.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-execute.lo + -rm -f src/libsystemd_core_la-dbus-job.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-job.lo + -rm -f src/libsystemd_core_la-dbus-manager.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-manager.lo + -rm -f src/libsystemd_core_la-dbus-mount.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-mount.lo + -rm -f src/libsystemd_core_la-dbus-path.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-path.lo + -rm -f src/libsystemd_core_la-dbus-service.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-service.lo + -rm -f src/libsystemd_core_la-dbus-snapshot.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-snapshot.lo + -rm -f src/libsystemd_core_la-dbus-socket.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-socket.lo + -rm -f src/libsystemd_core_la-dbus-swap.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-swap.lo + -rm -f src/libsystemd_core_la-dbus-target.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-target.lo + -rm -f src/libsystemd_core_la-dbus-timer.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-timer.lo + -rm -f src/libsystemd_core_la-dbus-unit.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus-unit.lo + -rm -f src/libsystemd_core_la-dbus.$(OBJEXT) + -rm -f src/libsystemd_core_la-dbus.lo + -rm -f src/libsystemd_core_la-device.$(OBJEXT) + -rm -f src/libsystemd_core_la-device.lo + -rm -f src/libsystemd_core_la-execute.$(OBJEXT) + -rm -f src/libsystemd_core_la-execute.lo + -rm -f src/libsystemd_core_la-fdset.$(OBJEXT) + -rm -f src/libsystemd_core_la-fdset.lo + -rm -f src/libsystemd_core_la-hostname-setup.$(OBJEXT) + -rm -f src/libsystemd_core_la-hostname-setup.lo + -rm -f src/libsystemd_core_la-install.$(OBJEXT) + -rm -f src/libsystemd_core_la-install.lo + -rm -f src/libsystemd_core_la-job.$(OBJEXT) + -rm -f src/libsystemd_core_la-job.lo + -rm -f src/libsystemd_core_la-kmod-setup.$(OBJEXT) + -rm -f src/libsystemd_core_la-kmod-setup.lo + -rm -f src/libsystemd_core_la-load-dropin.$(OBJEXT) + -rm -f src/libsystemd_core_la-load-dropin.lo + -rm -f src/libsystemd_core_la-load-fragment-gperf-nulstr.$(OBJEXT) + -rm -f src/libsystemd_core_la-load-fragment-gperf-nulstr.lo + -rm -f src/libsystemd_core_la-load-fragment-gperf.$(OBJEXT) + -rm -f src/libsystemd_core_la-load-fragment-gperf.lo + -rm -f src/libsystemd_core_la-load-fragment.$(OBJEXT) + -rm -f src/libsystemd_core_la-load-fragment.lo + -rm -f src/libsystemd_core_la-locale-setup.$(OBJEXT) + -rm -f src/libsystemd_core_la-locale-setup.lo + -rm -f src/libsystemd_core_la-loopback-setup.$(OBJEXT) + -rm -f src/libsystemd_core_la-loopback-setup.lo + -rm -f src/libsystemd_core_la-machine-id-setup.$(OBJEXT) + -rm -f src/libsystemd_core_la-machine-id-setup.lo + -rm -f src/libsystemd_core_la-manager.$(OBJEXT) + -rm -f src/libsystemd_core_la-manager.lo + -rm -f src/libsystemd_core_la-mount-setup.$(OBJEXT) + -rm -f src/libsystemd_core_la-mount-setup.lo + -rm -f src/libsystemd_core_la-mount.$(OBJEXT) + -rm -f src/libsystemd_core_la-mount.lo + -rm -f src/libsystemd_core_la-namespace.$(OBJEXT) + -rm -f src/libsystemd_core_la-namespace.lo + -rm -f src/libsystemd_core_la-path-lookup.$(OBJEXT) + -rm -f src/libsystemd_core_la-path-lookup.lo + -rm -f src/libsystemd_core_la-path.$(OBJEXT) + -rm -f src/libsystemd_core_la-path.lo + -rm -f src/libsystemd_core_la-sd-daemon.$(OBJEXT) + -rm -f src/libsystemd_core_la-sd-daemon.lo + -rm -f src/libsystemd_core_la-sd-id128.$(OBJEXT) + -rm -f src/libsystemd_core_la-sd-id128.lo + -rm -f src/libsystemd_core_la-selinux-setup.$(OBJEXT) + -rm -f src/libsystemd_core_la-selinux-setup.lo + -rm -f src/libsystemd_core_la-service.$(OBJEXT) + -rm -f src/libsystemd_core_la-service.lo + -rm -f src/libsystemd_core_la-snapshot.$(OBJEXT) + -rm -f src/libsystemd_core_la-snapshot.lo + -rm -f src/libsystemd_core_la-socket.$(OBJEXT) + -rm -f src/libsystemd_core_la-socket.lo + -rm -f src/libsystemd_core_la-specifier.$(OBJEXT) + -rm -f src/libsystemd_core_la-specifier.lo + -rm -f src/libsystemd_core_la-swap.$(OBJEXT) + -rm -f src/libsystemd_core_la-swap.lo + -rm -f src/libsystemd_core_la-target.$(OBJEXT) + -rm -f src/libsystemd_core_la-target.lo + -rm -f src/libsystemd_core_la-tcpwrap.$(OBJEXT) + -rm -f src/libsystemd_core_la-tcpwrap.lo + -rm -f src/libsystemd_core_la-timer.$(OBJEXT) + -rm -f src/libsystemd_core_la-timer.lo + -rm -f src/libsystemd_core_la-unit-name.$(OBJEXT) + -rm -f src/libsystemd_core_la-unit-name.lo + -rm -f src/libsystemd_core_la-unit.$(OBJEXT) + -rm -f src/libsystemd_core_la-unit.lo + -rm -f src/libsystemd_core_la-utmp-wtmp.$(OBJEXT) + -rm -f src/libsystemd_core_la-utmp-wtmp.lo + -rm -f src/libsystemd_daemon_la-sd-daemon.$(OBJEXT) + -rm -f src/libsystemd_daemon_la-sd-daemon.lo + -rm -f src/libsystemd_id128_la-sd-id128.$(OBJEXT) + -rm -f src/libsystemd_id128_la-sd-id128.lo + -rm -f src/libsystemd_login_la-cgroup-util.$(OBJEXT) + -rm -f src/libsystemd_login_la-cgroup-util.lo + -rm -f src/locale/systemd_localed-localed.$(OBJEXT) + -rm -f src/login/libsystemd_login_la-sd-login.$(OBJEXT) + -rm -f src/login/libsystemd_login_la-sd-login.lo + -rm -f src/login/pam_systemd_la-pam-module.$(OBJEXT) + -rm -f src/login/pam_systemd_la-pam-module.lo + -rm -f src/login/systemd_loginctl-loginctl.$(OBJEXT) + -rm -f src/login/systemd_loginctl-sysfs-show.$(OBJEXT) + -rm -f src/login/systemd_logind-logind-acl.$(OBJEXT) + -rm -f src/login/systemd_logind-logind-dbus.$(OBJEXT) + -rm -f src/login/systemd_logind-logind-device.$(OBJEXT) + -rm -f src/login/systemd_logind-logind-gperf.$(OBJEXT) + -rm -f src/login/systemd_logind-logind-seat-dbus.$(OBJEXT) + -rm -f src/login/systemd_logind-logind-seat.$(OBJEXT) + -rm -f src/login/systemd_logind-logind-session-dbus.$(OBJEXT) + -rm -f src/login/systemd_logind-logind-session.$(OBJEXT) + -rm -f src/login/systemd_logind-logind-user-dbus.$(OBJEXT) + -rm -f src/login/systemd_logind-logind-user.$(OBJEXT) + -rm -f src/login/systemd_logind-logind.$(OBJEXT) + -rm -f src/login/systemd_multi_seat_x-multi-seat-x.$(OBJEXT) + -rm -f src/login/systemd_uaccess-logind-acl.$(OBJEXT) + -rm -f src/login/systemd_uaccess-uaccess.$(OBJEXT) + -rm -f src/login/test-login.$(OBJEXT) + -rm -f src/login/user-sessions.$(OBJEXT) + -rm -f src/loopback-setup.$(OBJEXT) + -rm -f src/machine-id-main.$(OBJEXT) + -rm -f src/machine-id-setup.$(OBJEXT) + -rm -f src/mount-setup.$(OBJEXT) + -rm -f src/notify.$(OBJEXT) + -rm -f src/nspawn.$(OBJEXT) + -rm -f src/pager.$(OBJEXT) + -rm -f src/pam_systemd_la-dbus-common.$(OBJEXT) + -rm -f src/pam_systemd_la-dbus-common.lo + -rm -f src/quotacheck.$(OBJEXT) + -rm -f src/random-seed.$(OBJEXT) + -rm -f src/rc-local-generator.$(OBJEXT) + -rm -f src/readahead/sd-readahead.$(OBJEXT) + -rm -f src/readahead/systemd_readahead_collect-readahead-collect.$(OBJEXT) + -rm -f src/readahead/systemd_readahead_collect-readahead-common.$(OBJEXT) + -rm -f src/readahead/systemd_readahead_replay-readahead-common.$(OBJEXT) + -rm -f src/readahead/systemd_readahead_replay-readahead-replay.$(OBJEXT) + -rm -f src/remount-api-vfs.$(OBJEXT) + -rm -f src/reply-password.$(OBJEXT) + -rm -f src/sd-id128.$(OBJEXT) + -rm -f src/specifier.$(OBJEXT) + -rm -f src/sysctl.$(OBJEXT) + -rm -f src/systemadm-systemadm.$(OBJEXT) + -rm -f src/systemadm-systemd-interfaces.$(OBJEXT) + -rm -f src/systemadm-wraplabel.$(OBJEXT) + -rm -f src/systemctl-cgroup-show.$(OBJEXT) + -rm -f src/systemctl-cgroup-util.$(OBJEXT) + -rm -f src/systemctl-dbus-common.$(OBJEXT) + -rm -f src/systemctl-exit-status.$(OBJEXT) + -rm -f src/systemctl-install.$(OBJEXT) + -rm -f src/systemctl-logs-show.$(OBJEXT) + -rm -f src/systemctl-pager.$(OBJEXT) + -rm -f src/systemctl-path-lookup.$(OBJEXT) + -rm -f src/systemctl-spawn-agent.$(OBJEXT) + -rm -f src/systemctl-systemctl.$(OBJEXT) + -rm -f src/systemctl-unit-name.$(OBJEXT) + -rm -f src/systemctl-utmp-wtmp.$(OBJEXT) + -rm -f src/systemd-main.$(OBJEXT) + -rm -f src/systemd_ac_power-ac-power.$(OBJEXT) + -rm -f src/systemd_cgroups_agent-cgroups-agent.$(OBJEXT) + -rm -f src/systemd_cgroups_agent-dbus-common.$(OBJEXT) + -rm -f src/systemd_cryptsetup-ask-password-api.$(OBJEXT) + -rm -f src/systemd_fsck-dbus-common.$(OBJEXT) + -rm -f src/systemd_fsck-fsck.$(OBJEXT) + -rm -f src/systemd_gnome_ask_password_agent-gnome-ask-password-agent.$(OBJEXT) + -rm -f src/systemd_hostnamed-dbus-common.$(OBJEXT) + -rm -f src/systemd_hostnamed-polkit.$(OBJEXT) + -rm -f src/systemd_initctl-dbus-common.$(OBJEXT) + -rm -f src/systemd_initctl-initctl.$(OBJEXT) + -rm -f src/systemd_journalctl-logs-show.$(OBJEXT) + -rm -f src/systemd_journalctl-pager.$(OBJEXT) + -rm -f src/systemd_journald-acl-util.$(OBJEXT) + -rm -f src/systemd_journald-cgroup-util.$(OBJEXT) + -rm -f src/systemd_journald-sd-id128.$(OBJEXT) + -rm -f src/systemd_localed-dbus-common.$(OBJEXT) + -rm -f src/systemd_localed-polkit.$(OBJEXT) + -rm -f src/systemd_loginctl-cgroup-show.$(OBJEXT) + -rm -f src/systemd_loginctl-cgroup-util.$(OBJEXT) + -rm -f src/systemd_loginctl-dbus-common.$(OBJEXT) + -rm -f src/systemd_loginctl-pager.$(OBJEXT) + -rm -f src/systemd_logind-acl-util.$(OBJEXT) + -rm -f src/systemd_logind-cgroup-util.$(OBJEXT) + -rm -f src/systemd_logind-dbus-common.$(OBJEXT) + -rm -f src/systemd_logind-dbus-loop.$(OBJEXT) + -rm -f src/systemd_logind-polkit.$(OBJEXT) + -rm -f src/systemd_modules_load-modules-load.$(OBJEXT) + -rm -f src/systemd_shutdown-mount-setup.$(OBJEXT) + -rm -f src/systemd_shutdown-shutdown.$(OBJEXT) + -rm -f src/systemd_shutdown-umount.$(OBJEXT) + -rm -f src/systemd_shutdownd-shutdownd.$(OBJEXT) + -rm -f src/systemd_shutdownd-utmp-wtmp.$(OBJEXT) + -rm -f src/systemd_timedated-dbus-common.$(OBJEXT) + -rm -f src/systemd_timedated-polkit.$(OBJEXT) + -rm -f src/systemd_uaccess-acl-util.$(OBJEXT) + -rm -f src/systemd_update_utmp-dbus-common.$(OBJEXT) + -rm -f src/systemd_update_utmp-update-utmp.$(OBJEXT) + -rm -f src/systemd_update_utmp-utmp-wtmp.$(OBJEXT) + -rm -f src/test-cgroup.$(OBJEXT) + -rm -f src/test-daemon.$(OBJEXT) + -rm -f src/test-env-replace.$(OBJEXT) + -rm -f src/test-hostname.$(OBJEXT) + -rm -f src/test-id128.$(OBJEXT) + -rm -f src/test-loopback.$(OBJEXT) + -rm -f src/test-strv.$(OBJEXT) + -rm -f src/test_engine-test-engine.$(OBJEXT) + -rm -f src/test_install-install.$(OBJEXT) + -rm -f src/test_install-path-lookup.$(OBJEXT) + -rm -f src/test_install-test-install.$(OBJEXT) + -rm -f src/test_install-unit-name.$(OBJEXT) + -rm -f src/test_job_type-test-job-type.$(OBJEXT) + -rm -f src/test_journal-sd-id128.$(OBJEXT) + -rm -f src/test_ns-test-ns.$(OBJEXT) + -rm -f src/timedate/systemd_timedated-timedated.$(OBJEXT) + -rm -f src/timestamp.$(OBJEXT) + -rm -f src/tmpfiles.$(OBJEXT) + -rm -f src/tty-ask-password-agent.$(OBJEXT) + -rm -f src/unit-name.$(OBJEXT) + -rm -f src/utmp-wtmp.$(OBJEXT) + -rm -f src/vconsole/vconsole-setup.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ask-password-api.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ask-password.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/bridge.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/cgls.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/cgroup-show.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/cgroup-util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/cgtop.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/detect-virt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/exit-status.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/getty-generator.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/hostname-setup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_basic_la-conf-parser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_basic_la-exit-status.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_basic_la-hashmap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_basic_la-label.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_basic_la-log.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_basic_la-ratelimit.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_basic_la-set.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_basic_la-socket-util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_basic_la-strv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_basic_la-util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_basic_la-virt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-automount.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-cgroup-attr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-cgroup-util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-cgroup.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-condition.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-automount.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-common.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-device.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-execute.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-job.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-mount.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-path.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-service.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-snapshot.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-socket.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-swap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-target.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-timer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus-unit.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-dbus.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-device.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-execute.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-fdset.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-hostname-setup.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-install.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-job.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-kmod-setup.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-load-dropin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-load-fragment-gperf-nulstr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-load-fragment-gperf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-load-fragment.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-locale-setup.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-loopback-setup.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-machine-id-setup.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-mount-setup.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-mount.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-namespace.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-path-lookup.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-path.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-sd-daemon.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-sd-id128.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-selinux-setup.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-service.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-snapshot.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-socket.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-specifier.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-swap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-target.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-tcpwrap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-timer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-unit-name.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-unit.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_core_la-utmp-wtmp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_daemon_la-sd-daemon.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_id128_la-sd-id128.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/libsystemd_login_la-cgroup-util.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/loopback-setup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/machine-id-main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/machine-id-setup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/mount-setup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/notify.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/nspawn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pam_systemd_la-dbus-common.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/quotacheck.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/random-seed.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/rc-local-generator.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/remount-api-vfs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/reply-password.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/sd-id128.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/specifier.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/sysctl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemadm-systemadm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemadm-systemd-interfaces.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemadm-wraplabel.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemctl-cgroup-show.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemctl-cgroup-util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemctl-dbus-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemctl-exit-status.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemctl-install.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemctl-logs-show.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemctl-pager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemctl-path-lookup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemctl-spawn-agent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemctl-systemctl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemctl-unit-name.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemctl-utmp-wtmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd-main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_ac_power-ac-power.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_cgroups_agent-cgroups-agent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_cgroups_agent-dbus-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_cryptsetup-ask-password-api.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_fsck-dbus-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_fsck-fsck.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_gnome_ask_password_agent-gnome-ask-password-agent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_hostnamed-dbus-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_hostnamed-polkit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_initctl-dbus-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_initctl-initctl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_journalctl-logs-show.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_journalctl-pager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_journald-acl-util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_journald-cgroup-util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_journald-sd-id128.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_localed-dbus-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_localed-polkit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_loginctl-cgroup-show.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_loginctl-cgroup-util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_loginctl-dbus-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_loginctl-pager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_logind-acl-util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_logind-cgroup-util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_logind-dbus-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_logind-dbus-loop.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_logind-polkit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_modules_load-modules-load.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_shutdown-mount-setup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_shutdown-shutdown.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_shutdown-umount.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_shutdownd-shutdownd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_shutdownd-utmp-wtmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_timedated-dbus-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_timedated-polkit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_uaccess-acl-util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_update_utmp-dbus-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_update_utmp-update-utmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/systemd_update_utmp-utmp-wtmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test-cgroup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test-daemon.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test-env-replace.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test-hostname.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test-id128.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test-loopback.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test-strv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_engine-test-engine.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_install-install.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_install-path-lookup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_install-test-install.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_install-unit-name.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_job_type-test-job-type.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_journal-sd-id128.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/test_ns-test-ns.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/timestamp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/tmpfiles.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/tty-ask-password-agent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/unit-name.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/utmp-wtmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/binfmt/$(DEPDIR)/binfmt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/cryptsetup/$(DEPDIR)/cryptsetup-generator.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/cryptsetup/$(DEPDIR)/systemd_cryptsetup-cryptsetup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/hostname/$(DEPDIR)/systemd_hostnamed-hostnamed.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/cat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/coredump.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/libsystemd_journal_la-compress.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/libsystemd_journal_la-journal-file.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/libsystemd_journal_la-journal-send.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/libsystemd_journal_la-lookup3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/libsystemd_journal_la-sd-journal.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/systemd_journalctl-compress.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/systemd_journalctl-journalctl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/systemd_journald-compress.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/systemd_journald-journal-file.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/systemd_journald-journal-rate-limit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/systemd_journald-journald-gperf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/systemd_journald-journald.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/systemd_journald-lookup3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/systemd_journald-sd-journal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/test_journal-compress.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/test_journal-journal-file.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/test_journal-journal-send.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/test_journal-lookup3.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/test_journal-sd-journal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/journal/$(DEPDIR)/test_journal-test-journal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/locale/$(DEPDIR)/systemd_localed-localed.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/libsystemd_login_la-sd-login.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/pam_systemd_la-pam-module.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_loginctl-loginctl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_loginctl-sysfs-show.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_logind-logind-acl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_logind-logind-dbus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_logind-logind-device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_logind-logind-gperf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_logind-logind-seat-dbus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_logind-logind-seat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_logind-logind-session-dbus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_logind-logind-session.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_logind-logind-user-dbus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_logind-logind-user.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_logind-logind.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_multi_seat_x-multi-seat-x.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_uaccess-logind-acl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/systemd_uaccess-uaccess.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/test-login.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/login/$(DEPDIR)/user-sessions.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/readahead/$(DEPDIR)/sd-readahead.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/readahead/$(DEPDIR)/systemd_readahead_collect-readahead-collect.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/readahead/$(DEPDIR)/systemd_readahead_collect-readahead-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/readahead/$(DEPDIR)/systemd_readahead_replay-readahead-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/readahead/$(DEPDIR)/systemd_readahead_replay-readahead-replay.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/timedate/$(DEPDIR)/systemd_timedated-timedated.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/vconsole/$(DEPDIR)/vconsole-setup.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +src/libsystemd_basic_la-util.lo: src/util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_basic_la-util.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_basic_la-util.Tpo -c -o src/libsystemd_basic_la-util.lo `test -f 'src/util.c' || echo '$(srcdir)/'`src/util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_basic_la-util.Tpo src/$(DEPDIR)/libsystemd_basic_la-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util.c' object='src/libsystemd_basic_la-util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_basic_la-util.lo `test -f 'src/util.c' || echo '$(srcdir)/'`src/util.c + +src/libsystemd_basic_la-virt.lo: src/virt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_basic_la-virt.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_basic_la-virt.Tpo -c -o src/libsystemd_basic_la-virt.lo `test -f 'src/virt.c' || echo '$(srcdir)/'`src/virt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_basic_la-virt.Tpo src/$(DEPDIR)/libsystemd_basic_la-virt.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/virt.c' object='src/libsystemd_basic_la-virt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_basic_la-virt.lo `test -f 'src/virt.c' || echo '$(srcdir)/'`src/virt.c + +src/libsystemd_basic_la-label.lo: src/label.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_basic_la-label.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_basic_la-label.Tpo -c -o src/libsystemd_basic_la-label.lo `test -f 'src/label.c' || echo '$(srcdir)/'`src/label.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_basic_la-label.Tpo src/$(DEPDIR)/libsystemd_basic_la-label.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/label.c' object='src/libsystemd_basic_la-label.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_basic_la-label.lo `test -f 'src/label.c' || echo '$(srcdir)/'`src/label.c + +src/libsystemd_basic_la-hashmap.lo: src/hashmap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_basic_la-hashmap.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_basic_la-hashmap.Tpo -c -o src/libsystemd_basic_la-hashmap.lo `test -f 'src/hashmap.c' || echo '$(srcdir)/'`src/hashmap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_basic_la-hashmap.Tpo src/$(DEPDIR)/libsystemd_basic_la-hashmap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/hashmap.c' object='src/libsystemd_basic_la-hashmap.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_basic_la-hashmap.lo `test -f 'src/hashmap.c' || echo '$(srcdir)/'`src/hashmap.c + +src/libsystemd_basic_la-set.lo: src/set.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_basic_la-set.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_basic_la-set.Tpo -c -o src/libsystemd_basic_la-set.lo `test -f 'src/set.c' || echo '$(srcdir)/'`src/set.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_basic_la-set.Tpo src/$(DEPDIR)/libsystemd_basic_la-set.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/set.c' object='src/libsystemd_basic_la-set.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_basic_la-set.lo `test -f 'src/set.c' || echo '$(srcdir)/'`src/set.c + +src/libsystemd_basic_la-strv.lo: src/strv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_basic_la-strv.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_basic_la-strv.Tpo -c -o src/libsystemd_basic_la-strv.lo `test -f 'src/strv.c' || echo '$(srcdir)/'`src/strv.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_basic_la-strv.Tpo src/$(DEPDIR)/libsystemd_basic_la-strv.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/strv.c' object='src/libsystemd_basic_la-strv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_basic_la-strv.lo `test -f 'src/strv.c' || echo '$(srcdir)/'`src/strv.c + +src/libsystemd_basic_la-conf-parser.lo: src/conf-parser.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_basic_la-conf-parser.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_basic_la-conf-parser.Tpo -c -o src/libsystemd_basic_la-conf-parser.lo `test -f 'src/conf-parser.c' || echo '$(srcdir)/'`src/conf-parser.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_basic_la-conf-parser.Tpo src/$(DEPDIR)/libsystemd_basic_la-conf-parser.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/conf-parser.c' object='src/libsystemd_basic_la-conf-parser.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_basic_la-conf-parser.lo `test -f 'src/conf-parser.c' || echo '$(srcdir)/'`src/conf-parser.c + +src/libsystemd_basic_la-socket-util.lo: src/socket-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_basic_la-socket-util.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_basic_la-socket-util.Tpo -c -o src/libsystemd_basic_la-socket-util.lo `test -f 'src/socket-util.c' || echo '$(srcdir)/'`src/socket-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_basic_la-socket-util.Tpo src/$(DEPDIR)/libsystemd_basic_la-socket-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/socket-util.c' object='src/libsystemd_basic_la-socket-util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_basic_la-socket-util.lo `test -f 'src/socket-util.c' || echo '$(srcdir)/'`src/socket-util.c + +src/libsystemd_basic_la-log.lo: src/log.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_basic_la-log.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_basic_la-log.Tpo -c -o src/libsystemd_basic_la-log.lo `test -f 'src/log.c' || echo '$(srcdir)/'`src/log.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_basic_la-log.Tpo src/$(DEPDIR)/libsystemd_basic_la-log.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/log.c' object='src/libsystemd_basic_la-log.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_basic_la-log.lo `test -f 'src/log.c' || echo '$(srcdir)/'`src/log.c + +src/libsystemd_basic_la-ratelimit.lo: src/ratelimit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_basic_la-ratelimit.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_basic_la-ratelimit.Tpo -c -o src/libsystemd_basic_la-ratelimit.lo `test -f 'src/ratelimit.c' || echo '$(srcdir)/'`src/ratelimit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_basic_la-ratelimit.Tpo src/$(DEPDIR)/libsystemd_basic_la-ratelimit.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ratelimit.c' object='src/libsystemd_basic_la-ratelimit.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_basic_la-ratelimit.lo `test -f 'src/ratelimit.c' || echo '$(srcdir)/'`src/ratelimit.c + +src/libsystemd_basic_la-exit-status.lo: src/exit-status.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_basic_la-exit-status.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_basic_la-exit-status.Tpo -c -o src/libsystemd_basic_la-exit-status.lo `test -f 'src/exit-status.c' || echo '$(srcdir)/'`src/exit-status.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_basic_la-exit-status.Tpo src/$(DEPDIR)/libsystemd_basic_la-exit-status.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/exit-status.c' object='src/libsystemd_basic_la-exit-status.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_basic_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_basic_la-exit-status.lo `test -f 'src/exit-status.c' || echo '$(srcdir)/'`src/exit-status.c + +src/libsystemd_core_la-unit.lo: src/unit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-unit.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-unit.Tpo -c -o src/libsystemd_core_la-unit.lo `test -f 'src/unit.c' || echo '$(srcdir)/'`src/unit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-unit.Tpo src/$(DEPDIR)/libsystemd_core_la-unit.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/unit.c' object='src/libsystemd_core_la-unit.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-unit.lo `test -f 'src/unit.c' || echo '$(srcdir)/'`src/unit.c + +src/libsystemd_core_la-job.lo: src/job.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-job.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-job.Tpo -c -o src/libsystemd_core_la-job.lo `test -f 'src/job.c' || echo '$(srcdir)/'`src/job.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-job.Tpo src/$(DEPDIR)/libsystemd_core_la-job.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/job.c' object='src/libsystemd_core_la-job.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-job.lo `test -f 'src/job.c' || echo '$(srcdir)/'`src/job.c + +src/libsystemd_core_la-manager.lo: src/manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-manager.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-manager.Tpo -c -o src/libsystemd_core_la-manager.lo `test -f 'src/manager.c' || echo '$(srcdir)/'`src/manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-manager.Tpo src/$(DEPDIR)/libsystemd_core_la-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/manager.c' object='src/libsystemd_core_la-manager.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-manager.lo `test -f 'src/manager.c' || echo '$(srcdir)/'`src/manager.c + +src/libsystemd_core_la-path-lookup.lo: src/path-lookup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-path-lookup.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-path-lookup.Tpo -c -o src/libsystemd_core_la-path-lookup.lo `test -f 'src/path-lookup.c' || echo '$(srcdir)/'`src/path-lookup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-path-lookup.Tpo src/$(DEPDIR)/libsystemd_core_la-path-lookup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/path-lookup.c' object='src/libsystemd_core_la-path-lookup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-path-lookup.lo `test -f 'src/path-lookup.c' || echo '$(srcdir)/'`src/path-lookup.c + +src/libsystemd_core_la-load-fragment.lo: src/load-fragment.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-load-fragment.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-load-fragment.Tpo -c -o src/libsystemd_core_la-load-fragment.lo `test -f 'src/load-fragment.c' || echo '$(srcdir)/'`src/load-fragment.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-load-fragment.Tpo src/$(DEPDIR)/libsystemd_core_la-load-fragment.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/load-fragment.c' object='src/libsystemd_core_la-load-fragment.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-load-fragment.lo `test -f 'src/load-fragment.c' || echo '$(srcdir)/'`src/load-fragment.c + +src/libsystemd_core_la-service.lo: src/service.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-service.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-service.Tpo -c -o src/libsystemd_core_la-service.lo `test -f 'src/service.c' || echo '$(srcdir)/'`src/service.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-service.Tpo src/$(DEPDIR)/libsystemd_core_la-service.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/service.c' object='src/libsystemd_core_la-service.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-service.lo `test -f 'src/service.c' || echo '$(srcdir)/'`src/service.c + +src/libsystemd_core_la-automount.lo: src/automount.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-automount.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-automount.Tpo -c -o src/libsystemd_core_la-automount.lo `test -f 'src/automount.c' || echo '$(srcdir)/'`src/automount.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-automount.Tpo src/$(DEPDIR)/libsystemd_core_la-automount.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/automount.c' object='src/libsystemd_core_la-automount.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-automount.lo `test -f 'src/automount.c' || echo '$(srcdir)/'`src/automount.c + +src/libsystemd_core_la-mount.lo: src/mount.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-mount.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-mount.Tpo -c -o src/libsystemd_core_la-mount.lo `test -f 'src/mount.c' || echo '$(srcdir)/'`src/mount.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-mount.Tpo src/$(DEPDIR)/libsystemd_core_la-mount.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/mount.c' object='src/libsystemd_core_la-mount.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-mount.lo `test -f 'src/mount.c' || echo '$(srcdir)/'`src/mount.c + +src/libsystemd_core_la-swap.lo: src/swap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-swap.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-swap.Tpo -c -o src/libsystemd_core_la-swap.lo `test -f 'src/swap.c' || echo '$(srcdir)/'`src/swap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-swap.Tpo src/$(DEPDIR)/libsystemd_core_la-swap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/swap.c' object='src/libsystemd_core_la-swap.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-swap.lo `test -f 'src/swap.c' || echo '$(srcdir)/'`src/swap.c + +src/libsystemd_core_la-device.lo: src/device.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-device.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-device.Tpo -c -o src/libsystemd_core_la-device.lo `test -f 'src/device.c' || echo '$(srcdir)/'`src/device.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-device.Tpo src/$(DEPDIR)/libsystemd_core_la-device.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/device.c' object='src/libsystemd_core_la-device.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-device.lo `test -f 'src/device.c' || echo '$(srcdir)/'`src/device.c + +src/libsystemd_core_la-target.lo: src/target.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-target.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-target.Tpo -c -o src/libsystemd_core_la-target.lo `test -f 'src/target.c' || echo '$(srcdir)/'`src/target.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-target.Tpo src/$(DEPDIR)/libsystemd_core_la-target.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/target.c' object='src/libsystemd_core_la-target.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-target.lo `test -f 'src/target.c' || echo '$(srcdir)/'`src/target.c + +src/libsystemd_core_la-snapshot.lo: src/snapshot.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-snapshot.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-snapshot.Tpo -c -o src/libsystemd_core_la-snapshot.lo `test -f 'src/snapshot.c' || echo '$(srcdir)/'`src/snapshot.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-snapshot.Tpo src/$(DEPDIR)/libsystemd_core_la-snapshot.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/snapshot.c' object='src/libsystemd_core_la-snapshot.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-snapshot.lo `test -f 'src/snapshot.c' || echo '$(srcdir)/'`src/snapshot.c + +src/libsystemd_core_la-socket.lo: src/socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-socket.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-socket.Tpo -c -o src/libsystemd_core_la-socket.lo `test -f 'src/socket.c' || echo '$(srcdir)/'`src/socket.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-socket.Tpo src/$(DEPDIR)/libsystemd_core_la-socket.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/socket.c' object='src/libsystemd_core_la-socket.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-socket.lo `test -f 'src/socket.c' || echo '$(srcdir)/'`src/socket.c + +src/libsystemd_core_la-timer.lo: src/timer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-timer.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-timer.Tpo -c -o src/libsystemd_core_la-timer.lo `test -f 'src/timer.c' || echo '$(srcdir)/'`src/timer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-timer.Tpo src/$(DEPDIR)/libsystemd_core_la-timer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/timer.c' object='src/libsystemd_core_la-timer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-timer.lo `test -f 'src/timer.c' || echo '$(srcdir)/'`src/timer.c + +src/libsystemd_core_la-path.lo: src/path.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-path.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-path.Tpo -c -o src/libsystemd_core_la-path.lo `test -f 'src/path.c' || echo '$(srcdir)/'`src/path.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-path.Tpo src/$(DEPDIR)/libsystemd_core_la-path.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/path.c' object='src/libsystemd_core_la-path.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-path.lo `test -f 'src/path.c' || echo '$(srcdir)/'`src/path.c + +src/libsystemd_core_la-load-dropin.lo: src/load-dropin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-load-dropin.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-load-dropin.Tpo -c -o src/libsystemd_core_la-load-dropin.lo `test -f 'src/load-dropin.c' || echo '$(srcdir)/'`src/load-dropin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-load-dropin.Tpo src/$(DEPDIR)/libsystemd_core_la-load-dropin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/load-dropin.c' object='src/libsystemd_core_la-load-dropin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-load-dropin.lo `test -f 'src/load-dropin.c' || echo '$(srcdir)/'`src/load-dropin.c + +src/libsystemd_core_la-execute.lo: src/execute.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-execute.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-execute.Tpo -c -o src/libsystemd_core_la-execute.lo `test -f 'src/execute.c' || echo '$(srcdir)/'`src/execute.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-execute.Tpo src/$(DEPDIR)/libsystemd_core_la-execute.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/execute.c' object='src/libsystemd_core_la-execute.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-execute.lo `test -f 'src/execute.c' || echo '$(srcdir)/'`src/execute.c + +src/libsystemd_core_la-utmp-wtmp.lo: src/utmp-wtmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-utmp-wtmp.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-utmp-wtmp.Tpo -c -o src/libsystemd_core_la-utmp-wtmp.lo `test -f 'src/utmp-wtmp.c' || echo '$(srcdir)/'`src/utmp-wtmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-utmp-wtmp.Tpo src/$(DEPDIR)/libsystemd_core_la-utmp-wtmp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/utmp-wtmp.c' object='src/libsystemd_core_la-utmp-wtmp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-utmp-wtmp.lo `test -f 'src/utmp-wtmp.c' || echo '$(srcdir)/'`src/utmp-wtmp.c + +src/libsystemd_core_la-dbus.lo: src/dbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus.Tpo -c -o src/libsystemd_core_la-dbus.lo `test -f 'src/dbus.c' || echo '$(srcdir)/'`src/dbus.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus.c' object='src/libsystemd_core_la-dbus.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus.lo `test -f 'src/dbus.c' || echo '$(srcdir)/'`src/dbus.c + +src/libsystemd_core_la-dbus-manager.lo: src/dbus-manager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-manager.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-manager.Tpo -c -o src/libsystemd_core_la-dbus-manager.lo `test -f 'src/dbus-manager.c' || echo '$(srcdir)/'`src/dbus-manager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-manager.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-manager.c' object='src/libsystemd_core_la-dbus-manager.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-manager.lo `test -f 'src/dbus-manager.c' || echo '$(srcdir)/'`src/dbus-manager.c + +src/libsystemd_core_la-dbus-unit.lo: src/dbus-unit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-unit.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-unit.Tpo -c -o src/libsystemd_core_la-dbus-unit.lo `test -f 'src/dbus-unit.c' || echo '$(srcdir)/'`src/dbus-unit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-unit.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-unit.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-unit.c' object='src/libsystemd_core_la-dbus-unit.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-unit.lo `test -f 'src/dbus-unit.c' || echo '$(srcdir)/'`src/dbus-unit.c + +src/libsystemd_core_la-dbus-job.lo: src/dbus-job.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-job.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-job.Tpo -c -o src/libsystemd_core_la-dbus-job.lo `test -f 'src/dbus-job.c' || echo '$(srcdir)/'`src/dbus-job.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-job.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-job.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-job.c' object='src/libsystemd_core_la-dbus-job.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-job.lo `test -f 'src/dbus-job.c' || echo '$(srcdir)/'`src/dbus-job.c + +src/libsystemd_core_la-dbus-service.lo: src/dbus-service.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-service.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-service.Tpo -c -o src/libsystemd_core_la-dbus-service.lo `test -f 'src/dbus-service.c' || echo '$(srcdir)/'`src/dbus-service.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-service.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-service.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-service.c' object='src/libsystemd_core_la-dbus-service.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-service.lo `test -f 'src/dbus-service.c' || echo '$(srcdir)/'`src/dbus-service.c + +src/libsystemd_core_la-dbus-socket.lo: src/dbus-socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-socket.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-socket.Tpo -c -o src/libsystemd_core_la-dbus-socket.lo `test -f 'src/dbus-socket.c' || echo '$(srcdir)/'`src/dbus-socket.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-socket.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-socket.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-socket.c' object='src/libsystemd_core_la-dbus-socket.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-socket.lo `test -f 'src/dbus-socket.c' || echo '$(srcdir)/'`src/dbus-socket.c + +src/libsystemd_core_la-dbus-timer.lo: src/dbus-timer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-timer.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-timer.Tpo -c -o src/libsystemd_core_la-dbus-timer.lo `test -f 'src/dbus-timer.c' || echo '$(srcdir)/'`src/dbus-timer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-timer.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-timer.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-timer.c' object='src/libsystemd_core_la-dbus-timer.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-timer.lo `test -f 'src/dbus-timer.c' || echo '$(srcdir)/'`src/dbus-timer.c + +src/libsystemd_core_la-dbus-target.lo: src/dbus-target.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-target.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-target.Tpo -c -o src/libsystemd_core_la-dbus-target.lo `test -f 'src/dbus-target.c' || echo '$(srcdir)/'`src/dbus-target.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-target.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-target.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-target.c' object='src/libsystemd_core_la-dbus-target.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-target.lo `test -f 'src/dbus-target.c' || echo '$(srcdir)/'`src/dbus-target.c + +src/libsystemd_core_la-dbus-mount.lo: src/dbus-mount.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-mount.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-mount.Tpo -c -o src/libsystemd_core_la-dbus-mount.lo `test -f 'src/dbus-mount.c' || echo '$(srcdir)/'`src/dbus-mount.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-mount.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-mount.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-mount.c' object='src/libsystemd_core_la-dbus-mount.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-mount.lo `test -f 'src/dbus-mount.c' || echo '$(srcdir)/'`src/dbus-mount.c + +src/libsystemd_core_la-dbus-automount.lo: src/dbus-automount.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-automount.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-automount.Tpo -c -o src/libsystemd_core_la-dbus-automount.lo `test -f 'src/dbus-automount.c' || echo '$(srcdir)/'`src/dbus-automount.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-automount.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-automount.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-automount.c' object='src/libsystemd_core_la-dbus-automount.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-automount.lo `test -f 'src/dbus-automount.c' || echo '$(srcdir)/'`src/dbus-automount.c + +src/libsystemd_core_la-dbus-swap.lo: src/dbus-swap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-swap.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-swap.Tpo -c -o src/libsystemd_core_la-dbus-swap.lo `test -f 'src/dbus-swap.c' || echo '$(srcdir)/'`src/dbus-swap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-swap.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-swap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-swap.c' object='src/libsystemd_core_la-dbus-swap.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-swap.lo `test -f 'src/dbus-swap.c' || echo '$(srcdir)/'`src/dbus-swap.c + +src/libsystemd_core_la-dbus-snapshot.lo: src/dbus-snapshot.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-snapshot.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-snapshot.Tpo -c -o src/libsystemd_core_la-dbus-snapshot.lo `test -f 'src/dbus-snapshot.c' || echo '$(srcdir)/'`src/dbus-snapshot.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-snapshot.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-snapshot.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-snapshot.c' object='src/libsystemd_core_la-dbus-snapshot.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-snapshot.lo `test -f 'src/dbus-snapshot.c' || echo '$(srcdir)/'`src/dbus-snapshot.c + +src/libsystemd_core_la-dbus-device.lo: src/dbus-device.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-device.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-device.Tpo -c -o src/libsystemd_core_la-dbus-device.lo `test -f 'src/dbus-device.c' || echo '$(srcdir)/'`src/dbus-device.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-device.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-device.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-device.c' object='src/libsystemd_core_la-dbus-device.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-device.lo `test -f 'src/dbus-device.c' || echo '$(srcdir)/'`src/dbus-device.c + +src/libsystemd_core_la-dbus-execute.lo: src/dbus-execute.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-execute.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-execute.Tpo -c -o src/libsystemd_core_la-dbus-execute.lo `test -f 'src/dbus-execute.c' || echo '$(srcdir)/'`src/dbus-execute.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-execute.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-execute.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-execute.c' object='src/libsystemd_core_la-dbus-execute.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-execute.lo `test -f 'src/dbus-execute.c' || echo '$(srcdir)/'`src/dbus-execute.c + +src/libsystemd_core_la-dbus-path.lo: src/dbus-path.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-path.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-path.Tpo -c -o src/libsystemd_core_la-dbus-path.lo `test -f 'src/dbus-path.c' || echo '$(srcdir)/'`src/dbus-path.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-path.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-path.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-path.c' object='src/libsystemd_core_la-dbus-path.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-path.lo `test -f 'src/dbus-path.c' || echo '$(srcdir)/'`src/dbus-path.c + +src/libsystemd_core_la-cgroup.lo: src/cgroup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-cgroup.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-cgroup.Tpo -c -o src/libsystemd_core_la-cgroup.lo `test -f 'src/cgroup.c' || echo '$(srcdir)/'`src/cgroup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-cgroup.Tpo src/$(DEPDIR)/libsystemd_core_la-cgroup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup.c' object='src/libsystemd_core_la-cgroup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-cgroup.lo `test -f 'src/cgroup.c' || echo '$(srcdir)/'`src/cgroup.c + +src/libsystemd_core_la-mount-setup.lo: src/mount-setup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-mount-setup.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-mount-setup.Tpo -c -o src/libsystemd_core_la-mount-setup.lo `test -f 'src/mount-setup.c' || echo '$(srcdir)/'`src/mount-setup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-mount-setup.Tpo src/$(DEPDIR)/libsystemd_core_la-mount-setup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/mount-setup.c' object='src/libsystemd_core_la-mount-setup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-mount-setup.lo `test -f 'src/mount-setup.c' || echo '$(srcdir)/'`src/mount-setup.c + +src/libsystemd_core_la-hostname-setup.lo: src/hostname-setup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-hostname-setup.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-hostname-setup.Tpo -c -o src/libsystemd_core_la-hostname-setup.lo `test -f 'src/hostname-setup.c' || echo '$(srcdir)/'`src/hostname-setup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-hostname-setup.Tpo src/$(DEPDIR)/libsystemd_core_la-hostname-setup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/hostname-setup.c' object='src/libsystemd_core_la-hostname-setup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-hostname-setup.lo `test -f 'src/hostname-setup.c' || echo '$(srcdir)/'`src/hostname-setup.c + +src/libsystemd_core_la-selinux-setup.lo: src/selinux-setup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-selinux-setup.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-selinux-setup.Tpo -c -o src/libsystemd_core_la-selinux-setup.lo `test -f 'src/selinux-setup.c' || echo '$(srcdir)/'`src/selinux-setup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-selinux-setup.Tpo src/$(DEPDIR)/libsystemd_core_la-selinux-setup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/selinux-setup.c' object='src/libsystemd_core_la-selinux-setup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-selinux-setup.lo `test -f 'src/selinux-setup.c' || echo '$(srcdir)/'`src/selinux-setup.c + +src/libsystemd_core_la-loopback-setup.lo: src/loopback-setup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-loopback-setup.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-loopback-setup.Tpo -c -o src/libsystemd_core_la-loopback-setup.lo `test -f 'src/loopback-setup.c' || echo '$(srcdir)/'`src/loopback-setup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-loopback-setup.Tpo src/$(DEPDIR)/libsystemd_core_la-loopback-setup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/loopback-setup.c' object='src/libsystemd_core_la-loopback-setup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-loopback-setup.lo `test -f 'src/loopback-setup.c' || echo '$(srcdir)/'`src/loopback-setup.c + +src/libsystemd_core_la-kmod-setup.lo: src/kmod-setup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-kmod-setup.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-kmod-setup.Tpo -c -o src/libsystemd_core_la-kmod-setup.lo `test -f 'src/kmod-setup.c' || echo '$(srcdir)/'`src/kmod-setup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-kmod-setup.Tpo src/$(DEPDIR)/libsystemd_core_la-kmod-setup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/kmod-setup.c' object='src/libsystemd_core_la-kmod-setup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-kmod-setup.lo `test -f 'src/kmod-setup.c' || echo '$(srcdir)/'`src/kmod-setup.c + +src/libsystemd_core_la-locale-setup.lo: src/locale-setup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-locale-setup.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-locale-setup.Tpo -c -o src/libsystemd_core_la-locale-setup.lo `test -f 'src/locale-setup.c' || echo '$(srcdir)/'`src/locale-setup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-locale-setup.Tpo src/$(DEPDIR)/libsystemd_core_la-locale-setup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/locale-setup.c' object='src/libsystemd_core_la-locale-setup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-locale-setup.lo `test -f 'src/locale-setup.c' || echo '$(srcdir)/'`src/locale-setup.c + +src/libsystemd_core_la-machine-id-setup.lo: src/machine-id-setup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-machine-id-setup.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-machine-id-setup.Tpo -c -o src/libsystemd_core_la-machine-id-setup.lo `test -f 'src/machine-id-setup.c' || echo '$(srcdir)/'`src/machine-id-setup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-machine-id-setup.Tpo src/$(DEPDIR)/libsystemd_core_la-machine-id-setup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/machine-id-setup.c' object='src/libsystemd_core_la-machine-id-setup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-machine-id-setup.lo `test -f 'src/machine-id-setup.c' || echo '$(srcdir)/'`src/machine-id-setup.c + +src/libsystemd_core_la-specifier.lo: src/specifier.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-specifier.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-specifier.Tpo -c -o src/libsystemd_core_la-specifier.lo `test -f 'src/specifier.c' || echo '$(srcdir)/'`src/specifier.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-specifier.Tpo src/$(DEPDIR)/libsystemd_core_la-specifier.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/specifier.c' object='src/libsystemd_core_la-specifier.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-specifier.lo `test -f 'src/specifier.c' || echo '$(srcdir)/'`src/specifier.c + +src/libsystemd_core_la-unit-name.lo: src/unit-name.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-unit-name.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-unit-name.Tpo -c -o src/libsystemd_core_la-unit-name.lo `test -f 'src/unit-name.c' || echo '$(srcdir)/'`src/unit-name.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-unit-name.Tpo src/$(DEPDIR)/libsystemd_core_la-unit-name.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/unit-name.c' object='src/libsystemd_core_la-unit-name.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-unit-name.lo `test -f 'src/unit-name.c' || echo '$(srcdir)/'`src/unit-name.c + +src/libsystemd_core_la-fdset.lo: src/fdset.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-fdset.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-fdset.Tpo -c -o src/libsystemd_core_la-fdset.lo `test -f 'src/fdset.c' || echo '$(srcdir)/'`src/fdset.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-fdset.Tpo src/$(DEPDIR)/libsystemd_core_la-fdset.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/fdset.c' object='src/libsystemd_core_la-fdset.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-fdset.lo `test -f 'src/fdset.c' || echo '$(srcdir)/'`src/fdset.c + +src/libsystemd_core_la-namespace.lo: src/namespace.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-namespace.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-namespace.Tpo -c -o src/libsystemd_core_la-namespace.lo `test -f 'src/namespace.c' || echo '$(srcdir)/'`src/namespace.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-namespace.Tpo src/$(DEPDIR)/libsystemd_core_la-namespace.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/namespace.c' object='src/libsystemd_core_la-namespace.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-namespace.lo `test -f 'src/namespace.c' || echo '$(srcdir)/'`src/namespace.c + +src/libsystemd_core_la-tcpwrap.lo: src/tcpwrap.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-tcpwrap.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-tcpwrap.Tpo -c -o src/libsystemd_core_la-tcpwrap.lo `test -f 'src/tcpwrap.c' || echo '$(srcdir)/'`src/tcpwrap.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-tcpwrap.Tpo src/$(DEPDIR)/libsystemd_core_la-tcpwrap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tcpwrap.c' object='src/libsystemd_core_la-tcpwrap.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-tcpwrap.lo `test -f 'src/tcpwrap.c' || echo '$(srcdir)/'`src/tcpwrap.c + +src/libsystemd_core_la-cgroup-util.lo: src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-cgroup-util.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-cgroup-util.Tpo -c -o src/libsystemd_core_la-cgroup-util.lo `test -f 'src/cgroup-util.c' || echo '$(srcdir)/'`src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-cgroup-util.Tpo src/$(DEPDIR)/libsystemd_core_la-cgroup-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-util.c' object='src/libsystemd_core_la-cgroup-util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-cgroup-util.lo `test -f 'src/cgroup-util.c' || echo '$(srcdir)/'`src/cgroup-util.c + +src/libsystemd_core_la-condition.lo: src/condition.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-condition.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-condition.Tpo -c -o src/libsystemd_core_la-condition.lo `test -f 'src/condition.c' || echo '$(srcdir)/'`src/condition.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-condition.Tpo src/$(DEPDIR)/libsystemd_core_la-condition.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/condition.c' object='src/libsystemd_core_la-condition.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-condition.lo `test -f 'src/condition.c' || echo '$(srcdir)/'`src/condition.c + +src/libsystemd_core_la-dbus-common.lo: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-dbus-common.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-dbus-common.Tpo -c -o src/libsystemd_core_la-dbus-common.lo `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-dbus-common.Tpo src/$(DEPDIR)/libsystemd_core_la-dbus-common.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/libsystemd_core_la-dbus-common.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-dbus-common.lo `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c + +src/libsystemd_core_la-sd-daemon.lo: src/sd-daemon.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-sd-daemon.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-sd-daemon.Tpo -c -o src/libsystemd_core_la-sd-daemon.lo `test -f 'src/sd-daemon.c' || echo '$(srcdir)/'`src/sd-daemon.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-sd-daemon.Tpo src/$(DEPDIR)/libsystemd_core_la-sd-daemon.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sd-daemon.c' object='src/libsystemd_core_la-sd-daemon.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-sd-daemon.lo `test -f 'src/sd-daemon.c' || echo '$(srcdir)/'`src/sd-daemon.c + +src/libsystemd_core_la-install.lo: src/install.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-install.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-install.Tpo -c -o src/libsystemd_core_la-install.lo `test -f 'src/install.c' || echo '$(srcdir)/'`src/install.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-install.Tpo src/$(DEPDIR)/libsystemd_core_la-install.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/install.c' object='src/libsystemd_core_la-install.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-install.lo `test -f 'src/install.c' || echo '$(srcdir)/'`src/install.c + +src/libsystemd_core_la-cgroup-attr.lo: src/cgroup-attr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-cgroup-attr.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-cgroup-attr.Tpo -c -o src/libsystemd_core_la-cgroup-attr.lo `test -f 'src/cgroup-attr.c' || echo '$(srcdir)/'`src/cgroup-attr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-cgroup-attr.Tpo src/$(DEPDIR)/libsystemd_core_la-cgroup-attr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-attr.c' object='src/libsystemd_core_la-cgroup-attr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-cgroup-attr.lo `test -f 'src/cgroup-attr.c' || echo '$(srcdir)/'`src/cgroup-attr.c + +src/libsystemd_core_la-sd-id128.lo: src/sd-id128.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-sd-id128.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-sd-id128.Tpo -c -o src/libsystemd_core_la-sd-id128.lo `test -f 'src/sd-id128.c' || echo '$(srcdir)/'`src/sd-id128.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-sd-id128.Tpo src/$(DEPDIR)/libsystemd_core_la-sd-id128.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sd-id128.c' object='src/libsystemd_core_la-sd-id128.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-sd-id128.lo `test -f 'src/sd-id128.c' || echo '$(srcdir)/'`src/sd-id128.c + +src/libsystemd_core_la-load-fragment-gperf.lo: src/load-fragment-gperf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-load-fragment-gperf.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-load-fragment-gperf.Tpo -c -o src/libsystemd_core_la-load-fragment-gperf.lo `test -f 'src/load-fragment-gperf.c' || echo '$(srcdir)/'`src/load-fragment-gperf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-load-fragment-gperf.Tpo src/$(DEPDIR)/libsystemd_core_la-load-fragment-gperf.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/load-fragment-gperf.c' object='src/libsystemd_core_la-load-fragment-gperf.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-load-fragment-gperf.lo `test -f 'src/load-fragment-gperf.c' || echo '$(srcdir)/'`src/load-fragment-gperf.c + +src/libsystemd_core_la-load-fragment-gperf-nulstr.lo: src/load-fragment-gperf-nulstr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_core_la-load-fragment-gperf-nulstr.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_core_la-load-fragment-gperf-nulstr.Tpo -c -o src/libsystemd_core_la-load-fragment-gperf-nulstr.lo `test -f 'src/load-fragment-gperf-nulstr.c' || echo '$(srcdir)/'`src/load-fragment-gperf-nulstr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_core_la-load-fragment-gperf-nulstr.Tpo src/$(DEPDIR)/libsystemd_core_la-load-fragment-gperf-nulstr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/load-fragment-gperf-nulstr.c' object='src/libsystemd_core_la-load-fragment-gperf-nulstr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_core_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_core_la-load-fragment-gperf-nulstr.lo `test -f 'src/load-fragment-gperf-nulstr.c' || echo '$(srcdir)/'`src/load-fragment-gperf-nulstr.c + +src/libsystemd_daemon_la-sd-daemon.lo: src/sd-daemon.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_daemon_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_daemon_la-sd-daemon.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_daemon_la-sd-daemon.Tpo -c -o src/libsystemd_daemon_la-sd-daemon.lo `test -f 'src/sd-daemon.c' || echo '$(srcdir)/'`src/sd-daemon.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_daemon_la-sd-daemon.Tpo src/$(DEPDIR)/libsystemd_daemon_la-sd-daemon.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sd-daemon.c' object='src/libsystemd_daemon_la-sd-daemon.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_daemon_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_daemon_la-sd-daemon.lo `test -f 'src/sd-daemon.c' || echo '$(srcdir)/'`src/sd-daemon.c + +src/libsystemd_id128_la-sd-id128.lo: src/sd-id128.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_id128_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_id128_la-sd-id128.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_id128_la-sd-id128.Tpo -c -o src/libsystemd_id128_la-sd-id128.lo `test -f 'src/sd-id128.c' || echo '$(srcdir)/'`src/sd-id128.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_id128_la-sd-id128.Tpo src/$(DEPDIR)/libsystemd_id128_la-sd-id128.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sd-id128.c' object='src/libsystemd_id128_la-sd-id128.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_id128_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_id128_la-sd-id128.lo `test -f 'src/sd-id128.c' || echo '$(srcdir)/'`src/sd-id128.c + +src/journal/libsystemd_journal_la-sd-journal.lo: src/journal/sd-journal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_journal_la_CFLAGS) $(CFLAGS) -MT src/journal/libsystemd_journal_la-sd-journal.lo -MD -MP -MF src/journal/$(DEPDIR)/libsystemd_journal_la-sd-journal.Tpo -c -o src/journal/libsystemd_journal_la-sd-journal.lo `test -f 'src/journal/sd-journal.c' || echo '$(srcdir)/'`src/journal/sd-journal.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/libsystemd_journal_la-sd-journal.Tpo src/journal/$(DEPDIR)/libsystemd_journal_la-sd-journal.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/sd-journal.c' object='src/journal/libsystemd_journal_la-sd-journal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_journal_la_CFLAGS) $(CFLAGS) -c -o src/journal/libsystemd_journal_la-sd-journal.lo `test -f 'src/journal/sd-journal.c' || echo '$(srcdir)/'`src/journal/sd-journal.c + +src/journal/libsystemd_journal_la-journal-file.lo: src/journal/journal-file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_journal_la_CFLAGS) $(CFLAGS) -MT src/journal/libsystemd_journal_la-journal-file.lo -MD -MP -MF src/journal/$(DEPDIR)/libsystemd_journal_la-journal-file.Tpo -c -o src/journal/libsystemd_journal_la-journal-file.lo `test -f 'src/journal/journal-file.c' || echo '$(srcdir)/'`src/journal/journal-file.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/libsystemd_journal_la-journal-file.Tpo src/journal/$(DEPDIR)/libsystemd_journal_la-journal-file.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journal-file.c' object='src/journal/libsystemd_journal_la-journal-file.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_journal_la_CFLAGS) $(CFLAGS) -c -o src/journal/libsystemd_journal_la-journal-file.lo `test -f 'src/journal/journal-file.c' || echo '$(srcdir)/'`src/journal/journal-file.c + +src/journal/libsystemd_journal_la-lookup3.lo: src/journal/lookup3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_journal_la_CFLAGS) $(CFLAGS) -MT src/journal/libsystemd_journal_la-lookup3.lo -MD -MP -MF src/journal/$(DEPDIR)/libsystemd_journal_la-lookup3.Tpo -c -o src/journal/libsystemd_journal_la-lookup3.lo `test -f 'src/journal/lookup3.c' || echo '$(srcdir)/'`src/journal/lookup3.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/libsystemd_journal_la-lookup3.Tpo src/journal/$(DEPDIR)/libsystemd_journal_la-lookup3.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/lookup3.c' object='src/journal/libsystemd_journal_la-lookup3.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_journal_la_CFLAGS) $(CFLAGS) -c -o src/journal/libsystemd_journal_la-lookup3.lo `test -f 'src/journal/lookup3.c' || echo '$(srcdir)/'`src/journal/lookup3.c + +src/journal/libsystemd_journal_la-journal-send.lo: src/journal/journal-send.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_journal_la_CFLAGS) $(CFLAGS) -MT src/journal/libsystemd_journal_la-journal-send.lo -MD -MP -MF src/journal/$(DEPDIR)/libsystemd_journal_la-journal-send.Tpo -c -o src/journal/libsystemd_journal_la-journal-send.lo `test -f 'src/journal/journal-send.c' || echo '$(srcdir)/'`src/journal/journal-send.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/libsystemd_journal_la-journal-send.Tpo src/journal/$(DEPDIR)/libsystemd_journal_la-journal-send.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journal-send.c' object='src/journal/libsystemd_journal_la-journal-send.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_journal_la_CFLAGS) $(CFLAGS) -c -o src/journal/libsystemd_journal_la-journal-send.lo `test -f 'src/journal/journal-send.c' || echo '$(srcdir)/'`src/journal/journal-send.c + +src/journal/libsystemd_journal_la-compress.lo: src/journal/compress.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_journal_la_CFLAGS) $(CFLAGS) -MT src/journal/libsystemd_journal_la-compress.lo -MD -MP -MF src/journal/$(DEPDIR)/libsystemd_journal_la-compress.Tpo -c -o src/journal/libsystemd_journal_la-compress.lo `test -f 'src/journal/compress.c' || echo '$(srcdir)/'`src/journal/compress.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/libsystemd_journal_la-compress.Tpo src/journal/$(DEPDIR)/libsystemd_journal_la-compress.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/compress.c' object='src/journal/libsystemd_journal_la-compress.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_journal_la_CFLAGS) $(CFLAGS) -c -o src/journal/libsystemd_journal_la-compress.lo `test -f 'src/journal/compress.c' || echo '$(srcdir)/'`src/journal/compress.c + +src/login/libsystemd_login_la-sd-login.lo: src/login/sd-login.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_login_la_CFLAGS) $(CFLAGS) -MT src/login/libsystemd_login_la-sd-login.lo -MD -MP -MF src/login/$(DEPDIR)/libsystemd_login_la-sd-login.Tpo -c -o src/login/libsystemd_login_la-sd-login.lo `test -f 'src/login/sd-login.c' || echo '$(srcdir)/'`src/login/sd-login.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/libsystemd_login_la-sd-login.Tpo src/login/$(DEPDIR)/libsystemd_login_la-sd-login.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/sd-login.c' object='src/login/libsystemd_login_la-sd-login.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_login_la_CFLAGS) $(CFLAGS) -c -o src/login/libsystemd_login_la-sd-login.lo `test -f 'src/login/sd-login.c' || echo '$(srcdir)/'`src/login/sd-login.c + +src/libsystemd_login_la-cgroup-util.lo: src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_login_la_CFLAGS) $(CFLAGS) -MT src/libsystemd_login_la-cgroup-util.lo -MD -MP -MF src/$(DEPDIR)/libsystemd_login_la-cgroup-util.Tpo -c -o src/libsystemd_login_la-cgroup-util.lo `test -f 'src/cgroup-util.c' || echo '$(srcdir)/'`src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/libsystemd_login_la-cgroup-util.Tpo src/$(DEPDIR)/libsystemd_login_la-cgroup-util.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-util.c' object='src/libsystemd_login_la-cgroup-util.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsystemd_login_la_CFLAGS) $(CFLAGS) -c -o src/libsystemd_login_la-cgroup-util.lo `test -f 'src/cgroup-util.c' || echo '$(srcdir)/'`src/cgroup-util.c + +src/login/pam_systemd_la-pam-module.lo: src/login/pam-module.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_systemd_la_CFLAGS) $(CFLAGS) -MT src/login/pam_systemd_la-pam-module.lo -MD -MP -MF src/login/$(DEPDIR)/pam_systemd_la-pam-module.Tpo -c -o src/login/pam_systemd_la-pam-module.lo `test -f 'src/login/pam-module.c' || echo '$(srcdir)/'`src/login/pam-module.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/pam_systemd_la-pam-module.Tpo src/login/$(DEPDIR)/pam_systemd_la-pam-module.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/pam-module.c' object='src/login/pam_systemd_la-pam-module.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_systemd_la_CFLAGS) $(CFLAGS) -c -o src/login/pam_systemd_la-pam-module.lo `test -f 'src/login/pam-module.c' || echo '$(srcdir)/'`src/login/pam-module.c + +src/pam_systemd_la-dbus-common.lo: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_systemd_la_CFLAGS) $(CFLAGS) -MT src/pam_systemd_la-dbus-common.lo -MD -MP -MF src/$(DEPDIR)/pam_systemd_la-dbus-common.Tpo -c -o src/pam_systemd_la-dbus-common.lo `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/pam_systemd_la-dbus-common.Tpo src/$(DEPDIR)/pam_systemd_la-dbus-common.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/pam_systemd_la-dbus-common.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_systemd_la_CFLAGS) $(CFLAGS) -c -o src/pam_systemd_la-dbus-common.lo `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c + +src/systemadm-systemadm.o: src/systemadm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemadm_CFLAGS) $(CFLAGS) -MT src/systemadm-systemadm.o -MD -MP -MF src/$(DEPDIR)/systemadm-systemadm.Tpo -c -o src/systemadm-systemadm.o `test -f 'src/systemadm.c' || echo '$(srcdir)/'`src/systemadm.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemadm-systemadm.Tpo src/$(DEPDIR)/systemadm-systemadm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/systemadm.c' object='src/systemadm-systemadm.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemadm_CFLAGS) $(CFLAGS) -c -o src/systemadm-systemadm.o `test -f 'src/systemadm.c' || echo '$(srcdir)/'`src/systemadm.c + +src/systemadm-systemadm.obj: src/systemadm.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemadm_CFLAGS) $(CFLAGS) -MT src/systemadm-systemadm.obj -MD -MP -MF src/$(DEPDIR)/systemadm-systemadm.Tpo -c -o src/systemadm-systemadm.obj `if test -f 'src/systemadm.c'; then $(CYGPATH_W) 'src/systemadm.c'; else $(CYGPATH_W) '$(srcdir)/src/systemadm.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemadm-systemadm.Tpo src/$(DEPDIR)/systemadm-systemadm.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/systemadm.c' object='src/systemadm-systemadm.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemadm_CFLAGS) $(CFLAGS) -c -o src/systemadm-systemadm.obj `if test -f 'src/systemadm.c'; then $(CYGPATH_W) 'src/systemadm.c'; else $(CYGPATH_W) '$(srcdir)/src/systemadm.c'; fi` + +src/systemadm-systemd-interfaces.o: src/systemd-interfaces.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemadm_CFLAGS) $(CFLAGS) -MT src/systemadm-systemd-interfaces.o -MD -MP -MF src/$(DEPDIR)/systemadm-systemd-interfaces.Tpo -c -o src/systemadm-systemd-interfaces.o `test -f 'src/systemd-interfaces.c' || echo '$(srcdir)/'`src/systemd-interfaces.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemadm-systemd-interfaces.Tpo src/$(DEPDIR)/systemadm-systemd-interfaces.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/systemd-interfaces.c' object='src/systemadm-systemd-interfaces.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemadm_CFLAGS) $(CFLAGS) -c -o src/systemadm-systemd-interfaces.o `test -f 'src/systemd-interfaces.c' || echo '$(srcdir)/'`src/systemd-interfaces.c + +src/systemadm-systemd-interfaces.obj: src/systemd-interfaces.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemadm_CFLAGS) $(CFLAGS) -MT src/systemadm-systemd-interfaces.obj -MD -MP -MF src/$(DEPDIR)/systemadm-systemd-interfaces.Tpo -c -o src/systemadm-systemd-interfaces.obj `if test -f 'src/systemd-interfaces.c'; then $(CYGPATH_W) 'src/systemd-interfaces.c'; else $(CYGPATH_W) '$(srcdir)/src/systemd-interfaces.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemadm-systemd-interfaces.Tpo src/$(DEPDIR)/systemadm-systemd-interfaces.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/systemd-interfaces.c' object='src/systemadm-systemd-interfaces.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemadm_CFLAGS) $(CFLAGS) -c -o src/systemadm-systemd-interfaces.obj `if test -f 'src/systemd-interfaces.c'; then $(CYGPATH_W) 'src/systemd-interfaces.c'; else $(CYGPATH_W) '$(srcdir)/src/systemd-interfaces.c'; fi` + +src/systemadm-wraplabel.o: src/wraplabel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemadm_CFLAGS) $(CFLAGS) -MT src/systemadm-wraplabel.o -MD -MP -MF src/$(DEPDIR)/systemadm-wraplabel.Tpo -c -o src/systemadm-wraplabel.o `test -f 'src/wraplabel.c' || echo '$(srcdir)/'`src/wraplabel.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemadm-wraplabel.Tpo src/$(DEPDIR)/systemadm-wraplabel.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/wraplabel.c' object='src/systemadm-wraplabel.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemadm_CFLAGS) $(CFLAGS) -c -o src/systemadm-wraplabel.o `test -f 'src/wraplabel.c' || echo '$(srcdir)/'`src/wraplabel.c + +src/systemadm-wraplabel.obj: src/wraplabel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemadm_CFLAGS) $(CFLAGS) -MT src/systemadm-wraplabel.obj -MD -MP -MF src/$(DEPDIR)/systemadm-wraplabel.Tpo -c -o src/systemadm-wraplabel.obj `if test -f 'src/wraplabel.c'; then $(CYGPATH_W) 'src/wraplabel.c'; else $(CYGPATH_W) '$(srcdir)/src/wraplabel.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemadm-wraplabel.Tpo src/$(DEPDIR)/systemadm-wraplabel.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/wraplabel.c' object='src/systemadm-wraplabel.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemadm_CFLAGS) $(CFLAGS) -c -o src/systemadm-wraplabel.obj `if test -f 'src/wraplabel.c'; then $(CYGPATH_W) 'src/wraplabel.c'; else $(CYGPATH_W) '$(srcdir)/src/wraplabel.c'; fi` + +src/systemctl-systemctl.o: src/systemctl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-systemctl.o -MD -MP -MF src/$(DEPDIR)/systemctl-systemctl.Tpo -c -o src/systemctl-systemctl.o `test -f 'src/systemctl.c' || echo '$(srcdir)/'`src/systemctl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-systemctl.Tpo src/$(DEPDIR)/systemctl-systemctl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/systemctl.c' object='src/systemctl-systemctl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-systemctl.o `test -f 'src/systemctl.c' || echo '$(srcdir)/'`src/systemctl.c + +src/systemctl-systemctl.obj: src/systemctl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-systemctl.obj -MD -MP -MF src/$(DEPDIR)/systemctl-systemctl.Tpo -c -o src/systemctl-systemctl.obj `if test -f 'src/systemctl.c'; then $(CYGPATH_W) 'src/systemctl.c'; else $(CYGPATH_W) '$(srcdir)/src/systemctl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-systemctl.Tpo src/$(DEPDIR)/systemctl-systemctl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/systemctl.c' object='src/systemctl-systemctl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-systemctl.obj `if test -f 'src/systemctl.c'; then $(CYGPATH_W) 'src/systemctl.c'; else $(CYGPATH_W) '$(srcdir)/src/systemctl.c'; fi` + +src/systemctl-utmp-wtmp.o: src/utmp-wtmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-utmp-wtmp.o -MD -MP -MF src/$(DEPDIR)/systemctl-utmp-wtmp.Tpo -c -o src/systemctl-utmp-wtmp.o `test -f 'src/utmp-wtmp.c' || echo '$(srcdir)/'`src/utmp-wtmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-utmp-wtmp.Tpo src/$(DEPDIR)/systemctl-utmp-wtmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/utmp-wtmp.c' object='src/systemctl-utmp-wtmp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-utmp-wtmp.o `test -f 'src/utmp-wtmp.c' || echo '$(srcdir)/'`src/utmp-wtmp.c + +src/systemctl-utmp-wtmp.obj: src/utmp-wtmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-utmp-wtmp.obj -MD -MP -MF src/$(DEPDIR)/systemctl-utmp-wtmp.Tpo -c -o src/systemctl-utmp-wtmp.obj `if test -f 'src/utmp-wtmp.c'; then $(CYGPATH_W) 'src/utmp-wtmp.c'; else $(CYGPATH_W) '$(srcdir)/src/utmp-wtmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-utmp-wtmp.Tpo src/$(DEPDIR)/systemctl-utmp-wtmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/utmp-wtmp.c' object='src/systemctl-utmp-wtmp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-utmp-wtmp.obj `if test -f 'src/utmp-wtmp.c'; then $(CYGPATH_W) 'src/utmp-wtmp.c'; else $(CYGPATH_W) '$(srcdir)/src/utmp-wtmp.c'; fi` + +src/systemctl-dbus-common.o: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-dbus-common.o -MD -MP -MF src/$(DEPDIR)/systemctl-dbus-common.Tpo -c -o src/systemctl-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-dbus-common.Tpo src/$(DEPDIR)/systemctl-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemctl-dbus-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c + +src/systemctl-dbus-common.obj: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-dbus-common.obj -MD -MP -MF src/$(DEPDIR)/systemctl-dbus-common.Tpo -c -o src/systemctl-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-dbus-common.Tpo src/$(DEPDIR)/systemctl-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemctl-dbus-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` + +src/systemctl-path-lookup.o: src/path-lookup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-path-lookup.o -MD -MP -MF src/$(DEPDIR)/systemctl-path-lookup.Tpo -c -o src/systemctl-path-lookup.o `test -f 'src/path-lookup.c' || echo '$(srcdir)/'`src/path-lookup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-path-lookup.Tpo src/$(DEPDIR)/systemctl-path-lookup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/path-lookup.c' object='src/systemctl-path-lookup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-path-lookup.o `test -f 'src/path-lookup.c' || echo '$(srcdir)/'`src/path-lookup.c + +src/systemctl-path-lookup.obj: src/path-lookup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-path-lookup.obj -MD -MP -MF src/$(DEPDIR)/systemctl-path-lookup.Tpo -c -o src/systemctl-path-lookup.obj `if test -f 'src/path-lookup.c'; then $(CYGPATH_W) 'src/path-lookup.c'; else $(CYGPATH_W) '$(srcdir)/src/path-lookup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-path-lookup.Tpo src/$(DEPDIR)/systemctl-path-lookup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/path-lookup.c' object='src/systemctl-path-lookup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-path-lookup.obj `if test -f 'src/path-lookup.c'; then $(CYGPATH_W) 'src/path-lookup.c'; else $(CYGPATH_W) '$(srcdir)/src/path-lookup.c'; fi` + +src/systemctl-cgroup-show.o: src/cgroup-show.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-cgroup-show.o -MD -MP -MF src/$(DEPDIR)/systemctl-cgroup-show.Tpo -c -o src/systemctl-cgroup-show.o `test -f 'src/cgroup-show.c' || echo '$(srcdir)/'`src/cgroup-show.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-cgroup-show.Tpo src/$(DEPDIR)/systemctl-cgroup-show.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-show.c' object='src/systemctl-cgroup-show.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-cgroup-show.o `test -f 'src/cgroup-show.c' || echo '$(srcdir)/'`src/cgroup-show.c + +src/systemctl-cgroup-show.obj: src/cgroup-show.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-cgroup-show.obj -MD -MP -MF src/$(DEPDIR)/systemctl-cgroup-show.Tpo -c -o src/systemctl-cgroup-show.obj `if test -f 'src/cgroup-show.c'; then $(CYGPATH_W) 'src/cgroup-show.c'; else $(CYGPATH_W) '$(srcdir)/src/cgroup-show.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-cgroup-show.Tpo src/$(DEPDIR)/systemctl-cgroup-show.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-show.c' object='src/systemctl-cgroup-show.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-cgroup-show.obj `if test -f 'src/cgroup-show.c'; then $(CYGPATH_W) 'src/cgroup-show.c'; else $(CYGPATH_W) '$(srcdir)/src/cgroup-show.c'; fi` + +src/systemctl-cgroup-util.o: src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-cgroup-util.o -MD -MP -MF src/$(DEPDIR)/systemctl-cgroup-util.Tpo -c -o src/systemctl-cgroup-util.o `test -f 'src/cgroup-util.c' || echo '$(srcdir)/'`src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-cgroup-util.Tpo src/$(DEPDIR)/systemctl-cgroup-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-util.c' object='src/systemctl-cgroup-util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-cgroup-util.o `test -f 'src/cgroup-util.c' || echo '$(srcdir)/'`src/cgroup-util.c + +src/systemctl-cgroup-util.obj: src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-cgroup-util.obj -MD -MP -MF src/$(DEPDIR)/systemctl-cgroup-util.Tpo -c -o src/systemctl-cgroup-util.obj `if test -f 'src/cgroup-util.c'; then $(CYGPATH_W) 'src/cgroup-util.c'; else $(CYGPATH_W) '$(srcdir)/src/cgroup-util.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-cgroup-util.Tpo src/$(DEPDIR)/systemctl-cgroup-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-util.c' object='src/systemctl-cgroup-util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-cgroup-util.obj `if test -f 'src/cgroup-util.c'; then $(CYGPATH_W) 'src/cgroup-util.c'; else $(CYGPATH_W) '$(srcdir)/src/cgroup-util.c'; fi` + +src/systemctl-exit-status.o: src/exit-status.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-exit-status.o -MD -MP -MF src/$(DEPDIR)/systemctl-exit-status.Tpo -c -o src/systemctl-exit-status.o `test -f 'src/exit-status.c' || echo '$(srcdir)/'`src/exit-status.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-exit-status.Tpo src/$(DEPDIR)/systemctl-exit-status.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/exit-status.c' object='src/systemctl-exit-status.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-exit-status.o `test -f 'src/exit-status.c' || echo '$(srcdir)/'`src/exit-status.c + +src/systemctl-exit-status.obj: src/exit-status.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-exit-status.obj -MD -MP -MF src/$(DEPDIR)/systemctl-exit-status.Tpo -c -o src/systemctl-exit-status.obj `if test -f 'src/exit-status.c'; then $(CYGPATH_W) 'src/exit-status.c'; else $(CYGPATH_W) '$(srcdir)/src/exit-status.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-exit-status.Tpo src/$(DEPDIR)/systemctl-exit-status.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/exit-status.c' object='src/systemctl-exit-status.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-exit-status.obj `if test -f 'src/exit-status.c'; then $(CYGPATH_W) 'src/exit-status.c'; else $(CYGPATH_W) '$(srcdir)/src/exit-status.c'; fi` + +src/systemctl-unit-name.o: src/unit-name.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-unit-name.o -MD -MP -MF src/$(DEPDIR)/systemctl-unit-name.Tpo -c -o src/systemctl-unit-name.o `test -f 'src/unit-name.c' || echo '$(srcdir)/'`src/unit-name.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-unit-name.Tpo src/$(DEPDIR)/systemctl-unit-name.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/unit-name.c' object='src/systemctl-unit-name.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-unit-name.o `test -f 'src/unit-name.c' || echo '$(srcdir)/'`src/unit-name.c + +src/systemctl-unit-name.obj: src/unit-name.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-unit-name.obj -MD -MP -MF src/$(DEPDIR)/systemctl-unit-name.Tpo -c -o src/systemctl-unit-name.obj `if test -f 'src/unit-name.c'; then $(CYGPATH_W) 'src/unit-name.c'; else $(CYGPATH_W) '$(srcdir)/src/unit-name.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-unit-name.Tpo src/$(DEPDIR)/systemctl-unit-name.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/unit-name.c' object='src/systemctl-unit-name.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-unit-name.obj `if test -f 'src/unit-name.c'; then $(CYGPATH_W) 'src/unit-name.c'; else $(CYGPATH_W) '$(srcdir)/src/unit-name.c'; fi` + +src/systemctl-pager.o: src/pager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-pager.o -MD -MP -MF src/$(DEPDIR)/systemctl-pager.Tpo -c -o src/systemctl-pager.o `test -f 'src/pager.c' || echo '$(srcdir)/'`src/pager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-pager.Tpo src/$(DEPDIR)/systemctl-pager.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pager.c' object='src/systemctl-pager.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-pager.o `test -f 'src/pager.c' || echo '$(srcdir)/'`src/pager.c + +src/systemctl-pager.obj: src/pager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-pager.obj -MD -MP -MF src/$(DEPDIR)/systemctl-pager.Tpo -c -o src/systemctl-pager.obj `if test -f 'src/pager.c'; then $(CYGPATH_W) 'src/pager.c'; else $(CYGPATH_W) '$(srcdir)/src/pager.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-pager.Tpo src/$(DEPDIR)/systemctl-pager.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pager.c' object='src/systemctl-pager.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-pager.obj `if test -f 'src/pager.c'; then $(CYGPATH_W) 'src/pager.c'; else $(CYGPATH_W) '$(srcdir)/src/pager.c'; fi` + +src/systemctl-install.o: src/install.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-install.o -MD -MP -MF src/$(DEPDIR)/systemctl-install.Tpo -c -o src/systemctl-install.o `test -f 'src/install.c' || echo '$(srcdir)/'`src/install.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-install.Tpo src/$(DEPDIR)/systemctl-install.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/install.c' object='src/systemctl-install.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-install.o `test -f 'src/install.c' || echo '$(srcdir)/'`src/install.c + +src/systemctl-install.obj: src/install.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-install.obj -MD -MP -MF src/$(DEPDIR)/systemctl-install.Tpo -c -o src/systemctl-install.obj `if test -f 'src/install.c'; then $(CYGPATH_W) 'src/install.c'; else $(CYGPATH_W) '$(srcdir)/src/install.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-install.Tpo src/$(DEPDIR)/systemctl-install.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/install.c' object='src/systemctl-install.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-install.obj `if test -f 'src/install.c'; then $(CYGPATH_W) 'src/install.c'; else $(CYGPATH_W) '$(srcdir)/src/install.c'; fi` + +src/systemctl-spawn-agent.o: src/spawn-agent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-spawn-agent.o -MD -MP -MF src/$(DEPDIR)/systemctl-spawn-agent.Tpo -c -o src/systemctl-spawn-agent.o `test -f 'src/spawn-agent.c' || echo '$(srcdir)/'`src/spawn-agent.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-spawn-agent.Tpo src/$(DEPDIR)/systemctl-spawn-agent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/spawn-agent.c' object='src/systemctl-spawn-agent.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-spawn-agent.o `test -f 'src/spawn-agent.c' || echo '$(srcdir)/'`src/spawn-agent.c + +src/systemctl-spawn-agent.obj: src/spawn-agent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-spawn-agent.obj -MD -MP -MF src/$(DEPDIR)/systemctl-spawn-agent.Tpo -c -o src/systemctl-spawn-agent.obj `if test -f 'src/spawn-agent.c'; then $(CYGPATH_W) 'src/spawn-agent.c'; else $(CYGPATH_W) '$(srcdir)/src/spawn-agent.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-spawn-agent.Tpo src/$(DEPDIR)/systemctl-spawn-agent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/spawn-agent.c' object='src/systemctl-spawn-agent.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-spawn-agent.obj `if test -f 'src/spawn-agent.c'; then $(CYGPATH_W) 'src/spawn-agent.c'; else $(CYGPATH_W) '$(srcdir)/src/spawn-agent.c'; fi` + +src/systemctl-logs-show.o: src/logs-show.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-logs-show.o -MD -MP -MF src/$(DEPDIR)/systemctl-logs-show.Tpo -c -o src/systemctl-logs-show.o `test -f 'src/logs-show.c' || echo '$(srcdir)/'`src/logs-show.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-logs-show.Tpo src/$(DEPDIR)/systemctl-logs-show.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/logs-show.c' object='src/systemctl-logs-show.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-logs-show.o `test -f 'src/logs-show.c' || echo '$(srcdir)/'`src/logs-show.c + +src/systemctl-logs-show.obj: src/logs-show.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -MT src/systemctl-logs-show.obj -MD -MP -MF src/$(DEPDIR)/systemctl-logs-show.Tpo -c -o src/systemctl-logs-show.obj `if test -f 'src/logs-show.c'; then $(CYGPATH_W) 'src/logs-show.c'; else $(CYGPATH_W) '$(srcdir)/src/logs-show.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemctl-logs-show.Tpo src/$(DEPDIR)/systemctl-logs-show.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/logs-show.c' object='src/systemctl-logs-show.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemctl_CFLAGS) $(CFLAGS) -c -o src/systemctl-logs-show.obj `if test -f 'src/logs-show.c'; then $(CYGPATH_W) 'src/logs-show.c'; else $(CYGPATH_W) '$(srcdir)/src/logs-show.c'; fi` + +src/systemd-main.o: src/main.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_CFLAGS) $(CFLAGS) -MT src/systemd-main.o -MD -MP -MF src/$(DEPDIR)/systemd-main.Tpo -c -o src/systemd-main.o `test -f 'src/main.c' || echo '$(srcdir)/'`src/main.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd-main.Tpo src/$(DEPDIR)/systemd-main.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/main.c' object='src/systemd-main.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_CFLAGS) $(CFLAGS) -c -o src/systemd-main.o `test -f 'src/main.c' || echo '$(srcdir)/'`src/main.c + +src/systemd-main.obj: src/main.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_CFLAGS) $(CFLAGS) -MT src/systemd-main.obj -MD -MP -MF src/$(DEPDIR)/systemd-main.Tpo -c -o src/systemd-main.obj `if test -f 'src/main.c'; then $(CYGPATH_W) 'src/main.c'; else $(CYGPATH_W) '$(srcdir)/src/main.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd-main.Tpo src/$(DEPDIR)/systemd-main.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/main.c' object='src/systemd-main.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_CFLAGS) $(CFLAGS) -c -o src/systemd-main.obj `if test -f 'src/main.c'; then $(CYGPATH_W) 'src/main.c'; else $(CYGPATH_W) '$(srcdir)/src/main.c'; fi` + +src/systemd_ac_power-ac-power.o: src/ac-power.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_ac_power_CFLAGS) $(CFLAGS) -MT src/systemd_ac_power-ac-power.o -MD -MP -MF src/$(DEPDIR)/systemd_ac_power-ac-power.Tpo -c -o src/systemd_ac_power-ac-power.o `test -f 'src/ac-power.c' || echo '$(srcdir)/'`src/ac-power.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_ac_power-ac-power.Tpo src/$(DEPDIR)/systemd_ac_power-ac-power.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ac-power.c' object='src/systemd_ac_power-ac-power.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_ac_power_CFLAGS) $(CFLAGS) -c -o src/systemd_ac_power-ac-power.o `test -f 'src/ac-power.c' || echo '$(srcdir)/'`src/ac-power.c + +src/systemd_ac_power-ac-power.obj: src/ac-power.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_ac_power_CFLAGS) $(CFLAGS) -MT src/systemd_ac_power-ac-power.obj -MD -MP -MF src/$(DEPDIR)/systemd_ac_power-ac-power.Tpo -c -o src/systemd_ac_power-ac-power.obj `if test -f 'src/ac-power.c'; then $(CYGPATH_W) 'src/ac-power.c'; else $(CYGPATH_W) '$(srcdir)/src/ac-power.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_ac_power-ac-power.Tpo src/$(DEPDIR)/systemd_ac_power-ac-power.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ac-power.c' object='src/systemd_ac_power-ac-power.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_ac_power_CFLAGS) $(CFLAGS) -c -o src/systemd_ac_power-ac-power.obj `if test -f 'src/ac-power.c'; then $(CYGPATH_W) 'src/ac-power.c'; else $(CYGPATH_W) '$(srcdir)/src/ac-power.c'; fi` + +src/systemd_cgroups_agent-cgroups-agent.o: src/cgroups-agent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cgroups_agent_CFLAGS) $(CFLAGS) -MT src/systemd_cgroups_agent-cgroups-agent.o -MD -MP -MF src/$(DEPDIR)/systemd_cgroups_agent-cgroups-agent.Tpo -c -o src/systemd_cgroups_agent-cgroups-agent.o `test -f 'src/cgroups-agent.c' || echo '$(srcdir)/'`src/cgroups-agent.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_cgroups_agent-cgroups-agent.Tpo src/$(DEPDIR)/systemd_cgroups_agent-cgroups-agent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroups-agent.c' object='src/systemd_cgroups_agent-cgroups-agent.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cgroups_agent_CFLAGS) $(CFLAGS) -c -o src/systemd_cgroups_agent-cgroups-agent.o `test -f 'src/cgroups-agent.c' || echo '$(srcdir)/'`src/cgroups-agent.c + +src/systemd_cgroups_agent-cgroups-agent.obj: src/cgroups-agent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cgroups_agent_CFLAGS) $(CFLAGS) -MT src/systemd_cgroups_agent-cgroups-agent.obj -MD -MP -MF src/$(DEPDIR)/systemd_cgroups_agent-cgroups-agent.Tpo -c -o src/systemd_cgroups_agent-cgroups-agent.obj `if test -f 'src/cgroups-agent.c'; then $(CYGPATH_W) 'src/cgroups-agent.c'; else $(CYGPATH_W) '$(srcdir)/src/cgroups-agent.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_cgroups_agent-cgroups-agent.Tpo src/$(DEPDIR)/systemd_cgroups_agent-cgroups-agent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroups-agent.c' object='src/systemd_cgroups_agent-cgroups-agent.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cgroups_agent_CFLAGS) $(CFLAGS) -c -o src/systemd_cgroups_agent-cgroups-agent.obj `if test -f 'src/cgroups-agent.c'; then $(CYGPATH_W) 'src/cgroups-agent.c'; else $(CYGPATH_W) '$(srcdir)/src/cgroups-agent.c'; fi` + +src/systemd_cgroups_agent-dbus-common.o: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cgroups_agent_CFLAGS) $(CFLAGS) -MT src/systemd_cgroups_agent-dbus-common.o -MD -MP -MF src/$(DEPDIR)/systemd_cgroups_agent-dbus-common.Tpo -c -o src/systemd_cgroups_agent-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_cgroups_agent-dbus-common.Tpo src/$(DEPDIR)/systemd_cgroups_agent-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_cgroups_agent-dbus-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cgroups_agent_CFLAGS) $(CFLAGS) -c -o src/systemd_cgroups_agent-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c + +src/systemd_cgroups_agent-dbus-common.obj: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cgroups_agent_CFLAGS) $(CFLAGS) -MT src/systemd_cgroups_agent-dbus-common.obj -MD -MP -MF src/$(DEPDIR)/systemd_cgroups_agent-dbus-common.Tpo -c -o src/systemd_cgroups_agent-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_cgroups_agent-dbus-common.Tpo src/$(DEPDIR)/systemd_cgroups_agent-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_cgroups_agent-dbus-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cgroups_agent_CFLAGS) $(CFLAGS) -c -o src/systemd_cgroups_agent-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` + +src/cryptsetup/systemd_cryptsetup-cryptsetup.o: src/cryptsetup/cryptsetup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cryptsetup_CFLAGS) $(CFLAGS) -MT src/cryptsetup/systemd_cryptsetup-cryptsetup.o -MD -MP -MF src/cryptsetup/$(DEPDIR)/systemd_cryptsetup-cryptsetup.Tpo -c -o src/cryptsetup/systemd_cryptsetup-cryptsetup.o `test -f 'src/cryptsetup/cryptsetup.c' || echo '$(srcdir)/'`src/cryptsetup/cryptsetup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/cryptsetup/$(DEPDIR)/systemd_cryptsetup-cryptsetup.Tpo src/cryptsetup/$(DEPDIR)/systemd_cryptsetup-cryptsetup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cryptsetup/cryptsetup.c' object='src/cryptsetup/systemd_cryptsetup-cryptsetup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cryptsetup_CFLAGS) $(CFLAGS) -c -o src/cryptsetup/systemd_cryptsetup-cryptsetup.o `test -f 'src/cryptsetup/cryptsetup.c' || echo '$(srcdir)/'`src/cryptsetup/cryptsetup.c + +src/cryptsetup/systemd_cryptsetup-cryptsetup.obj: src/cryptsetup/cryptsetup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cryptsetup_CFLAGS) $(CFLAGS) -MT src/cryptsetup/systemd_cryptsetup-cryptsetup.obj -MD -MP -MF src/cryptsetup/$(DEPDIR)/systemd_cryptsetup-cryptsetup.Tpo -c -o src/cryptsetup/systemd_cryptsetup-cryptsetup.obj `if test -f 'src/cryptsetup/cryptsetup.c'; then $(CYGPATH_W) 'src/cryptsetup/cryptsetup.c'; else $(CYGPATH_W) '$(srcdir)/src/cryptsetup/cryptsetup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/cryptsetup/$(DEPDIR)/systemd_cryptsetup-cryptsetup.Tpo src/cryptsetup/$(DEPDIR)/systemd_cryptsetup-cryptsetup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cryptsetup/cryptsetup.c' object='src/cryptsetup/systemd_cryptsetup-cryptsetup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cryptsetup_CFLAGS) $(CFLAGS) -c -o src/cryptsetup/systemd_cryptsetup-cryptsetup.obj `if test -f 'src/cryptsetup/cryptsetup.c'; then $(CYGPATH_W) 'src/cryptsetup/cryptsetup.c'; else $(CYGPATH_W) '$(srcdir)/src/cryptsetup/cryptsetup.c'; fi` + +src/systemd_cryptsetup-ask-password-api.o: src/ask-password-api.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cryptsetup_CFLAGS) $(CFLAGS) -MT src/systemd_cryptsetup-ask-password-api.o -MD -MP -MF src/$(DEPDIR)/systemd_cryptsetup-ask-password-api.Tpo -c -o src/systemd_cryptsetup-ask-password-api.o `test -f 'src/ask-password-api.c' || echo '$(srcdir)/'`src/ask-password-api.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_cryptsetup-ask-password-api.Tpo src/$(DEPDIR)/systemd_cryptsetup-ask-password-api.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ask-password-api.c' object='src/systemd_cryptsetup-ask-password-api.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cryptsetup_CFLAGS) $(CFLAGS) -c -o src/systemd_cryptsetup-ask-password-api.o `test -f 'src/ask-password-api.c' || echo '$(srcdir)/'`src/ask-password-api.c + +src/systemd_cryptsetup-ask-password-api.obj: src/ask-password-api.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cryptsetup_CFLAGS) $(CFLAGS) -MT src/systemd_cryptsetup-ask-password-api.obj -MD -MP -MF src/$(DEPDIR)/systemd_cryptsetup-ask-password-api.Tpo -c -o src/systemd_cryptsetup-ask-password-api.obj `if test -f 'src/ask-password-api.c'; then $(CYGPATH_W) 'src/ask-password-api.c'; else $(CYGPATH_W) '$(srcdir)/src/ask-password-api.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_cryptsetup-ask-password-api.Tpo src/$(DEPDIR)/systemd_cryptsetup-ask-password-api.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ask-password-api.c' object='src/systemd_cryptsetup-ask-password-api.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_cryptsetup_CFLAGS) $(CFLAGS) -c -o src/systemd_cryptsetup-ask-password-api.obj `if test -f 'src/ask-password-api.c'; then $(CYGPATH_W) 'src/ask-password-api.c'; else $(CYGPATH_W) '$(srcdir)/src/ask-password-api.c'; fi` + +src/systemd_fsck-fsck.o: src/fsck.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_fsck_CFLAGS) $(CFLAGS) -MT src/systemd_fsck-fsck.o -MD -MP -MF src/$(DEPDIR)/systemd_fsck-fsck.Tpo -c -o src/systemd_fsck-fsck.o `test -f 'src/fsck.c' || echo '$(srcdir)/'`src/fsck.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_fsck-fsck.Tpo src/$(DEPDIR)/systemd_fsck-fsck.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/fsck.c' object='src/systemd_fsck-fsck.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_fsck_CFLAGS) $(CFLAGS) -c -o src/systemd_fsck-fsck.o `test -f 'src/fsck.c' || echo '$(srcdir)/'`src/fsck.c + +src/systemd_fsck-fsck.obj: src/fsck.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_fsck_CFLAGS) $(CFLAGS) -MT src/systemd_fsck-fsck.obj -MD -MP -MF src/$(DEPDIR)/systemd_fsck-fsck.Tpo -c -o src/systemd_fsck-fsck.obj `if test -f 'src/fsck.c'; then $(CYGPATH_W) 'src/fsck.c'; else $(CYGPATH_W) '$(srcdir)/src/fsck.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_fsck-fsck.Tpo src/$(DEPDIR)/systemd_fsck-fsck.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/fsck.c' object='src/systemd_fsck-fsck.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_fsck_CFLAGS) $(CFLAGS) -c -o src/systemd_fsck-fsck.obj `if test -f 'src/fsck.c'; then $(CYGPATH_W) 'src/fsck.c'; else $(CYGPATH_W) '$(srcdir)/src/fsck.c'; fi` + +src/systemd_fsck-dbus-common.o: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_fsck_CFLAGS) $(CFLAGS) -MT src/systemd_fsck-dbus-common.o -MD -MP -MF src/$(DEPDIR)/systemd_fsck-dbus-common.Tpo -c -o src/systemd_fsck-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_fsck-dbus-common.Tpo src/$(DEPDIR)/systemd_fsck-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_fsck-dbus-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_fsck_CFLAGS) $(CFLAGS) -c -o src/systemd_fsck-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c + +src/systemd_fsck-dbus-common.obj: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_fsck_CFLAGS) $(CFLAGS) -MT src/systemd_fsck-dbus-common.obj -MD -MP -MF src/$(DEPDIR)/systemd_fsck-dbus-common.Tpo -c -o src/systemd_fsck-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_fsck-dbus-common.Tpo src/$(DEPDIR)/systemd_fsck-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_fsck-dbus-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_fsck_CFLAGS) $(CFLAGS) -c -o src/systemd_fsck-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` + +src/systemd_gnome_ask_password_agent-gnome-ask-password-agent.o: src/gnome-ask-password-agent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_gnome_ask_password_agent_CFLAGS) $(CFLAGS) -MT src/systemd_gnome_ask_password_agent-gnome-ask-password-agent.o -MD -MP -MF src/$(DEPDIR)/systemd_gnome_ask_password_agent-gnome-ask-password-agent.Tpo -c -o src/systemd_gnome_ask_password_agent-gnome-ask-password-agent.o `test -f 'src/gnome-ask-password-agent.c' || echo '$(srcdir)/'`src/gnome-ask-password-agent.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_gnome_ask_password_agent-gnome-ask-password-agent.Tpo src/$(DEPDIR)/systemd_gnome_ask_password_agent-gnome-ask-password-agent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/gnome-ask-password-agent.c' object='src/systemd_gnome_ask_password_agent-gnome-ask-password-agent.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_gnome_ask_password_agent_CFLAGS) $(CFLAGS) -c -o src/systemd_gnome_ask_password_agent-gnome-ask-password-agent.o `test -f 'src/gnome-ask-password-agent.c' || echo '$(srcdir)/'`src/gnome-ask-password-agent.c + +src/systemd_gnome_ask_password_agent-gnome-ask-password-agent.obj: src/gnome-ask-password-agent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_gnome_ask_password_agent_CFLAGS) $(CFLAGS) -MT src/systemd_gnome_ask_password_agent-gnome-ask-password-agent.obj -MD -MP -MF src/$(DEPDIR)/systemd_gnome_ask_password_agent-gnome-ask-password-agent.Tpo -c -o src/systemd_gnome_ask_password_agent-gnome-ask-password-agent.obj `if test -f 'src/gnome-ask-password-agent.c'; then $(CYGPATH_W) 'src/gnome-ask-password-agent.c'; else $(CYGPATH_W) '$(srcdir)/src/gnome-ask-password-agent.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_gnome_ask_password_agent-gnome-ask-password-agent.Tpo src/$(DEPDIR)/systemd_gnome_ask_password_agent-gnome-ask-password-agent.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/gnome-ask-password-agent.c' object='src/systemd_gnome_ask_password_agent-gnome-ask-password-agent.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_gnome_ask_password_agent_CFLAGS) $(CFLAGS) -c -o src/systemd_gnome_ask_password_agent-gnome-ask-password-agent.obj `if test -f 'src/gnome-ask-password-agent.c'; then $(CYGPATH_W) 'src/gnome-ask-password-agent.c'; else $(CYGPATH_W) '$(srcdir)/src/gnome-ask-password-agent.c'; fi` + +src/hostname/systemd_hostnamed-hostnamed.o: src/hostname/hostnamed.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_hostnamed_CFLAGS) $(CFLAGS) -MT src/hostname/systemd_hostnamed-hostnamed.o -MD -MP -MF src/hostname/$(DEPDIR)/systemd_hostnamed-hostnamed.Tpo -c -o src/hostname/systemd_hostnamed-hostnamed.o `test -f 'src/hostname/hostnamed.c' || echo '$(srcdir)/'`src/hostname/hostnamed.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/hostname/$(DEPDIR)/systemd_hostnamed-hostnamed.Tpo src/hostname/$(DEPDIR)/systemd_hostnamed-hostnamed.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/hostname/hostnamed.c' object='src/hostname/systemd_hostnamed-hostnamed.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_hostnamed_CFLAGS) $(CFLAGS) -c -o src/hostname/systemd_hostnamed-hostnamed.o `test -f 'src/hostname/hostnamed.c' || echo '$(srcdir)/'`src/hostname/hostnamed.c + +src/hostname/systemd_hostnamed-hostnamed.obj: src/hostname/hostnamed.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_hostnamed_CFLAGS) $(CFLAGS) -MT src/hostname/systemd_hostnamed-hostnamed.obj -MD -MP -MF src/hostname/$(DEPDIR)/systemd_hostnamed-hostnamed.Tpo -c -o src/hostname/systemd_hostnamed-hostnamed.obj `if test -f 'src/hostname/hostnamed.c'; then $(CYGPATH_W) 'src/hostname/hostnamed.c'; else $(CYGPATH_W) '$(srcdir)/src/hostname/hostnamed.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/hostname/$(DEPDIR)/systemd_hostnamed-hostnamed.Tpo src/hostname/$(DEPDIR)/systemd_hostnamed-hostnamed.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/hostname/hostnamed.c' object='src/hostname/systemd_hostnamed-hostnamed.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_hostnamed_CFLAGS) $(CFLAGS) -c -o src/hostname/systemd_hostnamed-hostnamed.obj `if test -f 'src/hostname/hostnamed.c'; then $(CYGPATH_W) 'src/hostname/hostnamed.c'; else $(CYGPATH_W) '$(srcdir)/src/hostname/hostnamed.c'; fi` + +src/systemd_hostnamed-dbus-common.o: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_hostnamed_CFLAGS) $(CFLAGS) -MT src/systemd_hostnamed-dbus-common.o -MD -MP -MF src/$(DEPDIR)/systemd_hostnamed-dbus-common.Tpo -c -o src/systemd_hostnamed-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_hostnamed-dbus-common.Tpo src/$(DEPDIR)/systemd_hostnamed-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_hostnamed-dbus-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_hostnamed_CFLAGS) $(CFLAGS) -c -o src/systemd_hostnamed-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c + +src/systemd_hostnamed-dbus-common.obj: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_hostnamed_CFLAGS) $(CFLAGS) -MT src/systemd_hostnamed-dbus-common.obj -MD -MP -MF src/$(DEPDIR)/systemd_hostnamed-dbus-common.Tpo -c -o src/systemd_hostnamed-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_hostnamed-dbus-common.Tpo src/$(DEPDIR)/systemd_hostnamed-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_hostnamed-dbus-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_hostnamed_CFLAGS) $(CFLAGS) -c -o src/systemd_hostnamed-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` + +src/systemd_hostnamed-polkit.o: src/polkit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_hostnamed_CFLAGS) $(CFLAGS) -MT src/systemd_hostnamed-polkit.o -MD -MP -MF src/$(DEPDIR)/systemd_hostnamed-polkit.Tpo -c -o src/systemd_hostnamed-polkit.o `test -f 'src/polkit.c' || echo '$(srcdir)/'`src/polkit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_hostnamed-polkit.Tpo src/$(DEPDIR)/systemd_hostnamed-polkit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/polkit.c' object='src/systemd_hostnamed-polkit.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_hostnamed_CFLAGS) $(CFLAGS) -c -o src/systemd_hostnamed-polkit.o `test -f 'src/polkit.c' || echo '$(srcdir)/'`src/polkit.c + +src/systemd_hostnamed-polkit.obj: src/polkit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_hostnamed_CFLAGS) $(CFLAGS) -MT src/systemd_hostnamed-polkit.obj -MD -MP -MF src/$(DEPDIR)/systemd_hostnamed-polkit.Tpo -c -o src/systemd_hostnamed-polkit.obj `if test -f 'src/polkit.c'; then $(CYGPATH_W) 'src/polkit.c'; else $(CYGPATH_W) '$(srcdir)/src/polkit.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_hostnamed-polkit.Tpo src/$(DEPDIR)/systemd_hostnamed-polkit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/polkit.c' object='src/systemd_hostnamed-polkit.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_hostnamed_CFLAGS) $(CFLAGS) -c -o src/systemd_hostnamed-polkit.obj `if test -f 'src/polkit.c'; then $(CYGPATH_W) 'src/polkit.c'; else $(CYGPATH_W) '$(srcdir)/src/polkit.c'; fi` + +src/systemd_initctl-initctl.o: src/initctl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_initctl_CFLAGS) $(CFLAGS) -MT src/systemd_initctl-initctl.o -MD -MP -MF src/$(DEPDIR)/systemd_initctl-initctl.Tpo -c -o src/systemd_initctl-initctl.o `test -f 'src/initctl.c' || echo '$(srcdir)/'`src/initctl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_initctl-initctl.Tpo src/$(DEPDIR)/systemd_initctl-initctl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/initctl.c' object='src/systemd_initctl-initctl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_initctl_CFLAGS) $(CFLAGS) -c -o src/systemd_initctl-initctl.o `test -f 'src/initctl.c' || echo '$(srcdir)/'`src/initctl.c + +src/systemd_initctl-initctl.obj: src/initctl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_initctl_CFLAGS) $(CFLAGS) -MT src/systemd_initctl-initctl.obj -MD -MP -MF src/$(DEPDIR)/systemd_initctl-initctl.Tpo -c -o src/systemd_initctl-initctl.obj `if test -f 'src/initctl.c'; then $(CYGPATH_W) 'src/initctl.c'; else $(CYGPATH_W) '$(srcdir)/src/initctl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_initctl-initctl.Tpo src/$(DEPDIR)/systemd_initctl-initctl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/initctl.c' object='src/systemd_initctl-initctl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_initctl_CFLAGS) $(CFLAGS) -c -o src/systemd_initctl-initctl.obj `if test -f 'src/initctl.c'; then $(CYGPATH_W) 'src/initctl.c'; else $(CYGPATH_W) '$(srcdir)/src/initctl.c'; fi` + +src/systemd_initctl-dbus-common.o: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_initctl_CFLAGS) $(CFLAGS) -MT src/systemd_initctl-dbus-common.o -MD -MP -MF src/$(DEPDIR)/systemd_initctl-dbus-common.Tpo -c -o src/systemd_initctl-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_initctl-dbus-common.Tpo src/$(DEPDIR)/systemd_initctl-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_initctl-dbus-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_initctl_CFLAGS) $(CFLAGS) -c -o src/systemd_initctl-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c + +src/systemd_initctl-dbus-common.obj: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_initctl_CFLAGS) $(CFLAGS) -MT src/systemd_initctl-dbus-common.obj -MD -MP -MF src/$(DEPDIR)/systemd_initctl-dbus-common.Tpo -c -o src/systemd_initctl-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_initctl-dbus-common.Tpo src/$(DEPDIR)/systemd_initctl-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_initctl-dbus-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_initctl_CFLAGS) $(CFLAGS) -c -o src/systemd_initctl-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` + +src/journal/systemd_journalctl-journalctl.o: src/journal/journalctl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journalctl-journalctl.o -MD -MP -MF src/journal/$(DEPDIR)/systemd_journalctl-journalctl.Tpo -c -o src/journal/systemd_journalctl-journalctl.o `test -f 'src/journal/journalctl.c' || echo '$(srcdir)/'`src/journal/journalctl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journalctl-journalctl.Tpo src/journal/$(DEPDIR)/systemd_journalctl-journalctl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journalctl.c' object='src/journal/systemd_journalctl-journalctl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journalctl-journalctl.o `test -f 'src/journal/journalctl.c' || echo '$(srcdir)/'`src/journal/journalctl.c + +src/journal/systemd_journalctl-journalctl.obj: src/journal/journalctl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journalctl-journalctl.obj -MD -MP -MF src/journal/$(DEPDIR)/systemd_journalctl-journalctl.Tpo -c -o src/journal/systemd_journalctl-journalctl.obj `if test -f 'src/journal/journalctl.c'; then $(CYGPATH_W) 'src/journal/journalctl.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/journalctl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journalctl-journalctl.Tpo src/journal/$(DEPDIR)/systemd_journalctl-journalctl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journalctl.c' object='src/journal/systemd_journalctl-journalctl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journalctl-journalctl.obj `if test -f 'src/journal/journalctl.c'; then $(CYGPATH_W) 'src/journal/journalctl.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/journalctl.c'; fi` + +src/systemd_journalctl-pager.o: src/pager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -MT src/systemd_journalctl-pager.o -MD -MP -MF src/$(DEPDIR)/systemd_journalctl-pager.Tpo -c -o src/systemd_journalctl-pager.o `test -f 'src/pager.c' || echo '$(srcdir)/'`src/pager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_journalctl-pager.Tpo src/$(DEPDIR)/systemd_journalctl-pager.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pager.c' object='src/systemd_journalctl-pager.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -c -o src/systemd_journalctl-pager.o `test -f 'src/pager.c' || echo '$(srcdir)/'`src/pager.c + +src/systemd_journalctl-pager.obj: src/pager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -MT src/systemd_journalctl-pager.obj -MD -MP -MF src/$(DEPDIR)/systemd_journalctl-pager.Tpo -c -o src/systemd_journalctl-pager.obj `if test -f 'src/pager.c'; then $(CYGPATH_W) 'src/pager.c'; else $(CYGPATH_W) '$(srcdir)/src/pager.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_journalctl-pager.Tpo src/$(DEPDIR)/systemd_journalctl-pager.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pager.c' object='src/systemd_journalctl-pager.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -c -o src/systemd_journalctl-pager.obj `if test -f 'src/pager.c'; then $(CYGPATH_W) 'src/pager.c'; else $(CYGPATH_W) '$(srcdir)/src/pager.c'; fi` + +src/systemd_journalctl-logs-show.o: src/logs-show.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -MT src/systemd_journalctl-logs-show.o -MD -MP -MF src/$(DEPDIR)/systemd_journalctl-logs-show.Tpo -c -o src/systemd_journalctl-logs-show.o `test -f 'src/logs-show.c' || echo '$(srcdir)/'`src/logs-show.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_journalctl-logs-show.Tpo src/$(DEPDIR)/systemd_journalctl-logs-show.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/logs-show.c' object='src/systemd_journalctl-logs-show.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -c -o src/systemd_journalctl-logs-show.o `test -f 'src/logs-show.c' || echo '$(srcdir)/'`src/logs-show.c + +src/systemd_journalctl-logs-show.obj: src/logs-show.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -MT src/systemd_journalctl-logs-show.obj -MD -MP -MF src/$(DEPDIR)/systemd_journalctl-logs-show.Tpo -c -o src/systemd_journalctl-logs-show.obj `if test -f 'src/logs-show.c'; then $(CYGPATH_W) 'src/logs-show.c'; else $(CYGPATH_W) '$(srcdir)/src/logs-show.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_journalctl-logs-show.Tpo src/$(DEPDIR)/systemd_journalctl-logs-show.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/logs-show.c' object='src/systemd_journalctl-logs-show.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -c -o src/systemd_journalctl-logs-show.obj `if test -f 'src/logs-show.c'; then $(CYGPATH_W) 'src/logs-show.c'; else $(CYGPATH_W) '$(srcdir)/src/logs-show.c'; fi` + +src/journal/systemd_journalctl-compress.o: src/journal/compress.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journalctl-compress.o -MD -MP -MF src/journal/$(DEPDIR)/systemd_journalctl-compress.Tpo -c -o src/journal/systemd_journalctl-compress.o `test -f 'src/journal/compress.c' || echo '$(srcdir)/'`src/journal/compress.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journalctl-compress.Tpo src/journal/$(DEPDIR)/systemd_journalctl-compress.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/compress.c' object='src/journal/systemd_journalctl-compress.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journalctl-compress.o `test -f 'src/journal/compress.c' || echo '$(srcdir)/'`src/journal/compress.c + +src/journal/systemd_journalctl-compress.obj: src/journal/compress.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journalctl-compress.obj -MD -MP -MF src/journal/$(DEPDIR)/systemd_journalctl-compress.Tpo -c -o src/journal/systemd_journalctl-compress.obj `if test -f 'src/journal/compress.c'; then $(CYGPATH_W) 'src/journal/compress.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/compress.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journalctl-compress.Tpo src/journal/$(DEPDIR)/systemd_journalctl-compress.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/compress.c' object='src/journal/systemd_journalctl-compress.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journalctl_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journalctl-compress.obj `if test -f 'src/journal/compress.c'; then $(CYGPATH_W) 'src/journal/compress.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/compress.c'; fi` + +src/journal/systemd_journald-journald.o: src/journal/journald.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journald-journald.o -MD -MP -MF src/journal/$(DEPDIR)/systemd_journald-journald.Tpo -c -o src/journal/systemd_journald-journald.o `test -f 'src/journal/journald.c' || echo '$(srcdir)/'`src/journal/journald.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journald-journald.Tpo src/journal/$(DEPDIR)/systemd_journald-journald.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journald.c' object='src/journal/systemd_journald-journald.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journald-journald.o `test -f 'src/journal/journald.c' || echo '$(srcdir)/'`src/journal/journald.c + +src/journal/systemd_journald-journald.obj: src/journal/journald.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journald-journald.obj -MD -MP -MF src/journal/$(DEPDIR)/systemd_journald-journald.Tpo -c -o src/journal/systemd_journald-journald.obj `if test -f 'src/journal/journald.c'; then $(CYGPATH_W) 'src/journal/journald.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/journald.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journald-journald.Tpo src/journal/$(DEPDIR)/systemd_journald-journald.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journald.c' object='src/journal/systemd_journald-journald.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journald-journald.obj `if test -f 'src/journal/journald.c'; then $(CYGPATH_W) 'src/journal/journald.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/journald.c'; fi` + +src/journal/systemd_journald-sd-journal.o: src/journal/sd-journal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journald-sd-journal.o -MD -MP -MF src/journal/$(DEPDIR)/systemd_journald-sd-journal.Tpo -c -o src/journal/systemd_journald-sd-journal.o `test -f 'src/journal/sd-journal.c' || echo '$(srcdir)/'`src/journal/sd-journal.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journald-sd-journal.Tpo src/journal/$(DEPDIR)/systemd_journald-sd-journal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/sd-journal.c' object='src/journal/systemd_journald-sd-journal.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journald-sd-journal.o `test -f 'src/journal/sd-journal.c' || echo '$(srcdir)/'`src/journal/sd-journal.c + +src/journal/systemd_journald-sd-journal.obj: src/journal/sd-journal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journald-sd-journal.obj -MD -MP -MF src/journal/$(DEPDIR)/systemd_journald-sd-journal.Tpo -c -o src/journal/systemd_journald-sd-journal.obj `if test -f 'src/journal/sd-journal.c'; then $(CYGPATH_W) 'src/journal/sd-journal.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/sd-journal.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journald-sd-journal.Tpo src/journal/$(DEPDIR)/systemd_journald-sd-journal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/sd-journal.c' object='src/journal/systemd_journald-sd-journal.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journald-sd-journal.obj `if test -f 'src/journal/sd-journal.c'; then $(CYGPATH_W) 'src/journal/sd-journal.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/sd-journal.c'; fi` + +src/journal/systemd_journald-journal-file.o: src/journal/journal-file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journald-journal-file.o -MD -MP -MF src/journal/$(DEPDIR)/systemd_journald-journal-file.Tpo -c -o src/journal/systemd_journald-journal-file.o `test -f 'src/journal/journal-file.c' || echo '$(srcdir)/'`src/journal/journal-file.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journald-journal-file.Tpo src/journal/$(DEPDIR)/systemd_journald-journal-file.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journal-file.c' object='src/journal/systemd_journald-journal-file.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journald-journal-file.o `test -f 'src/journal/journal-file.c' || echo '$(srcdir)/'`src/journal/journal-file.c + +src/journal/systemd_journald-journal-file.obj: src/journal/journal-file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journald-journal-file.obj -MD -MP -MF src/journal/$(DEPDIR)/systemd_journald-journal-file.Tpo -c -o src/journal/systemd_journald-journal-file.obj `if test -f 'src/journal/journal-file.c'; then $(CYGPATH_W) 'src/journal/journal-file.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/journal-file.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journald-journal-file.Tpo src/journal/$(DEPDIR)/systemd_journald-journal-file.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journal-file.c' object='src/journal/systemd_journald-journal-file.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journald-journal-file.obj `if test -f 'src/journal/journal-file.c'; then $(CYGPATH_W) 'src/journal/journal-file.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/journal-file.c'; fi` + +src/journal/systemd_journald-lookup3.o: src/journal/lookup3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journald-lookup3.o -MD -MP -MF src/journal/$(DEPDIR)/systemd_journald-lookup3.Tpo -c -o src/journal/systemd_journald-lookup3.o `test -f 'src/journal/lookup3.c' || echo '$(srcdir)/'`src/journal/lookup3.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journald-lookup3.Tpo src/journal/$(DEPDIR)/systemd_journald-lookup3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/lookup3.c' object='src/journal/systemd_journald-lookup3.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journald-lookup3.o `test -f 'src/journal/lookup3.c' || echo '$(srcdir)/'`src/journal/lookup3.c + +src/journal/systemd_journald-lookup3.obj: src/journal/lookup3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journald-lookup3.obj -MD -MP -MF src/journal/$(DEPDIR)/systemd_journald-lookup3.Tpo -c -o src/journal/systemd_journald-lookup3.obj `if test -f 'src/journal/lookup3.c'; then $(CYGPATH_W) 'src/journal/lookup3.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/lookup3.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journald-lookup3.Tpo src/journal/$(DEPDIR)/systemd_journald-lookup3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/lookup3.c' object='src/journal/systemd_journald-lookup3.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journald-lookup3.obj `if test -f 'src/journal/lookup3.c'; then $(CYGPATH_W) 'src/journal/lookup3.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/lookup3.c'; fi` + +src/journal/systemd_journald-journal-rate-limit.o: src/journal/journal-rate-limit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journald-journal-rate-limit.o -MD -MP -MF src/journal/$(DEPDIR)/systemd_journald-journal-rate-limit.Tpo -c -o src/journal/systemd_journald-journal-rate-limit.o `test -f 'src/journal/journal-rate-limit.c' || echo '$(srcdir)/'`src/journal/journal-rate-limit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journald-journal-rate-limit.Tpo src/journal/$(DEPDIR)/systemd_journald-journal-rate-limit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journal-rate-limit.c' object='src/journal/systemd_journald-journal-rate-limit.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journald-journal-rate-limit.o `test -f 'src/journal/journal-rate-limit.c' || echo '$(srcdir)/'`src/journal/journal-rate-limit.c + +src/journal/systemd_journald-journal-rate-limit.obj: src/journal/journal-rate-limit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journald-journal-rate-limit.obj -MD -MP -MF src/journal/$(DEPDIR)/systemd_journald-journal-rate-limit.Tpo -c -o src/journal/systemd_journald-journal-rate-limit.obj `if test -f 'src/journal/journal-rate-limit.c'; then $(CYGPATH_W) 'src/journal/journal-rate-limit.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/journal-rate-limit.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journald-journal-rate-limit.Tpo src/journal/$(DEPDIR)/systemd_journald-journal-rate-limit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journal-rate-limit.c' object='src/journal/systemd_journald-journal-rate-limit.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journald-journal-rate-limit.obj `if test -f 'src/journal/journal-rate-limit.c'; then $(CYGPATH_W) 'src/journal/journal-rate-limit.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/journal-rate-limit.c'; fi` + +src/systemd_journald-sd-id128.o: src/sd-id128.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/systemd_journald-sd-id128.o -MD -MP -MF src/$(DEPDIR)/systemd_journald-sd-id128.Tpo -c -o src/systemd_journald-sd-id128.o `test -f 'src/sd-id128.c' || echo '$(srcdir)/'`src/sd-id128.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_journald-sd-id128.Tpo src/$(DEPDIR)/systemd_journald-sd-id128.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sd-id128.c' object='src/systemd_journald-sd-id128.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/systemd_journald-sd-id128.o `test -f 'src/sd-id128.c' || echo '$(srcdir)/'`src/sd-id128.c + +src/systemd_journald-sd-id128.obj: src/sd-id128.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/systemd_journald-sd-id128.obj -MD -MP -MF src/$(DEPDIR)/systemd_journald-sd-id128.Tpo -c -o src/systemd_journald-sd-id128.obj `if test -f 'src/sd-id128.c'; then $(CYGPATH_W) 'src/sd-id128.c'; else $(CYGPATH_W) '$(srcdir)/src/sd-id128.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_journald-sd-id128.Tpo src/$(DEPDIR)/systemd_journald-sd-id128.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sd-id128.c' object='src/systemd_journald-sd-id128.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/systemd_journald-sd-id128.obj `if test -f 'src/sd-id128.c'; then $(CYGPATH_W) 'src/sd-id128.c'; else $(CYGPATH_W) '$(srcdir)/src/sd-id128.c'; fi` + +src/systemd_journald-cgroup-util.o: src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/systemd_journald-cgroup-util.o -MD -MP -MF src/$(DEPDIR)/systemd_journald-cgroup-util.Tpo -c -o src/systemd_journald-cgroup-util.o `test -f 'src/cgroup-util.c' || echo '$(srcdir)/'`src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_journald-cgroup-util.Tpo src/$(DEPDIR)/systemd_journald-cgroup-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-util.c' object='src/systemd_journald-cgroup-util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/systemd_journald-cgroup-util.o `test -f 'src/cgroup-util.c' || echo '$(srcdir)/'`src/cgroup-util.c + +src/systemd_journald-cgroup-util.obj: src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/systemd_journald-cgroup-util.obj -MD -MP -MF src/$(DEPDIR)/systemd_journald-cgroup-util.Tpo -c -o src/systemd_journald-cgroup-util.obj `if test -f 'src/cgroup-util.c'; then $(CYGPATH_W) 'src/cgroup-util.c'; else $(CYGPATH_W) '$(srcdir)/src/cgroup-util.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_journald-cgroup-util.Tpo src/$(DEPDIR)/systemd_journald-cgroup-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-util.c' object='src/systemd_journald-cgroup-util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/systemd_journald-cgroup-util.obj `if test -f 'src/cgroup-util.c'; then $(CYGPATH_W) 'src/cgroup-util.c'; else $(CYGPATH_W) '$(srcdir)/src/cgroup-util.c'; fi` + +src/systemd_journald-acl-util.o: src/acl-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/systemd_journald-acl-util.o -MD -MP -MF src/$(DEPDIR)/systemd_journald-acl-util.Tpo -c -o src/systemd_journald-acl-util.o `test -f 'src/acl-util.c' || echo '$(srcdir)/'`src/acl-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_journald-acl-util.Tpo src/$(DEPDIR)/systemd_journald-acl-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/acl-util.c' object='src/systemd_journald-acl-util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/systemd_journald-acl-util.o `test -f 'src/acl-util.c' || echo '$(srcdir)/'`src/acl-util.c + +src/systemd_journald-acl-util.obj: src/acl-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/systemd_journald-acl-util.obj -MD -MP -MF src/$(DEPDIR)/systemd_journald-acl-util.Tpo -c -o src/systemd_journald-acl-util.obj `if test -f 'src/acl-util.c'; then $(CYGPATH_W) 'src/acl-util.c'; else $(CYGPATH_W) '$(srcdir)/src/acl-util.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_journald-acl-util.Tpo src/$(DEPDIR)/systemd_journald-acl-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/acl-util.c' object='src/systemd_journald-acl-util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/systemd_journald-acl-util.obj `if test -f 'src/acl-util.c'; then $(CYGPATH_W) 'src/acl-util.c'; else $(CYGPATH_W) '$(srcdir)/src/acl-util.c'; fi` + +src/journal/systemd_journald-compress.o: src/journal/compress.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journald-compress.o -MD -MP -MF src/journal/$(DEPDIR)/systemd_journald-compress.Tpo -c -o src/journal/systemd_journald-compress.o `test -f 'src/journal/compress.c' || echo '$(srcdir)/'`src/journal/compress.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journald-compress.Tpo src/journal/$(DEPDIR)/systemd_journald-compress.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/compress.c' object='src/journal/systemd_journald-compress.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journald-compress.o `test -f 'src/journal/compress.c' || echo '$(srcdir)/'`src/journal/compress.c + +src/journal/systemd_journald-compress.obj: src/journal/compress.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journald-compress.obj -MD -MP -MF src/journal/$(DEPDIR)/systemd_journald-compress.Tpo -c -o src/journal/systemd_journald-compress.obj `if test -f 'src/journal/compress.c'; then $(CYGPATH_W) 'src/journal/compress.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/compress.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journald-compress.Tpo src/journal/$(DEPDIR)/systemd_journald-compress.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/compress.c' object='src/journal/systemd_journald-compress.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journald-compress.obj `if test -f 'src/journal/compress.c'; then $(CYGPATH_W) 'src/journal/compress.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/compress.c'; fi` + +src/journal/systemd_journald-journald-gperf.o: src/journal/journald-gperf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journald-journald-gperf.o -MD -MP -MF src/journal/$(DEPDIR)/systemd_journald-journald-gperf.Tpo -c -o src/journal/systemd_journald-journald-gperf.o `test -f 'src/journal/journald-gperf.c' || echo '$(srcdir)/'`src/journal/journald-gperf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journald-journald-gperf.Tpo src/journal/$(DEPDIR)/systemd_journald-journald-gperf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journald-gperf.c' object='src/journal/systemd_journald-journald-gperf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journald-journald-gperf.o `test -f 'src/journal/journald-gperf.c' || echo '$(srcdir)/'`src/journal/journald-gperf.c + +src/journal/systemd_journald-journald-gperf.obj: src/journal/journald-gperf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -MT src/journal/systemd_journald-journald-gperf.obj -MD -MP -MF src/journal/$(DEPDIR)/systemd_journald-journald-gperf.Tpo -c -o src/journal/systemd_journald-journald-gperf.obj `if test -f 'src/journal/journald-gperf.c'; then $(CYGPATH_W) 'src/journal/journald-gperf.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/journald-gperf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/systemd_journald-journald-gperf.Tpo src/journal/$(DEPDIR)/systemd_journald-journald-gperf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journald-gperf.c' object='src/journal/systemd_journald-journald-gperf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_journald_CFLAGS) $(CFLAGS) -c -o src/journal/systemd_journald-journald-gperf.obj `if test -f 'src/journal/journald-gperf.c'; then $(CYGPATH_W) 'src/journal/journald-gperf.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/journald-gperf.c'; fi` + +src/locale/systemd_localed-localed.o: src/locale/localed.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_localed_CFLAGS) $(CFLAGS) -MT src/locale/systemd_localed-localed.o -MD -MP -MF src/locale/$(DEPDIR)/systemd_localed-localed.Tpo -c -o src/locale/systemd_localed-localed.o `test -f 'src/locale/localed.c' || echo '$(srcdir)/'`src/locale/localed.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/locale/$(DEPDIR)/systemd_localed-localed.Tpo src/locale/$(DEPDIR)/systemd_localed-localed.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/locale/localed.c' object='src/locale/systemd_localed-localed.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_localed_CFLAGS) $(CFLAGS) -c -o src/locale/systemd_localed-localed.o `test -f 'src/locale/localed.c' || echo '$(srcdir)/'`src/locale/localed.c + +src/locale/systemd_localed-localed.obj: src/locale/localed.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_localed_CFLAGS) $(CFLAGS) -MT src/locale/systemd_localed-localed.obj -MD -MP -MF src/locale/$(DEPDIR)/systemd_localed-localed.Tpo -c -o src/locale/systemd_localed-localed.obj `if test -f 'src/locale/localed.c'; then $(CYGPATH_W) 'src/locale/localed.c'; else $(CYGPATH_W) '$(srcdir)/src/locale/localed.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/locale/$(DEPDIR)/systemd_localed-localed.Tpo src/locale/$(DEPDIR)/systemd_localed-localed.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/locale/localed.c' object='src/locale/systemd_localed-localed.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_localed_CFLAGS) $(CFLAGS) -c -o src/locale/systemd_localed-localed.obj `if test -f 'src/locale/localed.c'; then $(CYGPATH_W) 'src/locale/localed.c'; else $(CYGPATH_W) '$(srcdir)/src/locale/localed.c'; fi` + +src/systemd_localed-dbus-common.o: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_localed_CFLAGS) $(CFLAGS) -MT src/systemd_localed-dbus-common.o -MD -MP -MF src/$(DEPDIR)/systemd_localed-dbus-common.Tpo -c -o src/systemd_localed-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_localed-dbus-common.Tpo src/$(DEPDIR)/systemd_localed-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_localed-dbus-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_localed_CFLAGS) $(CFLAGS) -c -o src/systemd_localed-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c + +src/systemd_localed-dbus-common.obj: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_localed_CFLAGS) $(CFLAGS) -MT src/systemd_localed-dbus-common.obj -MD -MP -MF src/$(DEPDIR)/systemd_localed-dbus-common.Tpo -c -o src/systemd_localed-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_localed-dbus-common.Tpo src/$(DEPDIR)/systemd_localed-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_localed-dbus-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_localed_CFLAGS) $(CFLAGS) -c -o src/systemd_localed-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` + +src/systemd_localed-polkit.o: src/polkit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_localed_CFLAGS) $(CFLAGS) -MT src/systemd_localed-polkit.o -MD -MP -MF src/$(DEPDIR)/systemd_localed-polkit.Tpo -c -o src/systemd_localed-polkit.o `test -f 'src/polkit.c' || echo '$(srcdir)/'`src/polkit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_localed-polkit.Tpo src/$(DEPDIR)/systemd_localed-polkit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/polkit.c' object='src/systemd_localed-polkit.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_localed_CFLAGS) $(CFLAGS) -c -o src/systemd_localed-polkit.o `test -f 'src/polkit.c' || echo '$(srcdir)/'`src/polkit.c + +src/systemd_localed-polkit.obj: src/polkit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_localed_CFLAGS) $(CFLAGS) -MT src/systemd_localed-polkit.obj -MD -MP -MF src/$(DEPDIR)/systemd_localed-polkit.Tpo -c -o src/systemd_localed-polkit.obj `if test -f 'src/polkit.c'; then $(CYGPATH_W) 'src/polkit.c'; else $(CYGPATH_W) '$(srcdir)/src/polkit.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_localed-polkit.Tpo src/$(DEPDIR)/systemd_localed-polkit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/polkit.c' object='src/systemd_localed-polkit.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_localed_CFLAGS) $(CFLAGS) -c -o src/systemd_localed-polkit.obj `if test -f 'src/polkit.c'; then $(CYGPATH_W) 'src/polkit.c'; else $(CYGPATH_W) '$(srcdir)/src/polkit.c'; fi` + +src/login/systemd_loginctl-loginctl.o: src/login/loginctl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -MT src/login/systemd_loginctl-loginctl.o -MD -MP -MF src/login/$(DEPDIR)/systemd_loginctl-loginctl.Tpo -c -o src/login/systemd_loginctl-loginctl.o `test -f 'src/login/loginctl.c' || echo '$(srcdir)/'`src/login/loginctl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_loginctl-loginctl.Tpo src/login/$(DEPDIR)/systemd_loginctl-loginctl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/loginctl.c' object='src/login/systemd_loginctl-loginctl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -c -o src/login/systemd_loginctl-loginctl.o `test -f 'src/login/loginctl.c' || echo '$(srcdir)/'`src/login/loginctl.c + +src/login/systemd_loginctl-loginctl.obj: src/login/loginctl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -MT src/login/systemd_loginctl-loginctl.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_loginctl-loginctl.Tpo -c -o src/login/systemd_loginctl-loginctl.obj `if test -f 'src/login/loginctl.c'; then $(CYGPATH_W) 'src/login/loginctl.c'; else $(CYGPATH_W) '$(srcdir)/src/login/loginctl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_loginctl-loginctl.Tpo src/login/$(DEPDIR)/systemd_loginctl-loginctl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/loginctl.c' object='src/login/systemd_loginctl-loginctl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -c -o src/login/systemd_loginctl-loginctl.obj `if test -f 'src/login/loginctl.c'; then $(CYGPATH_W) 'src/login/loginctl.c'; else $(CYGPATH_W) '$(srcdir)/src/login/loginctl.c'; fi` + +src/login/systemd_loginctl-sysfs-show.o: src/login/sysfs-show.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -MT src/login/systemd_loginctl-sysfs-show.o -MD -MP -MF src/login/$(DEPDIR)/systemd_loginctl-sysfs-show.Tpo -c -o src/login/systemd_loginctl-sysfs-show.o `test -f 'src/login/sysfs-show.c' || echo '$(srcdir)/'`src/login/sysfs-show.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_loginctl-sysfs-show.Tpo src/login/$(DEPDIR)/systemd_loginctl-sysfs-show.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/sysfs-show.c' object='src/login/systemd_loginctl-sysfs-show.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -c -o src/login/systemd_loginctl-sysfs-show.o `test -f 'src/login/sysfs-show.c' || echo '$(srcdir)/'`src/login/sysfs-show.c + +src/login/systemd_loginctl-sysfs-show.obj: src/login/sysfs-show.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -MT src/login/systemd_loginctl-sysfs-show.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_loginctl-sysfs-show.Tpo -c -o src/login/systemd_loginctl-sysfs-show.obj `if test -f 'src/login/sysfs-show.c'; then $(CYGPATH_W) 'src/login/sysfs-show.c'; else $(CYGPATH_W) '$(srcdir)/src/login/sysfs-show.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_loginctl-sysfs-show.Tpo src/login/$(DEPDIR)/systemd_loginctl-sysfs-show.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/sysfs-show.c' object='src/login/systemd_loginctl-sysfs-show.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -c -o src/login/systemd_loginctl-sysfs-show.obj `if test -f 'src/login/sysfs-show.c'; then $(CYGPATH_W) 'src/login/sysfs-show.c'; else $(CYGPATH_W) '$(srcdir)/src/login/sysfs-show.c'; fi` + +src/systemd_loginctl-dbus-common.o: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -MT src/systemd_loginctl-dbus-common.o -MD -MP -MF src/$(DEPDIR)/systemd_loginctl-dbus-common.Tpo -c -o src/systemd_loginctl-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_loginctl-dbus-common.Tpo src/$(DEPDIR)/systemd_loginctl-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_loginctl-dbus-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -c -o src/systemd_loginctl-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c + +src/systemd_loginctl-dbus-common.obj: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -MT src/systemd_loginctl-dbus-common.obj -MD -MP -MF src/$(DEPDIR)/systemd_loginctl-dbus-common.Tpo -c -o src/systemd_loginctl-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_loginctl-dbus-common.Tpo src/$(DEPDIR)/systemd_loginctl-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_loginctl-dbus-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -c -o src/systemd_loginctl-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` + +src/systemd_loginctl-cgroup-show.o: src/cgroup-show.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -MT src/systemd_loginctl-cgroup-show.o -MD -MP -MF src/$(DEPDIR)/systemd_loginctl-cgroup-show.Tpo -c -o src/systemd_loginctl-cgroup-show.o `test -f 'src/cgroup-show.c' || echo '$(srcdir)/'`src/cgroup-show.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_loginctl-cgroup-show.Tpo src/$(DEPDIR)/systemd_loginctl-cgroup-show.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-show.c' object='src/systemd_loginctl-cgroup-show.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -c -o src/systemd_loginctl-cgroup-show.o `test -f 'src/cgroup-show.c' || echo '$(srcdir)/'`src/cgroup-show.c + +src/systemd_loginctl-cgroup-show.obj: src/cgroup-show.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -MT src/systemd_loginctl-cgroup-show.obj -MD -MP -MF src/$(DEPDIR)/systemd_loginctl-cgroup-show.Tpo -c -o src/systemd_loginctl-cgroup-show.obj `if test -f 'src/cgroup-show.c'; then $(CYGPATH_W) 'src/cgroup-show.c'; else $(CYGPATH_W) '$(srcdir)/src/cgroup-show.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_loginctl-cgroup-show.Tpo src/$(DEPDIR)/systemd_loginctl-cgroup-show.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-show.c' object='src/systemd_loginctl-cgroup-show.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -c -o src/systemd_loginctl-cgroup-show.obj `if test -f 'src/cgroup-show.c'; then $(CYGPATH_W) 'src/cgroup-show.c'; else $(CYGPATH_W) '$(srcdir)/src/cgroup-show.c'; fi` + +src/systemd_loginctl-cgroup-util.o: src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -MT src/systemd_loginctl-cgroup-util.o -MD -MP -MF src/$(DEPDIR)/systemd_loginctl-cgroup-util.Tpo -c -o src/systemd_loginctl-cgroup-util.o `test -f 'src/cgroup-util.c' || echo '$(srcdir)/'`src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_loginctl-cgroup-util.Tpo src/$(DEPDIR)/systemd_loginctl-cgroup-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-util.c' object='src/systemd_loginctl-cgroup-util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -c -o src/systemd_loginctl-cgroup-util.o `test -f 'src/cgroup-util.c' || echo '$(srcdir)/'`src/cgroup-util.c + +src/systemd_loginctl-cgroup-util.obj: src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -MT src/systemd_loginctl-cgroup-util.obj -MD -MP -MF src/$(DEPDIR)/systemd_loginctl-cgroup-util.Tpo -c -o src/systemd_loginctl-cgroup-util.obj `if test -f 'src/cgroup-util.c'; then $(CYGPATH_W) 'src/cgroup-util.c'; else $(CYGPATH_W) '$(srcdir)/src/cgroup-util.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_loginctl-cgroup-util.Tpo src/$(DEPDIR)/systemd_loginctl-cgroup-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-util.c' object='src/systemd_loginctl-cgroup-util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -c -o src/systemd_loginctl-cgroup-util.obj `if test -f 'src/cgroup-util.c'; then $(CYGPATH_W) 'src/cgroup-util.c'; else $(CYGPATH_W) '$(srcdir)/src/cgroup-util.c'; fi` + +src/systemd_loginctl-pager.o: src/pager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -MT src/systemd_loginctl-pager.o -MD -MP -MF src/$(DEPDIR)/systemd_loginctl-pager.Tpo -c -o src/systemd_loginctl-pager.o `test -f 'src/pager.c' || echo '$(srcdir)/'`src/pager.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_loginctl-pager.Tpo src/$(DEPDIR)/systemd_loginctl-pager.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pager.c' object='src/systemd_loginctl-pager.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -c -o src/systemd_loginctl-pager.o `test -f 'src/pager.c' || echo '$(srcdir)/'`src/pager.c + +src/systemd_loginctl-pager.obj: src/pager.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -MT src/systemd_loginctl-pager.obj -MD -MP -MF src/$(DEPDIR)/systemd_loginctl-pager.Tpo -c -o src/systemd_loginctl-pager.obj `if test -f 'src/pager.c'; then $(CYGPATH_W) 'src/pager.c'; else $(CYGPATH_W) '$(srcdir)/src/pager.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_loginctl-pager.Tpo src/$(DEPDIR)/systemd_loginctl-pager.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/pager.c' object='src/systemd_loginctl-pager.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_loginctl_CFLAGS) $(CFLAGS) -c -o src/systemd_loginctl-pager.obj `if test -f 'src/pager.c'; then $(CYGPATH_W) 'src/pager.c'; else $(CYGPATH_W) '$(srcdir)/src/pager.c'; fi` + +src/login/systemd_logind-logind.o: src/login/logind.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind.o -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind.Tpo -c -o src/login/systemd_logind-logind.o `test -f 'src/login/logind.c' || echo '$(srcdir)/'`src/login/logind.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind.Tpo src/login/$(DEPDIR)/systemd_logind-logind.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind.c' object='src/login/systemd_logind-logind.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind.o `test -f 'src/login/logind.c' || echo '$(srcdir)/'`src/login/logind.c + +src/login/systemd_logind-logind.obj: src/login/logind.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind.Tpo -c -o src/login/systemd_logind-logind.obj `if test -f 'src/login/logind.c'; then $(CYGPATH_W) 'src/login/logind.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind.Tpo src/login/$(DEPDIR)/systemd_logind-logind.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind.c' object='src/login/systemd_logind-logind.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind.obj `if test -f 'src/login/logind.c'; then $(CYGPATH_W) 'src/login/logind.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind.c'; fi` + +src/login/systemd_logind-logind-dbus.o: src/login/logind-dbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-dbus.o -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-dbus.Tpo -c -o src/login/systemd_logind-logind-dbus.o `test -f 'src/login/logind-dbus.c' || echo '$(srcdir)/'`src/login/logind-dbus.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-dbus.Tpo src/login/$(DEPDIR)/systemd_logind-logind-dbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-dbus.c' object='src/login/systemd_logind-logind-dbus.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-dbus.o `test -f 'src/login/logind-dbus.c' || echo '$(srcdir)/'`src/login/logind-dbus.c + +src/login/systemd_logind-logind-dbus.obj: src/login/logind-dbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-dbus.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-dbus.Tpo -c -o src/login/systemd_logind-logind-dbus.obj `if test -f 'src/login/logind-dbus.c'; then $(CYGPATH_W) 'src/login/logind-dbus.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-dbus.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-dbus.Tpo src/login/$(DEPDIR)/systemd_logind-logind-dbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-dbus.c' object='src/login/systemd_logind-logind-dbus.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-dbus.obj `if test -f 'src/login/logind-dbus.c'; then $(CYGPATH_W) 'src/login/logind-dbus.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-dbus.c'; fi` + +src/login/systemd_logind-logind-device.o: src/login/logind-device.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-device.o -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-device.Tpo -c -o src/login/systemd_logind-logind-device.o `test -f 'src/login/logind-device.c' || echo '$(srcdir)/'`src/login/logind-device.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-device.Tpo src/login/$(DEPDIR)/systemd_logind-logind-device.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-device.c' object='src/login/systemd_logind-logind-device.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-device.o `test -f 'src/login/logind-device.c' || echo '$(srcdir)/'`src/login/logind-device.c + +src/login/systemd_logind-logind-device.obj: src/login/logind-device.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-device.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-device.Tpo -c -o src/login/systemd_logind-logind-device.obj `if test -f 'src/login/logind-device.c'; then $(CYGPATH_W) 'src/login/logind-device.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-device.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-device.Tpo src/login/$(DEPDIR)/systemd_logind-logind-device.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-device.c' object='src/login/systemd_logind-logind-device.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-device.obj `if test -f 'src/login/logind-device.c'; then $(CYGPATH_W) 'src/login/logind-device.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-device.c'; fi` + +src/login/systemd_logind-logind-seat.o: src/login/logind-seat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-seat.o -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-seat.Tpo -c -o src/login/systemd_logind-logind-seat.o `test -f 'src/login/logind-seat.c' || echo '$(srcdir)/'`src/login/logind-seat.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-seat.Tpo src/login/$(DEPDIR)/systemd_logind-logind-seat.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-seat.c' object='src/login/systemd_logind-logind-seat.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-seat.o `test -f 'src/login/logind-seat.c' || echo '$(srcdir)/'`src/login/logind-seat.c + +src/login/systemd_logind-logind-seat.obj: src/login/logind-seat.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-seat.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-seat.Tpo -c -o src/login/systemd_logind-logind-seat.obj `if test -f 'src/login/logind-seat.c'; then $(CYGPATH_W) 'src/login/logind-seat.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-seat.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-seat.Tpo src/login/$(DEPDIR)/systemd_logind-logind-seat.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-seat.c' object='src/login/systemd_logind-logind-seat.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-seat.obj `if test -f 'src/login/logind-seat.c'; then $(CYGPATH_W) 'src/login/logind-seat.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-seat.c'; fi` + +src/login/systemd_logind-logind-seat-dbus.o: src/login/logind-seat-dbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-seat-dbus.o -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-seat-dbus.Tpo -c -o src/login/systemd_logind-logind-seat-dbus.o `test -f 'src/login/logind-seat-dbus.c' || echo '$(srcdir)/'`src/login/logind-seat-dbus.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-seat-dbus.Tpo src/login/$(DEPDIR)/systemd_logind-logind-seat-dbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-seat-dbus.c' object='src/login/systemd_logind-logind-seat-dbus.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-seat-dbus.o `test -f 'src/login/logind-seat-dbus.c' || echo '$(srcdir)/'`src/login/logind-seat-dbus.c + +src/login/systemd_logind-logind-seat-dbus.obj: src/login/logind-seat-dbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-seat-dbus.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-seat-dbus.Tpo -c -o src/login/systemd_logind-logind-seat-dbus.obj `if test -f 'src/login/logind-seat-dbus.c'; then $(CYGPATH_W) 'src/login/logind-seat-dbus.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-seat-dbus.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-seat-dbus.Tpo src/login/$(DEPDIR)/systemd_logind-logind-seat-dbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-seat-dbus.c' object='src/login/systemd_logind-logind-seat-dbus.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-seat-dbus.obj `if test -f 'src/login/logind-seat-dbus.c'; then $(CYGPATH_W) 'src/login/logind-seat-dbus.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-seat-dbus.c'; fi` + +src/login/systemd_logind-logind-session.o: src/login/logind-session.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-session.o -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-session.Tpo -c -o src/login/systemd_logind-logind-session.o `test -f 'src/login/logind-session.c' || echo '$(srcdir)/'`src/login/logind-session.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-session.Tpo src/login/$(DEPDIR)/systemd_logind-logind-session.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-session.c' object='src/login/systemd_logind-logind-session.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-session.o `test -f 'src/login/logind-session.c' || echo '$(srcdir)/'`src/login/logind-session.c + +src/login/systemd_logind-logind-session.obj: src/login/logind-session.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-session.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-session.Tpo -c -o src/login/systemd_logind-logind-session.obj `if test -f 'src/login/logind-session.c'; then $(CYGPATH_W) 'src/login/logind-session.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-session.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-session.Tpo src/login/$(DEPDIR)/systemd_logind-logind-session.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-session.c' object='src/login/systemd_logind-logind-session.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-session.obj `if test -f 'src/login/logind-session.c'; then $(CYGPATH_W) 'src/login/logind-session.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-session.c'; fi` + +src/login/systemd_logind-logind-session-dbus.o: src/login/logind-session-dbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-session-dbus.o -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-session-dbus.Tpo -c -o src/login/systemd_logind-logind-session-dbus.o `test -f 'src/login/logind-session-dbus.c' || echo '$(srcdir)/'`src/login/logind-session-dbus.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-session-dbus.Tpo src/login/$(DEPDIR)/systemd_logind-logind-session-dbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-session-dbus.c' object='src/login/systemd_logind-logind-session-dbus.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-session-dbus.o `test -f 'src/login/logind-session-dbus.c' || echo '$(srcdir)/'`src/login/logind-session-dbus.c + +src/login/systemd_logind-logind-session-dbus.obj: src/login/logind-session-dbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-session-dbus.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-session-dbus.Tpo -c -o src/login/systemd_logind-logind-session-dbus.obj `if test -f 'src/login/logind-session-dbus.c'; then $(CYGPATH_W) 'src/login/logind-session-dbus.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-session-dbus.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-session-dbus.Tpo src/login/$(DEPDIR)/systemd_logind-logind-session-dbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-session-dbus.c' object='src/login/systemd_logind-logind-session-dbus.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-session-dbus.obj `if test -f 'src/login/logind-session-dbus.c'; then $(CYGPATH_W) 'src/login/logind-session-dbus.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-session-dbus.c'; fi` + +src/login/systemd_logind-logind-user.o: src/login/logind-user.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-user.o -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-user.Tpo -c -o src/login/systemd_logind-logind-user.o `test -f 'src/login/logind-user.c' || echo '$(srcdir)/'`src/login/logind-user.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-user.Tpo src/login/$(DEPDIR)/systemd_logind-logind-user.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-user.c' object='src/login/systemd_logind-logind-user.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-user.o `test -f 'src/login/logind-user.c' || echo '$(srcdir)/'`src/login/logind-user.c + +src/login/systemd_logind-logind-user.obj: src/login/logind-user.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-user.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-user.Tpo -c -o src/login/systemd_logind-logind-user.obj `if test -f 'src/login/logind-user.c'; then $(CYGPATH_W) 'src/login/logind-user.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-user.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-user.Tpo src/login/$(DEPDIR)/systemd_logind-logind-user.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-user.c' object='src/login/systemd_logind-logind-user.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-user.obj `if test -f 'src/login/logind-user.c'; then $(CYGPATH_W) 'src/login/logind-user.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-user.c'; fi` + +src/login/systemd_logind-logind-user-dbus.o: src/login/logind-user-dbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-user-dbus.o -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-user-dbus.Tpo -c -o src/login/systemd_logind-logind-user-dbus.o `test -f 'src/login/logind-user-dbus.c' || echo '$(srcdir)/'`src/login/logind-user-dbus.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-user-dbus.Tpo src/login/$(DEPDIR)/systemd_logind-logind-user-dbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-user-dbus.c' object='src/login/systemd_logind-logind-user-dbus.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-user-dbus.o `test -f 'src/login/logind-user-dbus.c' || echo '$(srcdir)/'`src/login/logind-user-dbus.c + +src/login/systemd_logind-logind-user-dbus.obj: src/login/logind-user-dbus.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-user-dbus.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-user-dbus.Tpo -c -o src/login/systemd_logind-logind-user-dbus.obj `if test -f 'src/login/logind-user-dbus.c'; then $(CYGPATH_W) 'src/login/logind-user-dbus.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-user-dbus.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-user-dbus.Tpo src/login/$(DEPDIR)/systemd_logind-logind-user-dbus.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-user-dbus.c' object='src/login/systemd_logind-logind-user-dbus.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-user-dbus.obj `if test -f 'src/login/logind-user-dbus.c'; then $(CYGPATH_W) 'src/login/logind-user-dbus.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-user-dbus.c'; fi` + +src/systemd_logind-dbus-common.o: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/systemd_logind-dbus-common.o -MD -MP -MF src/$(DEPDIR)/systemd_logind-dbus-common.Tpo -c -o src/systemd_logind-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_logind-dbus-common.Tpo src/$(DEPDIR)/systemd_logind-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_logind-dbus-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/systemd_logind-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c + +src/systemd_logind-dbus-common.obj: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/systemd_logind-dbus-common.obj -MD -MP -MF src/$(DEPDIR)/systemd_logind-dbus-common.Tpo -c -o src/systemd_logind-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_logind-dbus-common.Tpo src/$(DEPDIR)/systemd_logind-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_logind-dbus-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/systemd_logind-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` + +src/systemd_logind-dbus-loop.o: src/dbus-loop.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/systemd_logind-dbus-loop.o -MD -MP -MF src/$(DEPDIR)/systemd_logind-dbus-loop.Tpo -c -o src/systemd_logind-dbus-loop.o `test -f 'src/dbus-loop.c' || echo '$(srcdir)/'`src/dbus-loop.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_logind-dbus-loop.Tpo src/$(DEPDIR)/systemd_logind-dbus-loop.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-loop.c' object='src/systemd_logind-dbus-loop.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/systemd_logind-dbus-loop.o `test -f 'src/dbus-loop.c' || echo '$(srcdir)/'`src/dbus-loop.c + +src/systemd_logind-dbus-loop.obj: src/dbus-loop.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/systemd_logind-dbus-loop.obj -MD -MP -MF src/$(DEPDIR)/systemd_logind-dbus-loop.Tpo -c -o src/systemd_logind-dbus-loop.obj `if test -f 'src/dbus-loop.c'; then $(CYGPATH_W) 'src/dbus-loop.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-loop.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_logind-dbus-loop.Tpo src/$(DEPDIR)/systemd_logind-dbus-loop.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-loop.c' object='src/systemd_logind-dbus-loop.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/systemd_logind-dbus-loop.obj `if test -f 'src/dbus-loop.c'; then $(CYGPATH_W) 'src/dbus-loop.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-loop.c'; fi` + +src/systemd_logind-cgroup-util.o: src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/systemd_logind-cgroup-util.o -MD -MP -MF src/$(DEPDIR)/systemd_logind-cgroup-util.Tpo -c -o src/systemd_logind-cgroup-util.o `test -f 'src/cgroup-util.c' || echo '$(srcdir)/'`src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_logind-cgroup-util.Tpo src/$(DEPDIR)/systemd_logind-cgroup-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-util.c' object='src/systemd_logind-cgroup-util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/systemd_logind-cgroup-util.o `test -f 'src/cgroup-util.c' || echo '$(srcdir)/'`src/cgroup-util.c + +src/systemd_logind-cgroup-util.obj: src/cgroup-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/systemd_logind-cgroup-util.obj -MD -MP -MF src/$(DEPDIR)/systemd_logind-cgroup-util.Tpo -c -o src/systemd_logind-cgroup-util.obj `if test -f 'src/cgroup-util.c'; then $(CYGPATH_W) 'src/cgroup-util.c'; else $(CYGPATH_W) '$(srcdir)/src/cgroup-util.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_logind-cgroup-util.Tpo src/$(DEPDIR)/systemd_logind-cgroup-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/cgroup-util.c' object='src/systemd_logind-cgroup-util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/systemd_logind-cgroup-util.obj `if test -f 'src/cgroup-util.c'; then $(CYGPATH_W) 'src/cgroup-util.c'; else $(CYGPATH_W) '$(srcdir)/src/cgroup-util.c'; fi` + +src/systemd_logind-polkit.o: src/polkit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/systemd_logind-polkit.o -MD -MP -MF src/$(DEPDIR)/systemd_logind-polkit.Tpo -c -o src/systemd_logind-polkit.o `test -f 'src/polkit.c' || echo '$(srcdir)/'`src/polkit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_logind-polkit.Tpo src/$(DEPDIR)/systemd_logind-polkit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/polkit.c' object='src/systemd_logind-polkit.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/systemd_logind-polkit.o `test -f 'src/polkit.c' || echo '$(srcdir)/'`src/polkit.c + +src/systemd_logind-polkit.obj: src/polkit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/systemd_logind-polkit.obj -MD -MP -MF src/$(DEPDIR)/systemd_logind-polkit.Tpo -c -o src/systemd_logind-polkit.obj `if test -f 'src/polkit.c'; then $(CYGPATH_W) 'src/polkit.c'; else $(CYGPATH_W) '$(srcdir)/src/polkit.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_logind-polkit.Tpo src/$(DEPDIR)/systemd_logind-polkit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/polkit.c' object='src/systemd_logind-polkit.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/systemd_logind-polkit.obj `if test -f 'src/polkit.c'; then $(CYGPATH_W) 'src/polkit.c'; else $(CYGPATH_W) '$(srcdir)/src/polkit.c'; fi` + +src/login/systemd_logind-logind-acl.o: src/login/logind-acl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-acl.o -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-acl.Tpo -c -o src/login/systemd_logind-logind-acl.o `test -f 'src/login/logind-acl.c' || echo '$(srcdir)/'`src/login/logind-acl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-acl.Tpo src/login/$(DEPDIR)/systemd_logind-logind-acl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-acl.c' object='src/login/systemd_logind-logind-acl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-acl.o `test -f 'src/login/logind-acl.c' || echo '$(srcdir)/'`src/login/logind-acl.c + +src/login/systemd_logind-logind-acl.obj: src/login/logind-acl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-acl.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-acl.Tpo -c -o src/login/systemd_logind-logind-acl.obj `if test -f 'src/login/logind-acl.c'; then $(CYGPATH_W) 'src/login/logind-acl.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-acl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-acl.Tpo src/login/$(DEPDIR)/systemd_logind-logind-acl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-acl.c' object='src/login/systemd_logind-logind-acl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-acl.obj `if test -f 'src/login/logind-acl.c'; then $(CYGPATH_W) 'src/login/logind-acl.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-acl.c'; fi` + +src/systemd_logind-acl-util.o: src/acl-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/systemd_logind-acl-util.o -MD -MP -MF src/$(DEPDIR)/systemd_logind-acl-util.Tpo -c -o src/systemd_logind-acl-util.o `test -f 'src/acl-util.c' || echo '$(srcdir)/'`src/acl-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_logind-acl-util.Tpo src/$(DEPDIR)/systemd_logind-acl-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/acl-util.c' object='src/systemd_logind-acl-util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/systemd_logind-acl-util.o `test -f 'src/acl-util.c' || echo '$(srcdir)/'`src/acl-util.c + +src/systemd_logind-acl-util.obj: src/acl-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/systemd_logind-acl-util.obj -MD -MP -MF src/$(DEPDIR)/systemd_logind-acl-util.Tpo -c -o src/systemd_logind-acl-util.obj `if test -f 'src/acl-util.c'; then $(CYGPATH_W) 'src/acl-util.c'; else $(CYGPATH_W) '$(srcdir)/src/acl-util.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_logind-acl-util.Tpo src/$(DEPDIR)/systemd_logind-acl-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/acl-util.c' object='src/systemd_logind-acl-util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/systemd_logind-acl-util.obj `if test -f 'src/acl-util.c'; then $(CYGPATH_W) 'src/acl-util.c'; else $(CYGPATH_W) '$(srcdir)/src/acl-util.c'; fi` + +src/login/systemd_logind-logind-gperf.o: src/login/logind-gperf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-gperf.o -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-gperf.Tpo -c -o src/login/systemd_logind-logind-gperf.o `test -f 'src/login/logind-gperf.c' || echo '$(srcdir)/'`src/login/logind-gperf.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-gperf.Tpo src/login/$(DEPDIR)/systemd_logind-logind-gperf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-gperf.c' object='src/login/systemd_logind-logind-gperf.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-gperf.o `test -f 'src/login/logind-gperf.c' || echo '$(srcdir)/'`src/login/logind-gperf.c + +src/login/systemd_logind-logind-gperf.obj: src/login/logind-gperf.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -MT src/login/systemd_logind-logind-gperf.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_logind-logind-gperf.Tpo -c -o src/login/systemd_logind-logind-gperf.obj `if test -f 'src/login/logind-gperf.c'; then $(CYGPATH_W) 'src/login/logind-gperf.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-gperf.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_logind-logind-gperf.Tpo src/login/$(DEPDIR)/systemd_logind-logind-gperf.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-gperf.c' object='src/login/systemd_logind-logind-gperf.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_logind_CFLAGS) $(CFLAGS) -c -o src/login/systemd_logind-logind-gperf.obj `if test -f 'src/login/logind-gperf.c'; then $(CYGPATH_W) 'src/login/logind-gperf.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-gperf.c'; fi` + +src/systemd_modules_load-modules-load.o: src/modules-load.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_modules_load_CFLAGS) $(CFLAGS) -MT src/systemd_modules_load-modules-load.o -MD -MP -MF src/$(DEPDIR)/systemd_modules_load-modules-load.Tpo -c -o src/systemd_modules_load-modules-load.o `test -f 'src/modules-load.c' || echo '$(srcdir)/'`src/modules-load.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_modules_load-modules-load.Tpo src/$(DEPDIR)/systemd_modules_load-modules-load.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/modules-load.c' object='src/systemd_modules_load-modules-load.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_modules_load_CFLAGS) $(CFLAGS) -c -o src/systemd_modules_load-modules-load.o `test -f 'src/modules-load.c' || echo '$(srcdir)/'`src/modules-load.c + +src/systemd_modules_load-modules-load.obj: src/modules-load.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_modules_load_CFLAGS) $(CFLAGS) -MT src/systemd_modules_load-modules-load.obj -MD -MP -MF src/$(DEPDIR)/systemd_modules_load-modules-load.Tpo -c -o src/systemd_modules_load-modules-load.obj `if test -f 'src/modules-load.c'; then $(CYGPATH_W) 'src/modules-load.c'; else $(CYGPATH_W) '$(srcdir)/src/modules-load.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_modules_load-modules-load.Tpo src/$(DEPDIR)/systemd_modules_load-modules-load.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/modules-load.c' object='src/systemd_modules_load-modules-load.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_modules_load_CFLAGS) $(CFLAGS) -c -o src/systemd_modules_load-modules-load.obj `if test -f 'src/modules-load.c'; then $(CYGPATH_W) 'src/modules-load.c'; else $(CYGPATH_W) '$(srcdir)/src/modules-load.c'; fi` + +src/login/systemd_multi_seat_x-multi-seat-x.o: src/login/multi-seat-x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_multi_seat_x_CFLAGS) $(CFLAGS) -MT src/login/systemd_multi_seat_x-multi-seat-x.o -MD -MP -MF src/login/$(DEPDIR)/systemd_multi_seat_x-multi-seat-x.Tpo -c -o src/login/systemd_multi_seat_x-multi-seat-x.o `test -f 'src/login/multi-seat-x.c' || echo '$(srcdir)/'`src/login/multi-seat-x.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_multi_seat_x-multi-seat-x.Tpo src/login/$(DEPDIR)/systemd_multi_seat_x-multi-seat-x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/multi-seat-x.c' object='src/login/systemd_multi_seat_x-multi-seat-x.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_multi_seat_x_CFLAGS) $(CFLAGS) -c -o src/login/systemd_multi_seat_x-multi-seat-x.o `test -f 'src/login/multi-seat-x.c' || echo '$(srcdir)/'`src/login/multi-seat-x.c + +src/login/systemd_multi_seat_x-multi-seat-x.obj: src/login/multi-seat-x.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_multi_seat_x_CFLAGS) $(CFLAGS) -MT src/login/systemd_multi_seat_x-multi-seat-x.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_multi_seat_x-multi-seat-x.Tpo -c -o src/login/systemd_multi_seat_x-multi-seat-x.obj `if test -f 'src/login/multi-seat-x.c'; then $(CYGPATH_W) 'src/login/multi-seat-x.c'; else $(CYGPATH_W) '$(srcdir)/src/login/multi-seat-x.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_multi_seat_x-multi-seat-x.Tpo src/login/$(DEPDIR)/systemd_multi_seat_x-multi-seat-x.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/multi-seat-x.c' object='src/login/systemd_multi_seat_x-multi-seat-x.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_multi_seat_x_CFLAGS) $(CFLAGS) -c -o src/login/systemd_multi_seat_x-multi-seat-x.obj `if test -f 'src/login/multi-seat-x.c'; then $(CYGPATH_W) 'src/login/multi-seat-x.c'; else $(CYGPATH_W) '$(srcdir)/src/login/multi-seat-x.c'; fi` + +src/readahead/systemd_readahead_collect-readahead-collect.o: src/readahead/readahead-collect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_collect_CFLAGS) $(CFLAGS) -MT src/readahead/systemd_readahead_collect-readahead-collect.o -MD -MP -MF src/readahead/$(DEPDIR)/systemd_readahead_collect-readahead-collect.Tpo -c -o src/readahead/systemd_readahead_collect-readahead-collect.o `test -f 'src/readahead/readahead-collect.c' || echo '$(srcdir)/'`src/readahead/readahead-collect.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/readahead/$(DEPDIR)/systemd_readahead_collect-readahead-collect.Tpo src/readahead/$(DEPDIR)/systemd_readahead_collect-readahead-collect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/readahead/readahead-collect.c' object='src/readahead/systemd_readahead_collect-readahead-collect.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_collect_CFLAGS) $(CFLAGS) -c -o src/readahead/systemd_readahead_collect-readahead-collect.o `test -f 'src/readahead/readahead-collect.c' || echo '$(srcdir)/'`src/readahead/readahead-collect.c + +src/readahead/systemd_readahead_collect-readahead-collect.obj: src/readahead/readahead-collect.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_collect_CFLAGS) $(CFLAGS) -MT src/readahead/systemd_readahead_collect-readahead-collect.obj -MD -MP -MF src/readahead/$(DEPDIR)/systemd_readahead_collect-readahead-collect.Tpo -c -o src/readahead/systemd_readahead_collect-readahead-collect.obj `if test -f 'src/readahead/readahead-collect.c'; then $(CYGPATH_W) 'src/readahead/readahead-collect.c'; else $(CYGPATH_W) '$(srcdir)/src/readahead/readahead-collect.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/readahead/$(DEPDIR)/systemd_readahead_collect-readahead-collect.Tpo src/readahead/$(DEPDIR)/systemd_readahead_collect-readahead-collect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/readahead/readahead-collect.c' object='src/readahead/systemd_readahead_collect-readahead-collect.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_collect_CFLAGS) $(CFLAGS) -c -o src/readahead/systemd_readahead_collect-readahead-collect.obj `if test -f 'src/readahead/readahead-collect.c'; then $(CYGPATH_W) 'src/readahead/readahead-collect.c'; else $(CYGPATH_W) '$(srcdir)/src/readahead/readahead-collect.c'; fi` + +src/readahead/systemd_readahead_collect-readahead-common.o: src/readahead/readahead-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_collect_CFLAGS) $(CFLAGS) -MT src/readahead/systemd_readahead_collect-readahead-common.o -MD -MP -MF src/readahead/$(DEPDIR)/systemd_readahead_collect-readahead-common.Tpo -c -o src/readahead/systemd_readahead_collect-readahead-common.o `test -f 'src/readahead/readahead-common.c' || echo '$(srcdir)/'`src/readahead/readahead-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/readahead/$(DEPDIR)/systemd_readahead_collect-readahead-common.Tpo src/readahead/$(DEPDIR)/systemd_readahead_collect-readahead-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/readahead/readahead-common.c' object='src/readahead/systemd_readahead_collect-readahead-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_collect_CFLAGS) $(CFLAGS) -c -o src/readahead/systemd_readahead_collect-readahead-common.o `test -f 'src/readahead/readahead-common.c' || echo '$(srcdir)/'`src/readahead/readahead-common.c + +src/readahead/systemd_readahead_collect-readahead-common.obj: src/readahead/readahead-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_collect_CFLAGS) $(CFLAGS) -MT src/readahead/systemd_readahead_collect-readahead-common.obj -MD -MP -MF src/readahead/$(DEPDIR)/systemd_readahead_collect-readahead-common.Tpo -c -o src/readahead/systemd_readahead_collect-readahead-common.obj `if test -f 'src/readahead/readahead-common.c'; then $(CYGPATH_W) 'src/readahead/readahead-common.c'; else $(CYGPATH_W) '$(srcdir)/src/readahead/readahead-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/readahead/$(DEPDIR)/systemd_readahead_collect-readahead-common.Tpo src/readahead/$(DEPDIR)/systemd_readahead_collect-readahead-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/readahead/readahead-common.c' object='src/readahead/systemd_readahead_collect-readahead-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_collect_CFLAGS) $(CFLAGS) -c -o src/readahead/systemd_readahead_collect-readahead-common.obj `if test -f 'src/readahead/readahead-common.c'; then $(CYGPATH_W) 'src/readahead/readahead-common.c'; else $(CYGPATH_W) '$(srcdir)/src/readahead/readahead-common.c'; fi` + +src/readahead/systemd_readahead_replay-readahead-replay.o: src/readahead/readahead-replay.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_replay_CFLAGS) $(CFLAGS) -MT src/readahead/systemd_readahead_replay-readahead-replay.o -MD -MP -MF src/readahead/$(DEPDIR)/systemd_readahead_replay-readahead-replay.Tpo -c -o src/readahead/systemd_readahead_replay-readahead-replay.o `test -f 'src/readahead/readahead-replay.c' || echo '$(srcdir)/'`src/readahead/readahead-replay.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/readahead/$(DEPDIR)/systemd_readahead_replay-readahead-replay.Tpo src/readahead/$(DEPDIR)/systemd_readahead_replay-readahead-replay.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/readahead/readahead-replay.c' object='src/readahead/systemd_readahead_replay-readahead-replay.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_replay_CFLAGS) $(CFLAGS) -c -o src/readahead/systemd_readahead_replay-readahead-replay.o `test -f 'src/readahead/readahead-replay.c' || echo '$(srcdir)/'`src/readahead/readahead-replay.c + +src/readahead/systemd_readahead_replay-readahead-replay.obj: src/readahead/readahead-replay.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_replay_CFLAGS) $(CFLAGS) -MT src/readahead/systemd_readahead_replay-readahead-replay.obj -MD -MP -MF src/readahead/$(DEPDIR)/systemd_readahead_replay-readahead-replay.Tpo -c -o src/readahead/systemd_readahead_replay-readahead-replay.obj `if test -f 'src/readahead/readahead-replay.c'; then $(CYGPATH_W) 'src/readahead/readahead-replay.c'; else $(CYGPATH_W) '$(srcdir)/src/readahead/readahead-replay.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/readahead/$(DEPDIR)/systemd_readahead_replay-readahead-replay.Tpo src/readahead/$(DEPDIR)/systemd_readahead_replay-readahead-replay.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/readahead/readahead-replay.c' object='src/readahead/systemd_readahead_replay-readahead-replay.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_replay_CFLAGS) $(CFLAGS) -c -o src/readahead/systemd_readahead_replay-readahead-replay.obj `if test -f 'src/readahead/readahead-replay.c'; then $(CYGPATH_W) 'src/readahead/readahead-replay.c'; else $(CYGPATH_W) '$(srcdir)/src/readahead/readahead-replay.c'; fi` + +src/readahead/systemd_readahead_replay-readahead-common.o: src/readahead/readahead-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_replay_CFLAGS) $(CFLAGS) -MT src/readahead/systemd_readahead_replay-readahead-common.o -MD -MP -MF src/readahead/$(DEPDIR)/systemd_readahead_replay-readahead-common.Tpo -c -o src/readahead/systemd_readahead_replay-readahead-common.o `test -f 'src/readahead/readahead-common.c' || echo '$(srcdir)/'`src/readahead/readahead-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/readahead/$(DEPDIR)/systemd_readahead_replay-readahead-common.Tpo src/readahead/$(DEPDIR)/systemd_readahead_replay-readahead-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/readahead/readahead-common.c' object='src/readahead/systemd_readahead_replay-readahead-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_replay_CFLAGS) $(CFLAGS) -c -o src/readahead/systemd_readahead_replay-readahead-common.o `test -f 'src/readahead/readahead-common.c' || echo '$(srcdir)/'`src/readahead/readahead-common.c + +src/readahead/systemd_readahead_replay-readahead-common.obj: src/readahead/readahead-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_replay_CFLAGS) $(CFLAGS) -MT src/readahead/systemd_readahead_replay-readahead-common.obj -MD -MP -MF src/readahead/$(DEPDIR)/systemd_readahead_replay-readahead-common.Tpo -c -o src/readahead/systemd_readahead_replay-readahead-common.obj `if test -f 'src/readahead/readahead-common.c'; then $(CYGPATH_W) 'src/readahead/readahead-common.c'; else $(CYGPATH_W) '$(srcdir)/src/readahead/readahead-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/readahead/$(DEPDIR)/systemd_readahead_replay-readahead-common.Tpo src/readahead/$(DEPDIR)/systemd_readahead_replay-readahead-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/readahead/readahead-common.c' object='src/readahead/systemd_readahead_replay-readahead-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_readahead_replay_CFLAGS) $(CFLAGS) -c -o src/readahead/systemd_readahead_replay-readahead-common.obj `if test -f 'src/readahead/readahead-common.c'; then $(CYGPATH_W) 'src/readahead/readahead-common.c'; else $(CYGPATH_W) '$(srcdir)/src/readahead/readahead-common.c'; fi` + +src/systemd_shutdown-mount-setup.o: src/mount-setup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdown_CFLAGS) $(CFLAGS) -MT src/systemd_shutdown-mount-setup.o -MD -MP -MF src/$(DEPDIR)/systemd_shutdown-mount-setup.Tpo -c -o src/systemd_shutdown-mount-setup.o `test -f 'src/mount-setup.c' || echo '$(srcdir)/'`src/mount-setup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_shutdown-mount-setup.Tpo src/$(DEPDIR)/systemd_shutdown-mount-setup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/mount-setup.c' object='src/systemd_shutdown-mount-setup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdown_CFLAGS) $(CFLAGS) -c -o src/systemd_shutdown-mount-setup.o `test -f 'src/mount-setup.c' || echo '$(srcdir)/'`src/mount-setup.c + +src/systemd_shutdown-mount-setup.obj: src/mount-setup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdown_CFLAGS) $(CFLAGS) -MT src/systemd_shutdown-mount-setup.obj -MD -MP -MF src/$(DEPDIR)/systemd_shutdown-mount-setup.Tpo -c -o src/systemd_shutdown-mount-setup.obj `if test -f 'src/mount-setup.c'; then $(CYGPATH_W) 'src/mount-setup.c'; else $(CYGPATH_W) '$(srcdir)/src/mount-setup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_shutdown-mount-setup.Tpo src/$(DEPDIR)/systemd_shutdown-mount-setup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/mount-setup.c' object='src/systemd_shutdown-mount-setup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdown_CFLAGS) $(CFLAGS) -c -o src/systemd_shutdown-mount-setup.obj `if test -f 'src/mount-setup.c'; then $(CYGPATH_W) 'src/mount-setup.c'; else $(CYGPATH_W) '$(srcdir)/src/mount-setup.c'; fi` + +src/systemd_shutdown-umount.o: src/umount.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdown_CFLAGS) $(CFLAGS) -MT src/systemd_shutdown-umount.o -MD -MP -MF src/$(DEPDIR)/systemd_shutdown-umount.Tpo -c -o src/systemd_shutdown-umount.o `test -f 'src/umount.c' || echo '$(srcdir)/'`src/umount.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_shutdown-umount.Tpo src/$(DEPDIR)/systemd_shutdown-umount.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/umount.c' object='src/systemd_shutdown-umount.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdown_CFLAGS) $(CFLAGS) -c -o src/systemd_shutdown-umount.o `test -f 'src/umount.c' || echo '$(srcdir)/'`src/umount.c + +src/systemd_shutdown-umount.obj: src/umount.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdown_CFLAGS) $(CFLAGS) -MT src/systemd_shutdown-umount.obj -MD -MP -MF src/$(DEPDIR)/systemd_shutdown-umount.Tpo -c -o src/systemd_shutdown-umount.obj `if test -f 'src/umount.c'; then $(CYGPATH_W) 'src/umount.c'; else $(CYGPATH_W) '$(srcdir)/src/umount.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_shutdown-umount.Tpo src/$(DEPDIR)/systemd_shutdown-umount.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/umount.c' object='src/systemd_shutdown-umount.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdown_CFLAGS) $(CFLAGS) -c -o src/systemd_shutdown-umount.obj `if test -f 'src/umount.c'; then $(CYGPATH_W) 'src/umount.c'; else $(CYGPATH_W) '$(srcdir)/src/umount.c'; fi` + +src/systemd_shutdown-shutdown.o: src/shutdown.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdown_CFLAGS) $(CFLAGS) -MT src/systemd_shutdown-shutdown.o -MD -MP -MF src/$(DEPDIR)/systemd_shutdown-shutdown.Tpo -c -o src/systemd_shutdown-shutdown.o `test -f 'src/shutdown.c' || echo '$(srcdir)/'`src/shutdown.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_shutdown-shutdown.Tpo src/$(DEPDIR)/systemd_shutdown-shutdown.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/shutdown.c' object='src/systemd_shutdown-shutdown.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdown_CFLAGS) $(CFLAGS) -c -o src/systemd_shutdown-shutdown.o `test -f 'src/shutdown.c' || echo '$(srcdir)/'`src/shutdown.c + +src/systemd_shutdown-shutdown.obj: src/shutdown.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdown_CFLAGS) $(CFLAGS) -MT src/systemd_shutdown-shutdown.obj -MD -MP -MF src/$(DEPDIR)/systemd_shutdown-shutdown.Tpo -c -o src/systemd_shutdown-shutdown.obj `if test -f 'src/shutdown.c'; then $(CYGPATH_W) 'src/shutdown.c'; else $(CYGPATH_W) '$(srcdir)/src/shutdown.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_shutdown-shutdown.Tpo src/$(DEPDIR)/systemd_shutdown-shutdown.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/shutdown.c' object='src/systemd_shutdown-shutdown.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdown_CFLAGS) $(CFLAGS) -c -o src/systemd_shutdown-shutdown.obj `if test -f 'src/shutdown.c'; then $(CYGPATH_W) 'src/shutdown.c'; else $(CYGPATH_W) '$(srcdir)/src/shutdown.c'; fi` + +src/systemd_shutdownd-utmp-wtmp.o: src/utmp-wtmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdownd_CFLAGS) $(CFLAGS) -MT src/systemd_shutdownd-utmp-wtmp.o -MD -MP -MF src/$(DEPDIR)/systemd_shutdownd-utmp-wtmp.Tpo -c -o src/systemd_shutdownd-utmp-wtmp.o `test -f 'src/utmp-wtmp.c' || echo '$(srcdir)/'`src/utmp-wtmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_shutdownd-utmp-wtmp.Tpo src/$(DEPDIR)/systemd_shutdownd-utmp-wtmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/utmp-wtmp.c' object='src/systemd_shutdownd-utmp-wtmp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdownd_CFLAGS) $(CFLAGS) -c -o src/systemd_shutdownd-utmp-wtmp.o `test -f 'src/utmp-wtmp.c' || echo '$(srcdir)/'`src/utmp-wtmp.c + +src/systemd_shutdownd-utmp-wtmp.obj: src/utmp-wtmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdownd_CFLAGS) $(CFLAGS) -MT src/systemd_shutdownd-utmp-wtmp.obj -MD -MP -MF src/$(DEPDIR)/systemd_shutdownd-utmp-wtmp.Tpo -c -o src/systemd_shutdownd-utmp-wtmp.obj `if test -f 'src/utmp-wtmp.c'; then $(CYGPATH_W) 'src/utmp-wtmp.c'; else $(CYGPATH_W) '$(srcdir)/src/utmp-wtmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_shutdownd-utmp-wtmp.Tpo src/$(DEPDIR)/systemd_shutdownd-utmp-wtmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/utmp-wtmp.c' object='src/systemd_shutdownd-utmp-wtmp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdownd_CFLAGS) $(CFLAGS) -c -o src/systemd_shutdownd-utmp-wtmp.obj `if test -f 'src/utmp-wtmp.c'; then $(CYGPATH_W) 'src/utmp-wtmp.c'; else $(CYGPATH_W) '$(srcdir)/src/utmp-wtmp.c'; fi` + +src/systemd_shutdownd-shutdownd.o: src/shutdownd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdownd_CFLAGS) $(CFLAGS) -MT src/systemd_shutdownd-shutdownd.o -MD -MP -MF src/$(DEPDIR)/systemd_shutdownd-shutdownd.Tpo -c -o src/systemd_shutdownd-shutdownd.o `test -f 'src/shutdownd.c' || echo '$(srcdir)/'`src/shutdownd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_shutdownd-shutdownd.Tpo src/$(DEPDIR)/systemd_shutdownd-shutdownd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/shutdownd.c' object='src/systemd_shutdownd-shutdownd.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdownd_CFLAGS) $(CFLAGS) -c -o src/systemd_shutdownd-shutdownd.o `test -f 'src/shutdownd.c' || echo '$(srcdir)/'`src/shutdownd.c + +src/systemd_shutdownd-shutdownd.obj: src/shutdownd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdownd_CFLAGS) $(CFLAGS) -MT src/systemd_shutdownd-shutdownd.obj -MD -MP -MF src/$(DEPDIR)/systemd_shutdownd-shutdownd.Tpo -c -o src/systemd_shutdownd-shutdownd.obj `if test -f 'src/shutdownd.c'; then $(CYGPATH_W) 'src/shutdownd.c'; else $(CYGPATH_W) '$(srcdir)/src/shutdownd.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_shutdownd-shutdownd.Tpo src/$(DEPDIR)/systemd_shutdownd-shutdownd.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/shutdownd.c' object='src/systemd_shutdownd-shutdownd.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_shutdownd_CFLAGS) $(CFLAGS) -c -o src/systemd_shutdownd-shutdownd.obj `if test -f 'src/shutdownd.c'; then $(CYGPATH_W) 'src/shutdownd.c'; else $(CYGPATH_W) '$(srcdir)/src/shutdownd.c'; fi` + +src/timedate/systemd_timedated-timedated.o: src/timedate/timedated.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_timedated_CFLAGS) $(CFLAGS) -MT src/timedate/systemd_timedated-timedated.o -MD -MP -MF src/timedate/$(DEPDIR)/systemd_timedated-timedated.Tpo -c -o src/timedate/systemd_timedated-timedated.o `test -f 'src/timedate/timedated.c' || echo '$(srcdir)/'`src/timedate/timedated.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/timedate/$(DEPDIR)/systemd_timedated-timedated.Tpo src/timedate/$(DEPDIR)/systemd_timedated-timedated.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/timedate/timedated.c' object='src/timedate/systemd_timedated-timedated.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_timedated_CFLAGS) $(CFLAGS) -c -o src/timedate/systemd_timedated-timedated.o `test -f 'src/timedate/timedated.c' || echo '$(srcdir)/'`src/timedate/timedated.c + +src/timedate/systemd_timedated-timedated.obj: src/timedate/timedated.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_timedated_CFLAGS) $(CFLAGS) -MT src/timedate/systemd_timedated-timedated.obj -MD -MP -MF src/timedate/$(DEPDIR)/systemd_timedated-timedated.Tpo -c -o src/timedate/systemd_timedated-timedated.obj `if test -f 'src/timedate/timedated.c'; then $(CYGPATH_W) 'src/timedate/timedated.c'; else $(CYGPATH_W) '$(srcdir)/src/timedate/timedated.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/timedate/$(DEPDIR)/systemd_timedated-timedated.Tpo src/timedate/$(DEPDIR)/systemd_timedated-timedated.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/timedate/timedated.c' object='src/timedate/systemd_timedated-timedated.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_timedated_CFLAGS) $(CFLAGS) -c -o src/timedate/systemd_timedated-timedated.obj `if test -f 'src/timedate/timedated.c'; then $(CYGPATH_W) 'src/timedate/timedated.c'; else $(CYGPATH_W) '$(srcdir)/src/timedate/timedated.c'; fi` + +src/systemd_timedated-dbus-common.o: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_timedated_CFLAGS) $(CFLAGS) -MT src/systemd_timedated-dbus-common.o -MD -MP -MF src/$(DEPDIR)/systemd_timedated-dbus-common.Tpo -c -o src/systemd_timedated-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_timedated-dbus-common.Tpo src/$(DEPDIR)/systemd_timedated-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_timedated-dbus-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_timedated_CFLAGS) $(CFLAGS) -c -o src/systemd_timedated-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c + +src/systemd_timedated-dbus-common.obj: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_timedated_CFLAGS) $(CFLAGS) -MT src/systemd_timedated-dbus-common.obj -MD -MP -MF src/$(DEPDIR)/systemd_timedated-dbus-common.Tpo -c -o src/systemd_timedated-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_timedated-dbus-common.Tpo src/$(DEPDIR)/systemd_timedated-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_timedated-dbus-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_timedated_CFLAGS) $(CFLAGS) -c -o src/systemd_timedated-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` + +src/systemd_timedated-polkit.o: src/polkit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_timedated_CFLAGS) $(CFLAGS) -MT src/systemd_timedated-polkit.o -MD -MP -MF src/$(DEPDIR)/systemd_timedated-polkit.Tpo -c -o src/systemd_timedated-polkit.o `test -f 'src/polkit.c' || echo '$(srcdir)/'`src/polkit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_timedated-polkit.Tpo src/$(DEPDIR)/systemd_timedated-polkit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/polkit.c' object='src/systemd_timedated-polkit.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_timedated_CFLAGS) $(CFLAGS) -c -o src/systemd_timedated-polkit.o `test -f 'src/polkit.c' || echo '$(srcdir)/'`src/polkit.c + +src/systemd_timedated-polkit.obj: src/polkit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_timedated_CFLAGS) $(CFLAGS) -MT src/systemd_timedated-polkit.obj -MD -MP -MF src/$(DEPDIR)/systemd_timedated-polkit.Tpo -c -o src/systemd_timedated-polkit.obj `if test -f 'src/polkit.c'; then $(CYGPATH_W) 'src/polkit.c'; else $(CYGPATH_W) '$(srcdir)/src/polkit.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_timedated-polkit.Tpo src/$(DEPDIR)/systemd_timedated-polkit.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/polkit.c' object='src/systemd_timedated-polkit.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_timedated_CFLAGS) $(CFLAGS) -c -o src/systemd_timedated-polkit.obj `if test -f 'src/polkit.c'; then $(CYGPATH_W) 'src/polkit.c'; else $(CYGPATH_W) '$(srcdir)/src/polkit.c'; fi` + +src/login/systemd_uaccess-uaccess.o: src/login/uaccess.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_uaccess_CFLAGS) $(CFLAGS) -MT src/login/systemd_uaccess-uaccess.o -MD -MP -MF src/login/$(DEPDIR)/systemd_uaccess-uaccess.Tpo -c -o src/login/systemd_uaccess-uaccess.o `test -f 'src/login/uaccess.c' || echo '$(srcdir)/'`src/login/uaccess.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_uaccess-uaccess.Tpo src/login/$(DEPDIR)/systemd_uaccess-uaccess.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/uaccess.c' object='src/login/systemd_uaccess-uaccess.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_uaccess_CFLAGS) $(CFLAGS) -c -o src/login/systemd_uaccess-uaccess.o `test -f 'src/login/uaccess.c' || echo '$(srcdir)/'`src/login/uaccess.c + +src/login/systemd_uaccess-uaccess.obj: src/login/uaccess.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_uaccess_CFLAGS) $(CFLAGS) -MT src/login/systemd_uaccess-uaccess.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_uaccess-uaccess.Tpo -c -o src/login/systemd_uaccess-uaccess.obj `if test -f 'src/login/uaccess.c'; then $(CYGPATH_W) 'src/login/uaccess.c'; else $(CYGPATH_W) '$(srcdir)/src/login/uaccess.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_uaccess-uaccess.Tpo src/login/$(DEPDIR)/systemd_uaccess-uaccess.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/uaccess.c' object='src/login/systemd_uaccess-uaccess.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_uaccess_CFLAGS) $(CFLAGS) -c -o src/login/systemd_uaccess-uaccess.obj `if test -f 'src/login/uaccess.c'; then $(CYGPATH_W) 'src/login/uaccess.c'; else $(CYGPATH_W) '$(srcdir)/src/login/uaccess.c'; fi` + +src/login/systemd_uaccess-logind-acl.o: src/login/logind-acl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_uaccess_CFLAGS) $(CFLAGS) -MT src/login/systemd_uaccess-logind-acl.o -MD -MP -MF src/login/$(DEPDIR)/systemd_uaccess-logind-acl.Tpo -c -o src/login/systemd_uaccess-logind-acl.o `test -f 'src/login/logind-acl.c' || echo '$(srcdir)/'`src/login/logind-acl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_uaccess-logind-acl.Tpo src/login/$(DEPDIR)/systemd_uaccess-logind-acl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-acl.c' object='src/login/systemd_uaccess-logind-acl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_uaccess_CFLAGS) $(CFLAGS) -c -o src/login/systemd_uaccess-logind-acl.o `test -f 'src/login/logind-acl.c' || echo '$(srcdir)/'`src/login/logind-acl.c + +src/login/systemd_uaccess-logind-acl.obj: src/login/logind-acl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_uaccess_CFLAGS) $(CFLAGS) -MT src/login/systemd_uaccess-logind-acl.obj -MD -MP -MF src/login/$(DEPDIR)/systemd_uaccess-logind-acl.Tpo -c -o src/login/systemd_uaccess-logind-acl.obj `if test -f 'src/login/logind-acl.c'; then $(CYGPATH_W) 'src/login/logind-acl.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-acl.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/login/$(DEPDIR)/systemd_uaccess-logind-acl.Tpo src/login/$(DEPDIR)/systemd_uaccess-logind-acl.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/login/logind-acl.c' object='src/login/systemd_uaccess-logind-acl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_uaccess_CFLAGS) $(CFLAGS) -c -o src/login/systemd_uaccess-logind-acl.obj `if test -f 'src/login/logind-acl.c'; then $(CYGPATH_W) 'src/login/logind-acl.c'; else $(CYGPATH_W) '$(srcdir)/src/login/logind-acl.c'; fi` + +src/systemd_uaccess-acl-util.o: src/acl-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_uaccess_CFLAGS) $(CFLAGS) -MT src/systemd_uaccess-acl-util.o -MD -MP -MF src/$(DEPDIR)/systemd_uaccess-acl-util.Tpo -c -o src/systemd_uaccess-acl-util.o `test -f 'src/acl-util.c' || echo '$(srcdir)/'`src/acl-util.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_uaccess-acl-util.Tpo src/$(DEPDIR)/systemd_uaccess-acl-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/acl-util.c' object='src/systemd_uaccess-acl-util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_uaccess_CFLAGS) $(CFLAGS) -c -o src/systemd_uaccess-acl-util.o `test -f 'src/acl-util.c' || echo '$(srcdir)/'`src/acl-util.c + +src/systemd_uaccess-acl-util.obj: src/acl-util.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_uaccess_CFLAGS) $(CFLAGS) -MT src/systemd_uaccess-acl-util.obj -MD -MP -MF src/$(DEPDIR)/systemd_uaccess-acl-util.Tpo -c -o src/systemd_uaccess-acl-util.obj `if test -f 'src/acl-util.c'; then $(CYGPATH_W) 'src/acl-util.c'; else $(CYGPATH_W) '$(srcdir)/src/acl-util.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_uaccess-acl-util.Tpo src/$(DEPDIR)/systemd_uaccess-acl-util.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/acl-util.c' object='src/systemd_uaccess-acl-util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_uaccess_CFLAGS) $(CFLAGS) -c -o src/systemd_uaccess-acl-util.obj `if test -f 'src/acl-util.c'; then $(CYGPATH_W) 'src/acl-util.c'; else $(CYGPATH_W) '$(srcdir)/src/acl-util.c'; fi` + +src/systemd_update_utmp-update-utmp.o: src/update-utmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_update_utmp_CFLAGS) $(CFLAGS) -MT src/systemd_update_utmp-update-utmp.o -MD -MP -MF src/$(DEPDIR)/systemd_update_utmp-update-utmp.Tpo -c -o src/systemd_update_utmp-update-utmp.o `test -f 'src/update-utmp.c' || echo '$(srcdir)/'`src/update-utmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_update_utmp-update-utmp.Tpo src/$(DEPDIR)/systemd_update_utmp-update-utmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/update-utmp.c' object='src/systemd_update_utmp-update-utmp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_update_utmp_CFLAGS) $(CFLAGS) -c -o src/systemd_update_utmp-update-utmp.o `test -f 'src/update-utmp.c' || echo '$(srcdir)/'`src/update-utmp.c + +src/systemd_update_utmp-update-utmp.obj: src/update-utmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_update_utmp_CFLAGS) $(CFLAGS) -MT src/systemd_update_utmp-update-utmp.obj -MD -MP -MF src/$(DEPDIR)/systemd_update_utmp-update-utmp.Tpo -c -o src/systemd_update_utmp-update-utmp.obj `if test -f 'src/update-utmp.c'; then $(CYGPATH_W) 'src/update-utmp.c'; else $(CYGPATH_W) '$(srcdir)/src/update-utmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_update_utmp-update-utmp.Tpo src/$(DEPDIR)/systemd_update_utmp-update-utmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/update-utmp.c' object='src/systemd_update_utmp-update-utmp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_update_utmp_CFLAGS) $(CFLAGS) -c -o src/systemd_update_utmp-update-utmp.obj `if test -f 'src/update-utmp.c'; then $(CYGPATH_W) 'src/update-utmp.c'; else $(CYGPATH_W) '$(srcdir)/src/update-utmp.c'; fi` + +src/systemd_update_utmp-dbus-common.o: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_update_utmp_CFLAGS) $(CFLAGS) -MT src/systemd_update_utmp-dbus-common.o -MD -MP -MF src/$(DEPDIR)/systemd_update_utmp-dbus-common.Tpo -c -o src/systemd_update_utmp-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_update_utmp-dbus-common.Tpo src/$(DEPDIR)/systemd_update_utmp-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_update_utmp-dbus-common.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_update_utmp_CFLAGS) $(CFLAGS) -c -o src/systemd_update_utmp-dbus-common.o `test -f 'src/dbus-common.c' || echo '$(srcdir)/'`src/dbus-common.c + +src/systemd_update_utmp-dbus-common.obj: src/dbus-common.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_update_utmp_CFLAGS) $(CFLAGS) -MT src/systemd_update_utmp-dbus-common.obj -MD -MP -MF src/$(DEPDIR)/systemd_update_utmp-dbus-common.Tpo -c -o src/systemd_update_utmp-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_update_utmp-dbus-common.Tpo src/$(DEPDIR)/systemd_update_utmp-dbus-common.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/dbus-common.c' object='src/systemd_update_utmp-dbus-common.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_update_utmp_CFLAGS) $(CFLAGS) -c -o src/systemd_update_utmp-dbus-common.obj `if test -f 'src/dbus-common.c'; then $(CYGPATH_W) 'src/dbus-common.c'; else $(CYGPATH_W) '$(srcdir)/src/dbus-common.c'; fi` + +src/systemd_update_utmp-utmp-wtmp.o: src/utmp-wtmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_update_utmp_CFLAGS) $(CFLAGS) -MT src/systemd_update_utmp-utmp-wtmp.o -MD -MP -MF src/$(DEPDIR)/systemd_update_utmp-utmp-wtmp.Tpo -c -o src/systemd_update_utmp-utmp-wtmp.o `test -f 'src/utmp-wtmp.c' || echo '$(srcdir)/'`src/utmp-wtmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_update_utmp-utmp-wtmp.Tpo src/$(DEPDIR)/systemd_update_utmp-utmp-wtmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/utmp-wtmp.c' object='src/systemd_update_utmp-utmp-wtmp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_update_utmp_CFLAGS) $(CFLAGS) -c -o src/systemd_update_utmp-utmp-wtmp.o `test -f 'src/utmp-wtmp.c' || echo '$(srcdir)/'`src/utmp-wtmp.c + +src/systemd_update_utmp-utmp-wtmp.obj: src/utmp-wtmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_update_utmp_CFLAGS) $(CFLAGS) -MT src/systemd_update_utmp-utmp-wtmp.obj -MD -MP -MF src/$(DEPDIR)/systemd_update_utmp-utmp-wtmp.Tpo -c -o src/systemd_update_utmp-utmp-wtmp.obj `if test -f 'src/utmp-wtmp.c'; then $(CYGPATH_W) 'src/utmp-wtmp.c'; else $(CYGPATH_W) '$(srcdir)/src/utmp-wtmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/systemd_update_utmp-utmp-wtmp.Tpo src/$(DEPDIR)/systemd_update_utmp-utmp-wtmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/utmp-wtmp.c' object='src/systemd_update_utmp-utmp-wtmp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(systemd_update_utmp_CFLAGS) $(CFLAGS) -c -o src/systemd_update_utmp-utmp-wtmp.obj `if test -f 'src/utmp-wtmp.c'; then $(CYGPATH_W) 'src/utmp-wtmp.c'; else $(CYGPATH_W) '$(srcdir)/src/utmp-wtmp.c'; fi` + +src/test_engine-test-engine.o: src/test-engine.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_engine_CFLAGS) $(CFLAGS) -MT src/test_engine-test-engine.o -MD -MP -MF src/$(DEPDIR)/test_engine-test-engine.Tpo -c -o src/test_engine-test-engine.o `test -f 'src/test-engine.c' || echo '$(srcdir)/'`src/test-engine.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_engine-test-engine.Tpo src/$(DEPDIR)/test_engine-test-engine.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/test-engine.c' object='src/test_engine-test-engine.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_engine_CFLAGS) $(CFLAGS) -c -o src/test_engine-test-engine.o `test -f 'src/test-engine.c' || echo '$(srcdir)/'`src/test-engine.c + +src/test_engine-test-engine.obj: src/test-engine.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_engine_CFLAGS) $(CFLAGS) -MT src/test_engine-test-engine.obj -MD -MP -MF src/$(DEPDIR)/test_engine-test-engine.Tpo -c -o src/test_engine-test-engine.obj `if test -f 'src/test-engine.c'; then $(CYGPATH_W) 'src/test-engine.c'; else $(CYGPATH_W) '$(srcdir)/src/test-engine.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_engine-test-engine.Tpo src/$(DEPDIR)/test_engine-test-engine.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/test-engine.c' object='src/test_engine-test-engine.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_engine_CFLAGS) $(CFLAGS) -c -o src/test_engine-test-engine.obj `if test -f 'src/test-engine.c'; then $(CYGPATH_W) 'src/test-engine.c'; else $(CYGPATH_W) '$(srcdir)/src/test-engine.c'; fi` + +src/test_install-test-install.o: src/test-install.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -MT src/test_install-test-install.o -MD -MP -MF src/$(DEPDIR)/test_install-test-install.Tpo -c -o src/test_install-test-install.o `test -f 'src/test-install.c' || echo '$(srcdir)/'`src/test-install.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_install-test-install.Tpo src/$(DEPDIR)/test_install-test-install.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/test-install.c' object='src/test_install-test-install.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -c -o src/test_install-test-install.o `test -f 'src/test-install.c' || echo '$(srcdir)/'`src/test-install.c + +src/test_install-test-install.obj: src/test-install.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -MT src/test_install-test-install.obj -MD -MP -MF src/$(DEPDIR)/test_install-test-install.Tpo -c -o src/test_install-test-install.obj `if test -f 'src/test-install.c'; then $(CYGPATH_W) 'src/test-install.c'; else $(CYGPATH_W) '$(srcdir)/src/test-install.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_install-test-install.Tpo src/$(DEPDIR)/test_install-test-install.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/test-install.c' object='src/test_install-test-install.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -c -o src/test_install-test-install.obj `if test -f 'src/test-install.c'; then $(CYGPATH_W) 'src/test-install.c'; else $(CYGPATH_W) '$(srcdir)/src/test-install.c'; fi` + +src/test_install-install.o: src/install.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -MT src/test_install-install.o -MD -MP -MF src/$(DEPDIR)/test_install-install.Tpo -c -o src/test_install-install.o `test -f 'src/install.c' || echo '$(srcdir)/'`src/install.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_install-install.Tpo src/$(DEPDIR)/test_install-install.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/install.c' object='src/test_install-install.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -c -o src/test_install-install.o `test -f 'src/install.c' || echo '$(srcdir)/'`src/install.c + +src/test_install-install.obj: src/install.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -MT src/test_install-install.obj -MD -MP -MF src/$(DEPDIR)/test_install-install.Tpo -c -o src/test_install-install.obj `if test -f 'src/install.c'; then $(CYGPATH_W) 'src/install.c'; else $(CYGPATH_W) '$(srcdir)/src/install.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_install-install.Tpo src/$(DEPDIR)/test_install-install.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/install.c' object='src/test_install-install.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -c -o src/test_install-install.obj `if test -f 'src/install.c'; then $(CYGPATH_W) 'src/install.c'; else $(CYGPATH_W) '$(srcdir)/src/install.c'; fi` + +src/test_install-path-lookup.o: src/path-lookup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -MT src/test_install-path-lookup.o -MD -MP -MF src/$(DEPDIR)/test_install-path-lookup.Tpo -c -o src/test_install-path-lookup.o `test -f 'src/path-lookup.c' || echo '$(srcdir)/'`src/path-lookup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_install-path-lookup.Tpo src/$(DEPDIR)/test_install-path-lookup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/path-lookup.c' object='src/test_install-path-lookup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -c -o src/test_install-path-lookup.o `test -f 'src/path-lookup.c' || echo '$(srcdir)/'`src/path-lookup.c + +src/test_install-path-lookup.obj: src/path-lookup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -MT src/test_install-path-lookup.obj -MD -MP -MF src/$(DEPDIR)/test_install-path-lookup.Tpo -c -o src/test_install-path-lookup.obj `if test -f 'src/path-lookup.c'; then $(CYGPATH_W) 'src/path-lookup.c'; else $(CYGPATH_W) '$(srcdir)/src/path-lookup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_install-path-lookup.Tpo src/$(DEPDIR)/test_install-path-lookup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/path-lookup.c' object='src/test_install-path-lookup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -c -o src/test_install-path-lookup.obj `if test -f 'src/path-lookup.c'; then $(CYGPATH_W) 'src/path-lookup.c'; else $(CYGPATH_W) '$(srcdir)/src/path-lookup.c'; fi` + +src/test_install-unit-name.o: src/unit-name.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -MT src/test_install-unit-name.o -MD -MP -MF src/$(DEPDIR)/test_install-unit-name.Tpo -c -o src/test_install-unit-name.o `test -f 'src/unit-name.c' || echo '$(srcdir)/'`src/unit-name.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_install-unit-name.Tpo src/$(DEPDIR)/test_install-unit-name.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/unit-name.c' object='src/test_install-unit-name.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -c -o src/test_install-unit-name.o `test -f 'src/unit-name.c' || echo '$(srcdir)/'`src/unit-name.c + +src/test_install-unit-name.obj: src/unit-name.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -MT src/test_install-unit-name.obj -MD -MP -MF src/$(DEPDIR)/test_install-unit-name.Tpo -c -o src/test_install-unit-name.obj `if test -f 'src/unit-name.c'; then $(CYGPATH_W) 'src/unit-name.c'; else $(CYGPATH_W) '$(srcdir)/src/unit-name.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_install-unit-name.Tpo src/$(DEPDIR)/test_install-unit-name.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/unit-name.c' object='src/test_install-unit-name.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_install_CFLAGS) $(CFLAGS) -c -o src/test_install-unit-name.obj `if test -f 'src/unit-name.c'; then $(CYGPATH_W) 'src/unit-name.c'; else $(CYGPATH_W) '$(srcdir)/src/unit-name.c'; fi` + +src/test_job_type-test-job-type.o: src/test-job-type.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_job_type_CFLAGS) $(CFLAGS) -MT src/test_job_type-test-job-type.o -MD -MP -MF src/$(DEPDIR)/test_job_type-test-job-type.Tpo -c -o src/test_job_type-test-job-type.o `test -f 'src/test-job-type.c' || echo '$(srcdir)/'`src/test-job-type.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_job_type-test-job-type.Tpo src/$(DEPDIR)/test_job_type-test-job-type.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/test-job-type.c' object='src/test_job_type-test-job-type.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_job_type_CFLAGS) $(CFLAGS) -c -o src/test_job_type-test-job-type.o `test -f 'src/test-job-type.c' || echo '$(srcdir)/'`src/test-job-type.c + +src/test_job_type-test-job-type.obj: src/test-job-type.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_job_type_CFLAGS) $(CFLAGS) -MT src/test_job_type-test-job-type.obj -MD -MP -MF src/$(DEPDIR)/test_job_type-test-job-type.Tpo -c -o src/test_job_type-test-job-type.obj `if test -f 'src/test-job-type.c'; then $(CYGPATH_W) 'src/test-job-type.c'; else $(CYGPATH_W) '$(srcdir)/src/test-job-type.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_job_type-test-job-type.Tpo src/$(DEPDIR)/test_job_type-test-job-type.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/test-job-type.c' object='src/test_job_type-test-job-type.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_job_type_CFLAGS) $(CFLAGS) -c -o src/test_job_type-test-job-type.obj `if test -f 'src/test-job-type.c'; then $(CYGPATH_W) 'src/test-job-type.c'; else $(CYGPATH_W) '$(srcdir)/src/test-job-type.c'; fi` + +src/journal/test_journal-test-journal.o: src/journal/test-journal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -MT src/journal/test_journal-test-journal.o -MD -MP -MF src/journal/$(DEPDIR)/test_journal-test-journal.Tpo -c -o src/journal/test_journal-test-journal.o `test -f 'src/journal/test-journal.c' || echo '$(srcdir)/'`src/journal/test-journal.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/test_journal-test-journal.Tpo src/journal/$(DEPDIR)/test_journal-test-journal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/test-journal.c' object='src/journal/test_journal-test-journal.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -c -o src/journal/test_journal-test-journal.o `test -f 'src/journal/test-journal.c' || echo '$(srcdir)/'`src/journal/test-journal.c + +src/journal/test_journal-test-journal.obj: src/journal/test-journal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -MT src/journal/test_journal-test-journal.obj -MD -MP -MF src/journal/$(DEPDIR)/test_journal-test-journal.Tpo -c -o src/journal/test_journal-test-journal.obj `if test -f 'src/journal/test-journal.c'; then $(CYGPATH_W) 'src/journal/test-journal.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/test-journal.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/test_journal-test-journal.Tpo src/journal/$(DEPDIR)/test_journal-test-journal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/test-journal.c' object='src/journal/test_journal-test-journal.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -c -o src/journal/test_journal-test-journal.obj `if test -f 'src/journal/test-journal.c'; then $(CYGPATH_W) 'src/journal/test-journal.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/test-journal.c'; fi` + +src/journal/test_journal-sd-journal.o: src/journal/sd-journal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -MT src/journal/test_journal-sd-journal.o -MD -MP -MF src/journal/$(DEPDIR)/test_journal-sd-journal.Tpo -c -o src/journal/test_journal-sd-journal.o `test -f 'src/journal/sd-journal.c' || echo '$(srcdir)/'`src/journal/sd-journal.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/test_journal-sd-journal.Tpo src/journal/$(DEPDIR)/test_journal-sd-journal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/sd-journal.c' object='src/journal/test_journal-sd-journal.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -c -o src/journal/test_journal-sd-journal.o `test -f 'src/journal/sd-journal.c' || echo '$(srcdir)/'`src/journal/sd-journal.c + +src/journal/test_journal-sd-journal.obj: src/journal/sd-journal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -MT src/journal/test_journal-sd-journal.obj -MD -MP -MF src/journal/$(DEPDIR)/test_journal-sd-journal.Tpo -c -o src/journal/test_journal-sd-journal.obj `if test -f 'src/journal/sd-journal.c'; then $(CYGPATH_W) 'src/journal/sd-journal.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/sd-journal.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/test_journal-sd-journal.Tpo src/journal/$(DEPDIR)/test_journal-sd-journal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/sd-journal.c' object='src/journal/test_journal-sd-journal.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -c -o src/journal/test_journal-sd-journal.obj `if test -f 'src/journal/sd-journal.c'; then $(CYGPATH_W) 'src/journal/sd-journal.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/sd-journal.c'; fi` + +src/journal/test_journal-journal-file.o: src/journal/journal-file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -MT src/journal/test_journal-journal-file.o -MD -MP -MF src/journal/$(DEPDIR)/test_journal-journal-file.Tpo -c -o src/journal/test_journal-journal-file.o `test -f 'src/journal/journal-file.c' || echo '$(srcdir)/'`src/journal/journal-file.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/test_journal-journal-file.Tpo src/journal/$(DEPDIR)/test_journal-journal-file.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journal-file.c' object='src/journal/test_journal-journal-file.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -c -o src/journal/test_journal-journal-file.o `test -f 'src/journal/journal-file.c' || echo '$(srcdir)/'`src/journal/journal-file.c + +src/journal/test_journal-journal-file.obj: src/journal/journal-file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -MT src/journal/test_journal-journal-file.obj -MD -MP -MF src/journal/$(DEPDIR)/test_journal-journal-file.Tpo -c -o src/journal/test_journal-journal-file.obj `if test -f 'src/journal/journal-file.c'; then $(CYGPATH_W) 'src/journal/journal-file.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/journal-file.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/test_journal-journal-file.Tpo src/journal/$(DEPDIR)/test_journal-journal-file.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journal-file.c' object='src/journal/test_journal-journal-file.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -c -o src/journal/test_journal-journal-file.obj `if test -f 'src/journal/journal-file.c'; then $(CYGPATH_W) 'src/journal/journal-file.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/journal-file.c'; fi` + +src/journal/test_journal-lookup3.o: src/journal/lookup3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -MT src/journal/test_journal-lookup3.o -MD -MP -MF src/journal/$(DEPDIR)/test_journal-lookup3.Tpo -c -o src/journal/test_journal-lookup3.o `test -f 'src/journal/lookup3.c' || echo '$(srcdir)/'`src/journal/lookup3.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/test_journal-lookup3.Tpo src/journal/$(DEPDIR)/test_journal-lookup3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/lookup3.c' object='src/journal/test_journal-lookup3.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -c -o src/journal/test_journal-lookup3.o `test -f 'src/journal/lookup3.c' || echo '$(srcdir)/'`src/journal/lookup3.c + +src/journal/test_journal-lookup3.obj: src/journal/lookup3.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -MT src/journal/test_journal-lookup3.obj -MD -MP -MF src/journal/$(DEPDIR)/test_journal-lookup3.Tpo -c -o src/journal/test_journal-lookup3.obj `if test -f 'src/journal/lookup3.c'; then $(CYGPATH_W) 'src/journal/lookup3.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/lookup3.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/test_journal-lookup3.Tpo src/journal/$(DEPDIR)/test_journal-lookup3.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/lookup3.c' object='src/journal/test_journal-lookup3.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -c -o src/journal/test_journal-lookup3.obj `if test -f 'src/journal/lookup3.c'; then $(CYGPATH_W) 'src/journal/lookup3.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/lookup3.c'; fi` + +src/journal/test_journal-journal-send.o: src/journal/journal-send.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -MT src/journal/test_journal-journal-send.o -MD -MP -MF src/journal/$(DEPDIR)/test_journal-journal-send.Tpo -c -o src/journal/test_journal-journal-send.o `test -f 'src/journal/journal-send.c' || echo '$(srcdir)/'`src/journal/journal-send.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/test_journal-journal-send.Tpo src/journal/$(DEPDIR)/test_journal-journal-send.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journal-send.c' object='src/journal/test_journal-journal-send.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -c -o src/journal/test_journal-journal-send.o `test -f 'src/journal/journal-send.c' || echo '$(srcdir)/'`src/journal/journal-send.c + +src/journal/test_journal-journal-send.obj: src/journal/journal-send.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -MT src/journal/test_journal-journal-send.obj -MD -MP -MF src/journal/$(DEPDIR)/test_journal-journal-send.Tpo -c -o src/journal/test_journal-journal-send.obj `if test -f 'src/journal/journal-send.c'; then $(CYGPATH_W) 'src/journal/journal-send.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/journal-send.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/test_journal-journal-send.Tpo src/journal/$(DEPDIR)/test_journal-journal-send.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/journal-send.c' object='src/journal/test_journal-journal-send.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -c -o src/journal/test_journal-journal-send.obj `if test -f 'src/journal/journal-send.c'; then $(CYGPATH_W) 'src/journal/journal-send.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/journal-send.c'; fi` + +src/test_journal-sd-id128.o: src/sd-id128.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -MT src/test_journal-sd-id128.o -MD -MP -MF src/$(DEPDIR)/test_journal-sd-id128.Tpo -c -o src/test_journal-sd-id128.o `test -f 'src/sd-id128.c' || echo '$(srcdir)/'`src/sd-id128.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_journal-sd-id128.Tpo src/$(DEPDIR)/test_journal-sd-id128.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sd-id128.c' object='src/test_journal-sd-id128.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -c -o src/test_journal-sd-id128.o `test -f 'src/sd-id128.c' || echo '$(srcdir)/'`src/sd-id128.c + +src/test_journal-sd-id128.obj: src/sd-id128.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -MT src/test_journal-sd-id128.obj -MD -MP -MF src/$(DEPDIR)/test_journal-sd-id128.Tpo -c -o src/test_journal-sd-id128.obj `if test -f 'src/sd-id128.c'; then $(CYGPATH_W) 'src/sd-id128.c'; else $(CYGPATH_W) '$(srcdir)/src/sd-id128.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_journal-sd-id128.Tpo src/$(DEPDIR)/test_journal-sd-id128.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sd-id128.c' object='src/test_journal-sd-id128.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -c -o src/test_journal-sd-id128.obj `if test -f 'src/sd-id128.c'; then $(CYGPATH_W) 'src/sd-id128.c'; else $(CYGPATH_W) '$(srcdir)/src/sd-id128.c'; fi` + +src/journal/test_journal-compress.o: src/journal/compress.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -MT src/journal/test_journal-compress.o -MD -MP -MF src/journal/$(DEPDIR)/test_journal-compress.Tpo -c -o src/journal/test_journal-compress.o `test -f 'src/journal/compress.c' || echo '$(srcdir)/'`src/journal/compress.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/test_journal-compress.Tpo src/journal/$(DEPDIR)/test_journal-compress.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/compress.c' object='src/journal/test_journal-compress.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -c -o src/journal/test_journal-compress.o `test -f 'src/journal/compress.c' || echo '$(srcdir)/'`src/journal/compress.c + +src/journal/test_journal-compress.obj: src/journal/compress.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -MT src/journal/test_journal-compress.obj -MD -MP -MF src/journal/$(DEPDIR)/test_journal-compress.Tpo -c -o src/journal/test_journal-compress.obj `if test -f 'src/journal/compress.c'; then $(CYGPATH_W) 'src/journal/compress.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/compress.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/journal/$(DEPDIR)/test_journal-compress.Tpo src/journal/$(DEPDIR)/test_journal-compress.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/journal/compress.c' object='src/journal/test_journal-compress.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_journal_CFLAGS) $(CFLAGS) -c -o src/journal/test_journal-compress.obj `if test -f 'src/journal/compress.c'; then $(CYGPATH_W) 'src/journal/compress.c'; else $(CYGPATH_W) '$(srcdir)/src/journal/compress.c'; fi` + +src/test_ns-test-ns.o: src/test-ns.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ns_CFLAGS) $(CFLAGS) -MT src/test_ns-test-ns.o -MD -MP -MF src/$(DEPDIR)/test_ns-test-ns.Tpo -c -o src/test_ns-test-ns.o `test -f 'src/test-ns.c' || echo '$(srcdir)/'`src/test-ns.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_ns-test-ns.Tpo src/$(DEPDIR)/test_ns-test-ns.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/test-ns.c' object='src/test_ns-test-ns.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ns_CFLAGS) $(CFLAGS) -c -o src/test_ns-test-ns.o `test -f 'src/test-ns.c' || echo '$(srcdir)/'`src/test-ns.c + +src/test_ns-test-ns.obj: src/test-ns.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ns_CFLAGS) $(CFLAGS) -MT src/test_ns-test-ns.obj -MD -MP -MF src/$(DEPDIR)/test_ns-test-ns.Tpo -c -o src/test_ns-test-ns.obj `if test -f 'src/test-ns.c'; then $(CYGPATH_W) 'src/test-ns.c'; else $(CYGPATH_W) '$(srcdir)/src/test-ns.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/$(DEPDIR)/test_ns-test-ns.Tpo src/$(DEPDIR)/test_ns-test-ns.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/test-ns.c' object='src/test_ns-test-ns.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ns_CFLAGS) $(CFLAGS) -c -o src/test_ns-test-ns.obj `if test -f 'src/test-ns.c'; then $(CYGPATH_W) 'src/test-ns.c'; else $(CYGPATH_W) '$(srcdir)/src/test-ns.c'; fi` +$(srcdir)/test_loopback_vala.stamp: $(test_loopback_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(test_loopback_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_shutdownd_vala.stamp: $(systemd_shutdownd_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_shutdownd_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/test_journal_vala.stamp: $(test_journal_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(test_journal_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_readahead_replay_vala.stamp: $(systemd_readahead_replay_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_readahead_replay_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_getty_generator_vala.stamp: $(systemd_getty_generator_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_getty_generator_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_coredump_vala.stamp: $(systemd_coredump_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_coredump_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_ask_password_vala.stamp: $(systemd_ask_password_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_ask_password_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_localed_vala.stamp: $(systemd_localed_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_localed_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_nspawn_vala.stamp: $(systemd_nspawn_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_nspawn_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_uaccess_vala.stamp: $(systemd_uaccess_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_uaccess_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_cgroups_agent_vala.stamp: $(systemd_cgroups_agent_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_cgroups_agent_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_shutdown_vala.stamp: $(systemd_shutdown_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_shutdown_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/test_env_replace_vala.stamp: $(test_env_replace_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(test_env_replace_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_user_sessions_vala.stamp: $(systemd_user_sessions_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_user_sessions_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/test_ns_vala.stamp: $(test_ns_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(test_ns_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_readahead_collect_vala.stamp: $(systemd_readahead_collect_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_readahead_collect_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_fsck_vala.stamp: $(systemd_fsck_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_fsck_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_vala.stamp: $(systemd_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/test_strv_vala.stamp: $(test_strv_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(test_strv_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_tty_ask_password_agent_vala.stamp: $(systemd_tty_ask_password_agent_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_tty_ask_password_agent_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_modules_load_vala.stamp: $(systemd_modules_load_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_modules_load_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/test_cgroup_vala.stamp: $(test_cgroup_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(test_cgroup_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_random_seed_vala.stamp: $(systemd_random_seed_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_random_seed_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/test_id128_vala.stamp: $(test_id128_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(test_id128_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_vconsole_setup_vala.stamp: $(systemd_vconsole_setup_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_vconsole_setup_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_binfmt_vala.stamp: $(systemd_binfmt_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_binfmt_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_cryptsetup_vala.stamp: $(systemd_cryptsetup_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_cryptsetup_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_update_utmp_vala.stamp: $(systemd_update_utmp_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_update_utmp_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_reply_password_vala.stamp: $(systemd_reply_password_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_reply_password_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_timedated_vala.stamp: $(systemd_timedated_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_timedated_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_notify_vala.stamp: $(systemd_notify_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_notify_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/src/gnome-ask-password-agent.c: $(srcdir)/systemd_gnome_ask_password_agent_vala.stamp + @if test -f $@; then :; else rm -f $(srcdir)/systemd_gnome_ask_password_agent_vala.stamp; fi + @if test -f $@; then :; else \ + $(MAKE) $(AM_MAKEFLAGS) $(srcdir)/systemd_gnome_ask_password_agent_vala.stamp; \ + fi +$(srcdir)/systemd_gnome_ask_password_agent_vala.stamp: $(systemd_gnome_ask_password_agent_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(systemd_gnome_ask_password_agent_VALAFLAGS) $(VALAFLAGS) -C $(systemd_gnome_ask_password_agent_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_tmpfiles_vala.stamp: $(systemd_tmpfiles_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_tmpfiles_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/test_login_vala.stamp: $(test_login_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(test_login_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_remount_api_vfs_vala.stamp: $(systemd_remount_api_vfs_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_remount_api_vfs_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_hostnamed_vala.stamp: $(systemd_hostnamed_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_hostnamed_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_quotacheck_vala.stamp: $(systemd_quotacheck_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_quotacheck_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_rc_local_generator_vala.stamp: $(systemd_rc_local_generator_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_rc_local_generator_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_ac_power_vala.stamp: $(systemd_ac_power_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_ac_power_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_initctl_vala.stamp: $(systemd_initctl_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_initctl_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/test_engine_vala.stamp: $(test_engine_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(test_engine_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_cat_vala.stamp: $(systemd_cat_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_cat_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_detect_virt_vala.stamp: $(systemd_detect_virt_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_detect_virt_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_cgtop_vala.stamp: $(systemd_cgtop_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_cgtop_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemctl_vala.stamp: $(systemctl_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemctl_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/src/systemadm.c: $(srcdir)/systemadm_vala.stamp + @if test -f $@; then :; else rm -f $(srcdir)/systemadm_vala.stamp; fi + @if test -f $@; then :; else \ + $(MAKE) $(AM_MAKEFLAGS) $(srcdir)/systemadm_vala.stamp; \ + fi +$(srcdir)/src/systemd-interfaces.c: $(srcdir)/systemadm_vala.stamp + @if test -f $@; then :; else rm -f $(srcdir)/systemadm_vala.stamp; fi + @if test -f $@; then :; else \ + $(MAKE) $(AM_MAKEFLAGS) $(srcdir)/systemadm_vala.stamp; \ + fi +$(srcdir)/src/wraplabel.c: $(srcdir)/systemadm_vala.stamp + @if test -f $@; then :; else rm -f $(srcdir)/systemadm_vala.stamp; fi + @if test -f $@; then :; else \ + $(MAKE) $(AM_MAKEFLAGS) $(srcdir)/systemadm_vala.stamp; \ + fi +$(srcdir)/systemadm_vala.stamp: $(systemadm_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(systemadm_VALAFLAGS) $(VALAFLAGS) -C $(systemadm_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_loginctl_vala.stamp: $(systemd_loginctl_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_loginctl_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_machine_id_setup_vala.stamp: $(systemd_machine_id_setup_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_machine_id_setup_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/test_daemon_vala.stamp: $(test_daemon_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(test_daemon_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/test_install_vala.stamp: $(test_install_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(test_install_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_cryptsetup_generator_vala.stamp: $(systemd_cryptsetup_generator_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_cryptsetup_generator_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_timestamp_vala.stamp: $(systemd_timestamp_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_timestamp_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_journalctl_vala.stamp: $(systemd_journalctl_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_journalctl_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_multi_seat_x_vala.stamp: $(systemd_multi_seat_x_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_multi_seat_x_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_stdio_bridge_vala.stamp: $(systemd_stdio_bridge_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_stdio_bridge_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_sysctl_vala.stamp: $(systemd_sysctl_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_sysctl_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_logind_vala.stamp: $(systemd_logind_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_logind_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/test_job_type_vala.stamp: $(test_job_type_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(test_job_type_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/test_hostname_vala.stamp: $(test_hostname_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(test_hostname_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_journald_vala.stamp: $(systemd_journald_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_journald_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/systemd_cgls_vala.stamp: $(systemd_cgls_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(systemd_cgls_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/libsystemd_journal_la_vala.stamp: $(libsystemd_journal_la_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(libsystemd_journal_la_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/libsystemd_daemon_la_vala.stamp: $(libsystemd_daemon_la_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(libsystemd_daemon_la_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/libsystemd_core_la_vala.stamp: $(libsystemd_core_la_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(libsystemd_core_la_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/libsystemd_basic_la_vala.stamp: $(libsystemd_basic_la_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(libsystemd_basic_la_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/pam_systemd_la_vala.stamp: $(pam_systemd_la_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(pam_systemd_la_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/libsystemd_id128_la_vala.stamp: $(libsystemd_id128_la_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(libsystemd_id128_la_SOURCES) + $(AM_V_at)mv -f $@-t $@ +$(srcdir)/libsystemd_login_la_vala.stamp: $(libsystemd_login_la_SOURCES) + $(AM_V_at)rm -f $@ && echo stamp > $@-t + $(AM_V_VALAC)$(am__cd) $(srcdir) && $(VALAC) $(AM_VALAFLAGS) $(VALAFLAGS) -C $(libsystemd_login_la_SOURCES) + $(AM_V_at)mv -f $@-t $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf src/.libs src/_libs + -rm -rf src/journal/.libs src/journal/_libs + -rm -rf src/login/.libs src/login/_libs + +distclean-libtool: + -rm -f libtool config.lt +install-man1: $(dist_man_MANS) $(nodist_man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" + @list=''; test -n "$(man1dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS) $(nodist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS) $(nodist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +install-man3: $(dist_man_MANS) $(nodist_man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)" + @list=''; test -n "$(man3dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS) $(nodist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.3[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ + done; } + +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man3dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS) $(nodist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.3[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) +install-man5: $(dist_man_MANS) $(nodist_man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)" + @list=''; test -n "$(man5dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS) $(nodist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.5[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \ + done; } + +uninstall-man5: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man5dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS) $(nodist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.5[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) +install-man7: $(dist_man_MANS) $(nodist_man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man7dir)" || $(MKDIR_P) "$(DESTDIR)$(man7dir)" + @list=''; test -n "$(man7dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS) $(nodist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.7[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^7][0-9a-z]*$$,7,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man7dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man7dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man7dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man7dir)" || exit $$?; }; \ + done; } + +uninstall-man7: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man7dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS) $(nodist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.7[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^7][0-9a-z]*$$,7,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man7dir)'; $(am__uninstall_files_from_dir) +install-man8: $(dist_man_MANS) $(nodist_man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" + @list=''; test -n "$(man8dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS) $(nodist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } + +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS) $(nodist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) +install-dbusinterfaceDATA: $(dbusinterface_DATA) + @$(NORMAL_INSTALL) + test -z "$(dbusinterfacedir)" || $(MKDIR_P) "$(DESTDIR)$(dbusinterfacedir)" + @list='$(dbusinterface_DATA)'; test -n "$(dbusinterfacedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dbusinterfacedir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(dbusinterfacedir)" || exit $$?; \ + done + +uninstall-dbusinterfaceDATA: + @$(NORMAL_UNINSTALL) + @list='$(dbusinterface_DATA)'; test -n "$(dbusinterfacedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(dbusinterfacedir)'; $(am__uninstall_files_from_dir) +install-dist_bashcompletionDATA: $(dist_bashcompletion_DATA) + @$(NORMAL_INSTALL) + test -z "$(bashcompletiondir)" || $(MKDIR_P) "$(DESTDIR)$(bashcompletiondir)" + @list='$(dist_bashcompletion_DATA)'; test -n "$(bashcompletiondir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(bashcompletiondir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(bashcompletiondir)" || exit $$?; \ + done + +uninstall-dist_bashcompletionDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_bashcompletion_DATA)'; test -n "$(bashcompletiondir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(bashcompletiondir)'; $(am__uninstall_files_from_dir) +install-dist_dbuspolicyDATA: $(dist_dbuspolicy_DATA) + @$(NORMAL_INSTALL) + test -z "$(dbuspolicydir)" || $(MKDIR_P) "$(DESTDIR)$(dbuspolicydir)" + @list='$(dist_dbuspolicy_DATA)'; test -n "$(dbuspolicydir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dbuspolicydir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(dbuspolicydir)" || exit $$?; \ + done + +uninstall-dist_dbuspolicyDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_dbuspolicy_DATA)'; test -n "$(dbuspolicydir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(dbuspolicydir)'; $(am__uninstall_files_from_dir) +install-dist_dbussystemserviceDATA: $(dist_dbussystemservice_DATA) + @$(NORMAL_INSTALL) + test -z "$(dbussystemservicedir)" || $(MKDIR_P) "$(DESTDIR)$(dbussystemservicedir)" + @list='$(dist_dbussystemservice_DATA)'; test -n "$(dbussystemservicedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dbussystemservicedir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(dbussystemservicedir)" || exit $$?; \ + done + +uninstall-dist_dbussystemserviceDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_dbussystemservice_DATA)'; test -n "$(dbussystemservicedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(dbussystemservicedir)'; $(am__uninstall_files_from_dir) +install-dist_docDATA: $(dist_doc_DATA) + @$(NORMAL_INSTALL) + test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)" + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ + done + +uninstall-dist_docDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) +install-dist_pkgdataDATA: $(dist_pkgdata_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" + @list='$(dist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ + done + +uninstall-dist_pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgdatadir)'; $(am__uninstall_files_from_dir) +install-dist_pkgsysconfDATA: $(dist_pkgsysconf_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgsysconfdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgsysconfdir)" + @list='$(dist_pkgsysconf_DATA)'; test -n "$(pkgsysconfdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgsysconfdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgsysconfdir)" || exit $$?; \ + done + +uninstall-dist_pkgsysconfDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_pkgsysconf_DATA)'; test -n "$(pkgsysconfdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgsysconfdir)'; $(am__uninstall_files_from_dir) +install-dist_systemunitDATA: $(dist_systemunit_DATA) + @$(NORMAL_INSTALL) + test -z "$(systemunitdir)" || $(MKDIR_P) "$(DESTDIR)$(systemunitdir)" + @list='$(dist_systemunit_DATA)'; test -n "$(systemunitdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(systemunitdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(systemunitdir)" || exit $$?; \ + done + +uninstall-dist_systemunitDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_systemunit_DATA)'; test -n "$(systemunitdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(systemunitdir)'; $(am__uninstall_files_from_dir) +install-dist_tmpfilesDATA: $(dist_tmpfiles_DATA) + @$(NORMAL_INSTALL) + test -z "$(tmpfilesdir)" || $(MKDIR_P) "$(DESTDIR)$(tmpfilesdir)" + @list='$(dist_tmpfiles_DATA)'; test -n "$(tmpfilesdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(tmpfilesdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(tmpfilesdir)" || exit $$?; \ + done + +uninstall-dist_tmpfilesDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_tmpfiles_DATA)'; test -n "$(tmpfilesdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(tmpfilesdir)'; $(am__uninstall_files_from_dir) +install-dist_udevrulesDATA: $(dist_udevrules_DATA) + @$(NORMAL_INSTALL) + test -z "$(udevrulesdir)" || $(MKDIR_P) "$(DESTDIR)$(udevrulesdir)" + @list='$(dist_udevrules_DATA)'; test -n "$(udevrulesdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(udevrulesdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(udevrulesdir)" || exit $$?; \ + done + +uninstall-dist_udevrulesDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_udevrules_DATA)'; test -n "$(udevrulesdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(udevrulesdir)'; $(am__uninstall_files_from_dir) +install-dist_userunitDATA: $(dist_userunit_DATA) + @$(NORMAL_INSTALL) + test -z "$(userunitdir)" || $(MKDIR_P) "$(DESTDIR)$(userunitdir)" + @list='$(dist_userunit_DATA)'; test -n "$(userunitdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(userunitdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(userunitdir)" || exit $$?; \ + done + +uninstall-dist_userunitDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_userunit_DATA)'; test -n "$(userunitdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(userunitdir)'; $(am__uninstall_files_from_dir) +install-nodist_polkitpolicyDATA: $(nodist_polkitpolicy_DATA) + @$(NORMAL_INSTALL) + test -z "$(polkitpolicydir)" || $(MKDIR_P) "$(DESTDIR)$(polkitpolicydir)" + @list='$(nodist_polkitpolicy_DATA)'; test -n "$(polkitpolicydir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(polkitpolicydir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(polkitpolicydir)" || exit $$?; \ + done + +uninstall-nodist_polkitpolicyDATA: + @$(NORMAL_UNINSTALL) + @list='$(nodist_polkitpolicy_DATA)'; test -n "$(polkitpolicydir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(polkitpolicydir)'; $(am__uninstall_files_from_dir) +install-nodist_systemunitDATA: $(nodist_systemunit_DATA) + @$(NORMAL_INSTALL) + test -z "$(systemunitdir)" || $(MKDIR_P) "$(DESTDIR)$(systemunitdir)" + @list='$(nodist_systemunit_DATA)'; test -n "$(systemunitdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(systemunitdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(systemunitdir)" || exit $$?; \ + done + +uninstall-nodist_systemunitDATA: + @$(NORMAL_UNINSTALL) + @list='$(nodist_systemunit_DATA)'; test -n "$(systemunitdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(systemunitdir)'; $(am__uninstall_files_from_dir) +install-nodist_udevrulesDATA: $(nodist_udevrules_DATA) + @$(NORMAL_INSTALL) + test -z "$(udevrulesdir)" || $(MKDIR_P) "$(DESTDIR)$(udevrulesdir)" + @list='$(nodist_udevrules_DATA)'; test -n "$(udevrulesdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(udevrulesdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(udevrulesdir)" || exit $$?; \ + done + +uninstall-nodist_udevrulesDATA: + @$(NORMAL_UNINSTALL) + @list='$(nodist_udevrules_DATA)'; test -n "$(udevrulesdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(udevrulesdir)'; $(am__uninstall_files_from_dir) +install-nodist_userunitDATA: $(nodist_userunit_DATA) + @$(NORMAL_INSTALL) + test -z "$(userunitdir)" || $(MKDIR_P) "$(DESTDIR)$(userunitdir)" + @list='$(nodist_userunit_DATA)'; test -n "$(userunitdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(userunitdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(userunitdir)" || exit $$?; \ + done + +uninstall-nodist_userunitDATA: + @$(NORMAL_UNINSTALL) + @list='$(nodist_userunit_DATA)'; test -n "$(userunitdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(userunitdir)'; $(am__uninstall_files_from_dir) +install-pkgconfigdataDATA: $(pkgconfigdata_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgconfigdatadir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdatadir)" + @list='$(pkgconfigdata_DATA)'; test -n "$(pkgconfigdatadir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdatadir)" || exit $$?; \ + done + +uninstall-pkgconfigdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfigdata_DATA)'; test -n "$(pkgconfigdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdatadir)'; $(am__uninstall_files_from_dir) +install-pkgconfiglibDATA: $(pkgconfiglib_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgconfiglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfiglibdir)" + @list='$(pkgconfiglib_DATA)'; test -n "$(pkgconfiglibdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfiglibdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfiglibdir)" || exit $$?; \ + done + +uninstall-pkgconfiglibDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfiglib_DATA)'; test -n "$(pkgconfiglibdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfiglibdir)'; $(am__uninstall_files_from_dir) +install-sysctlDATA: $(sysctl_DATA) + @$(NORMAL_INSTALL) + test -z "$(sysctldir)" || $(MKDIR_P) "$(DESTDIR)$(sysctldir)" + @list='$(sysctl_DATA)'; test -n "$(sysctldir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sysctldir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(sysctldir)" || exit $$?; \ + done + +uninstall-sysctlDATA: + @$(NORMAL_UNINSTALL) + @list='$(sysctl_DATA)'; test -n "$(sysctldir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(sysctldir)'; $(am__uninstall_files_from_dir) +install-pkgincludeHEADERS: $(pkginclude_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ + done + +uninstall-pkgincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @case `sed 15q $(srcdir)/NEWS` in \ + *"$(VERSION)"*) : ;; \ + *) \ + echo "NEWS not updated; not releasing" 1>&2; \ + exit 1;; \ + esac + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically \`make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) \ + $(HEADERS) config.h +install-binPROGRAMS: install-libLTLIBRARIES + +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pamlibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(rootbindir)" "$(DESTDIR)$(rootlibexecdir)" "$(DESTDIR)$(systemgeneratordir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man7dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(dbusinterfacedir)" "$(DESTDIR)$(bashcompletiondir)" "$(DESTDIR)$(dbuspolicydir)" "$(DESTDIR)$(dbussystemservicedir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgsysconfdir)" "$(DESTDIR)$(systemunitdir)" "$(DESTDIR)$(tmpfilesdir)" "$(DESTDIR)$(udevrulesdir)" "$(DESTDIR)$(userunitdir)" "$(DESTDIR)$(polkitpolicydir)" "$(DESTDIR)$(systemunitdir)" "$(DESTDIR)$(udevrulesdir)" "$(DESTDIR)$(userunitdir)" "$(DESTDIR)$(pkgconfigdatadir)" "$(DESTDIR)$(pkgconfiglibdir)" "$(DESTDIR)$(sysctldir)" "$(DESTDIR)$(pkgincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f src/$(DEPDIR)/$(am__dirstamp) + -rm -f src/$(am__dirstamp) + -rm -f src/binfmt/$(DEPDIR)/$(am__dirstamp) + -rm -f src/binfmt/$(am__dirstamp) + -rm -f src/cryptsetup/$(DEPDIR)/$(am__dirstamp) + -rm -f src/cryptsetup/$(am__dirstamp) + -rm -f src/hostname/$(DEPDIR)/$(am__dirstamp) + -rm -f src/hostname/$(am__dirstamp) + -rm -f src/journal/$(DEPDIR)/$(am__dirstamp) + -rm -f src/journal/$(am__dirstamp) + -rm -f src/locale/$(DEPDIR)/$(am__dirstamp) + -rm -f src/locale/$(am__dirstamp) + -rm -f src/login/$(DEPDIR)/$(am__dirstamp) + -rm -f src/login/$(am__dirstamp) + -rm -f src/readahead/$(DEPDIR)/$(am__dirstamp) + -rm -f src/readahead/$(am__dirstamp) + -rm -f src/timedate/$(DEPDIR)/$(am__dirstamp) + -rm -f src/timedate/$(am__dirstamp) + -rm -f src/vconsole/$(DEPDIR)/$(am__dirstamp) + -rm -f src/vconsole/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -rm -f libsystemd_basic_la_vala.stamp + -rm -f libsystemd_core_la_vala.stamp + -rm -f libsystemd_daemon_la_vala.stamp + -rm -f libsystemd_id128_la_vala.stamp + -rm -f libsystemd_journal_la_vala.stamp + -rm -f libsystemd_login_la_vala.stamp + -rm -f pam_systemd_la_vala.stamp + -rm -f src/gnome-ask-password-agent.c + -rm -f src/systemadm.c + -rm -f src/systemd-interfaces.c + -rm -f src/wraplabel.c + -rm -f systemadm_vala.stamp + -rm -f systemctl_vala.stamp + -rm -f systemd_ac_power_vala.stamp + -rm -f systemd_ask_password_vala.stamp + -rm -f systemd_binfmt_vala.stamp + -rm -f systemd_cat_vala.stamp + -rm -f systemd_cgls_vala.stamp + -rm -f systemd_cgroups_agent_vala.stamp + -rm -f systemd_cgtop_vala.stamp + -rm -f systemd_coredump_vala.stamp + -rm -f systemd_cryptsetup_generator_vala.stamp + -rm -f systemd_cryptsetup_vala.stamp + -rm -f systemd_detect_virt_vala.stamp + -rm -f systemd_fsck_vala.stamp + -rm -f systemd_getty_generator_vala.stamp + -rm -f systemd_gnome_ask_password_agent_vala.stamp + -rm -f systemd_hostnamed_vala.stamp + -rm -f systemd_initctl_vala.stamp + -rm -f systemd_journalctl_vala.stamp + -rm -f systemd_journald_vala.stamp + -rm -f systemd_localed_vala.stamp + -rm -f systemd_loginctl_vala.stamp + -rm -f systemd_logind_vala.stamp + -rm -f systemd_machine_id_setup_vala.stamp + -rm -f systemd_modules_load_vala.stamp + -rm -f systemd_multi_seat_x_vala.stamp + -rm -f systemd_notify_vala.stamp + -rm -f systemd_nspawn_vala.stamp + -rm -f systemd_quotacheck_vala.stamp + -rm -f systemd_random_seed_vala.stamp + -rm -f systemd_rc_local_generator_vala.stamp + -rm -f systemd_readahead_collect_vala.stamp + -rm -f systemd_readahead_replay_vala.stamp + -rm -f systemd_remount_api_vfs_vala.stamp + -rm -f systemd_reply_password_vala.stamp + -rm -f systemd_shutdown_vala.stamp + -rm -f systemd_shutdownd_vala.stamp + -rm -f systemd_stdio_bridge_vala.stamp + -rm -f systemd_sysctl_vala.stamp + -rm -f systemd_timedated_vala.stamp + -rm -f systemd_timestamp_vala.stamp + -rm -f systemd_tmpfiles_vala.stamp + -rm -f systemd_tty_ask_password_agent_vala.stamp + -rm -f systemd_uaccess_vala.stamp + -rm -f systemd_update_utmp_vala.stamp + -rm -f systemd_user_sessions_vala.stamp + -rm -f systemd_vala.stamp + -rm -f systemd_vconsole_setup_vala.stamp + -rm -f test_cgroup_vala.stamp + -rm -f test_daemon_vala.stamp + -rm -f test_engine_vala.stamp + -rm -f test_env_replace_vala.stamp + -rm -f test_hostname_vala.stamp + -rm -f test_id128_vala.stamp + -rm -f test_install_vala.stamp + -rm -f test_job_type_vala.stamp + -rm -f test_journal_vala.stamp + -rm -f test_login_vala.stamp + -rm -f test_loopback_vala.stamp + -rm -f test_ns_vala.stamp + -rm -f test_strv_vala.stamp +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ + clean-pamlibLTLIBRARIES clean-rootbinPROGRAMS \ + clean-rootlibexecPROGRAMS clean-systemgeneratorPROGRAMS \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf src/$(DEPDIR) src/binfmt/$(DEPDIR) src/cryptsetup/$(DEPDIR) src/hostname/$(DEPDIR) src/journal/$(DEPDIR) src/locale/$(DEPDIR) src/login/$(DEPDIR) src/readahead/$(DEPDIR) src/timedate/$(DEPDIR) src/vconsole/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-dbusinterfaceDATA \ + install-dist_bashcompletionDATA install-dist_dbuspolicyDATA \ + install-dist_dbussystemserviceDATA install-dist_docDATA \ + install-dist_pkgdataDATA install-dist_pkgsysconfDATA \ + install-dist_systemunitDATA install-dist_tmpfilesDATA \ + install-dist_udevrulesDATA install-dist_userunitDATA \ + install-man install-nodist_polkitpolicyDATA \ + install-nodist_systemunitDATA install-nodist_udevrulesDATA \ + install-nodist_userunitDATA install-pamlibLTLIBRARIES \ + install-pkgconfigdataDATA install-pkgconfiglibDATA \ + install-pkgincludeHEADERS install-rootbinPROGRAMS \ + install-sysctlDATA install-systemgeneratorPROGRAMS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-dist_binSCRIPTS \ + install-libLTLIBRARIES install-rootlibexecPROGRAMS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: install-man1 install-man3 install-man5 install-man7 \ + install-man8 + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf src/$(DEPDIR) src/binfmt/$(DEPDIR) src/cryptsetup/$(DEPDIR) src/hostname/$(DEPDIR) src/journal/$(DEPDIR) src/locale/$(DEPDIR) src/login/$(DEPDIR) src/readahead/$(DEPDIR) src/timedate/$(DEPDIR) src/vconsole/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-dbusinterfaceDATA \ + uninstall-dist_bashcompletionDATA uninstall-dist_binSCRIPTS \ + uninstall-dist_dbuspolicyDATA \ + uninstall-dist_dbussystemserviceDATA uninstall-dist_docDATA \ + uninstall-dist_pkgdataDATA uninstall-dist_pkgsysconfDATA \ + uninstall-dist_systemunitDATA uninstall-dist_tmpfilesDATA \ + uninstall-dist_udevrulesDATA uninstall-dist_userunitDATA \ + uninstall-libLTLIBRARIES uninstall-man \ + uninstall-nodist_polkitpolicyDATA \ + uninstall-nodist_systemunitDATA uninstall-nodist_udevrulesDATA \ + uninstall-nodist_userunitDATA uninstall-pamlibLTLIBRARIES \ + uninstall-pkgconfigdataDATA uninstall-pkgconfiglibDATA \ + uninstall-pkgincludeHEADERS uninstall-rootbinPROGRAMS \ + uninstall-rootlibexecPROGRAMS uninstall-sysctlDATA \ + uninstall-systemgeneratorPROGRAMS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook +uninstall-man: uninstall-man1 uninstall-man3 uninstall-man5 \ + uninstall-man7 uninstall-man8 + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ + ctags-recursive install-am install-data-am install-exec-am \ + install-strip tags-recursive uninstall-am + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-binPROGRAMS \ + clean-generic clean-libLTLIBRARIES clean-libtool \ + clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ + clean-pamlibLTLIBRARIES clean-rootbinPROGRAMS \ + clean-rootlibexecPROGRAMS clean-systemgeneratorPROGRAMS ctags \ + ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-lzip \ + dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \ + distclean distclean-compile distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-binPROGRAMS install-data \ + install-data-am install-data-hook install-dbusinterfaceDATA \ + install-dist_bashcompletionDATA install-dist_binSCRIPTS \ + install-dist_dbuspolicyDATA install-dist_dbussystemserviceDATA \ + install-dist_docDATA install-dist_pkgdataDATA \ + install-dist_pkgsysconfDATA install-dist_systemunitDATA \ + install-dist_tmpfilesDATA install-dist_udevrulesDATA \ + install-dist_userunitDATA install-dvi install-dvi-am \ + install-exec install-exec-am install-exec-hook install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-man1 install-man3 \ + install-man5 install-man7 install-man8 \ + install-nodist_polkitpolicyDATA install-nodist_systemunitDATA \ + install-nodist_udevrulesDATA install-nodist_userunitDATA \ + install-pamlibLTLIBRARIES install-pdf install-pdf-am \ + install-pkgconfigdataDATA install-pkgconfiglibDATA \ + install-pkgincludeHEADERS install-ps install-ps-am \ + install-rootbinPROGRAMS install-rootlibexecPROGRAMS \ + install-strip install-sysctlDATA \ + install-systemgeneratorPROGRAMS installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-dbusinterfaceDATA \ + uninstall-dist_bashcompletionDATA uninstall-dist_binSCRIPTS \ + uninstall-dist_dbuspolicyDATA \ + uninstall-dist_dbussystemserviceDATA uninstall-dist_docDATA \ + uninstall-dist_pkgdataDATA uninstall-dist_pkgsysconfDATA \ + uninstall-dist_systemunitDATA uninstall-dist_tmpfilesDATA \ + uninstall-dist_udevrulesDATA uninstall-dist_userunitDATA \ + uninstall-hook uninstall-libLTLIBRARIES uninstall-man \ + uninstall-man1 uninstall-man3 uninstall-man5 uninstall-man7 \ + uninstall-man8 uninstall-nodist_polkitpolicyDATA \ + uninstall-nodist_systemunitDATA uninstall-nodist_udevrulesDATA \ + uninstall-nodist_userunitDATA uninstall-pamlibLTLIBRARIES \ + uninstall-pkgconfigdataDATA uninstall-pkgconfiglibDATA \ + uninstall-pkgincludeHEADERS uninstall-rootbinPROGRAMS \ + uninstall-rootlibexecPROGRAMS uninstall-sysctlDATA \ + uninstall-systemgeneratorPROGRAMS + + +@INTLTOOL_POLICY_RULE@ + +man/reboot.8: man/halt.8 +man/poweroff.8: man/halt.8 +man/init.1: man/systemd.1 + +# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed +libsystemd-daemon-install-hook: + if test "$(libdir)" != "$(rootlibdir)"; then \ + mkdir -p $(DESTDIR)$(rootlibdir) && \ + so_img_name=$$(readlink $(DESTDIR)$(libdir)/libsystemd-daemon.so) && \ + so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \ + ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libsystemd-daemon.so && \ + mv $(DESTDIR)$(libdir)/libsystemd-daemon.so.* $(DESTDIR)$(rootlibdir); \ + fi + +libsystemd-daemon-uninstall-hook: + rm -f $(DESTDIR)$(rootlibdir)/libsystemd-daemon.so* + +man/sd_is_socket.3: man/sd_is_fifo.3 +man/sd_is_socket_unix.3: man/sd_is_fifo.3 +man/sd_is_socket_inet.3: man/sd_is_fifo.3 +man/sd_is_mq.3: man/sd_is_fifo.3 +man/sd_notifyf.3: man/sd_notify.3 + +# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed +libsystemd-id128-install-hook: + if test "$(libdir)" != "$(rootlibdir)"; then \ + mkdir -p $(DESTDIR)$(rootlibdir) && \ + so_img_name=$$(readlink $(DESTDIR)$(libdir)/libsystemd-id128.so) && \ + so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \ + ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libsystemd-id128.so && \ + mv $(DESTDIR)$(libdir)/libsystemd-id128.so.* $(DESTDIR)$(rootlibdir); \ + fi + +libsystemd-id128-uninstall-hook: + rm -f $(DESTDIR)$(rootlibdir)/libsystemd-id128.so* + +# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed +libsystemd-journal-install-hook: + if test "$(libdir)" != "$(rootlibdir)"; then \ + mkdir -p $(DESTDIR)$(rootlibdir) && \ + so_img_name=$$(readlink $(DESTDIR)$(libdir)/libsystemd-journal.so) && \ + so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \ + ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libsystemd-journal.so && \ + mv $(DESTDIR)$(libdir)/libsystemd-journal.so.* $(DESTDIR)$(rootlibdir); \ + fi + +libsystemd-journal-uninstall-hook: + rm -f $(DESTDIR)$(rootlibdir)/libsystemd-journal.so* + +journal-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(systemunitdir)/sockets.target.wants \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants + ( cd $(DESTDIR)$(systemunitdir)/sockets.target.wants && \ + rm -f systemd-journald.socket && \ + $(LN_S) ../systemd-journald.socket ) + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f systemd-journald.service && \ + $(LN_S) ../systemd-journald.service ) + +@ENABLE_BINFMT_TRUE@binfmt-install-data-hook: +@ENABLE_BINFMT_TRUE@ $(MKDIR_P) -m 0755 \ +@ENABLE_BINFMT_TRUE@ $(DESTDIR)$(prefix)/lib/binfmt.d \ +@ENABLE_BINFMT_TRUE@ $(DESTDIR)$(sysconfdir)/binfmt.d \ +@ENABLE_BINFMT_TRUE@ $(DESTDIR)$(systemunitdir)/sysinit.target.wants +@ENABLE_BINFMT_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ +@ENABLE_BINFMT_TRUE@ rm -f systemd-binfmt.service \ +@ENABLE_BINFMT_TRUE@ proc-sys-fs-binfmt_misc.automount && \ +@ENABLE_BINFMT_TRUE@ $(LN_S) ../systemd-binfmt.service systemd-binfmt.service && \ +@ENABLE_BINFMT_TRUE@ $(LN_S) ../proc-sys-fs-binfmt_misc.automount proc-sys-fs-binfmt_misc.automount ) + +@ENABLE_VCONSOLE_TRUE@vconsole-install-data-hook: +@ENABLE_VCONSOLE_TRUE@ $(MKDIR_P) -m 0755 \ +@ENABLE_VCONSOLE_TRUE@ $(DESTDIR)$(systemunitdir)/sysinit.target.wants +@ENABLE_VCONSOLE_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ +@ENABLE_VCONSOLE_TRUE@ rm -f systemd-vconsole-setup.service && \ +@ENABLE_VCONSOLE_TRUE@ $(LN_S) ../systemd-vconsole-setup.service systemd-vconsole-setup.service ) + +@ENABLE_RANDOMSEED_TRUE@randomseed-install-data-hook: +@ENABLE_RANDOMSEED_TRUE@ $(MKDIR_P) -m 0755 \ +@ENABLE_RANDOMSEED_TRUE@ $(DESTDIR)$(systemunitdir)/shutdown.target.wants \ +@ENABLE_RANDOMSEED_TRUE@ $(DESTDIR)$(systemunitdir)/sysinit.target.wants +@ENABLE_RANDOMSEED_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/shutdown.target.wants && \ +@ENABLE_RANDOMSEED_TRUE@ rm -f systemd-random-seed-save.service && \ +@ENABLE_RANDOMSEED_TRUE@ $(LN_S) ../systemd-random-seed-save.service systemd-random-seed-save.service ) +@ENABLE_RANDOMSEED_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ +@ENABLE_RANDOMSEED_TRUE@ rm -f systemd-random-seed-load.service && \ +@ENABLE_RANDOMSEED_TRUE@ $(LN_S) ../systemd-random-seed-load.service systemd-random-seed-load.service ) + +@HAVE_LIBCRYPTSETUP_TRUE@cryptsetup-install-data-hook: +@HAVE_LIBCRYPTSETUP_TRUE@ $(MKDIR_P) -m 0755 \ +@HAVE_LIBCRYPTSETUP_TRUE@ $(DESTDIR)$(systemunitdir)/sysinit.target.wants +@HAVE_LIBCRYPTSETUP_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ +@HAVE_LIBCRYPTSETUP_TRUE@ rm -f cryptsetup.target && \ +@HAVE_LIBCRYPTSETUP_TRUE@ $(LN_S) ../cryptsetup.target cryptsetup.target ) + +@ENABLE_HOSTNAMED_TRUE@org.freedesktop.hostname1.xml: systemd-hostnamed +@ENABLE_HOSTNAMED_TRUE@ $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.hostname1 $< $@.tmp && \ +@ENABLE_HOSTNAMED_TRUE@ $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \ +@ENABLE_HOSTNAMED_TRUE@ $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp + +@ENABLE_HOSTNAMED_TRUE@hostnamed-install-data-hook: +@ENABLE_HOSTNAMED_TRUE@ ( cd $(DESTDIR)$(systemunitdir) && \ +@ENABLE_HOSTNAMED_TRUE@ rm -f dbus-org.freedesktop.hostname1.service && \ +@ENABLE_HOSTNAMED_TRUE@ $(LN_S) systemd-hostnamed.service dbus-org.freedesktop.hostname1.service ) + +@ENABLE_LOCALED_TRUE@org.freedesktop.locale1.xml: systemd-localed +@ENABLE_LOCALED_TRUE@ $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.locale1 $< $@.tmp && \ +@ENABLE_LOCALED_TRUE@ $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \ +@ENABLE_LOCALED_TRUE@ $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp + +@ENABLE_LOCALED_TRUE@localed-install-data-hook: +@ENABLE_LOCALED_TRUE@ ( cd $(DESTDIR)$(systemunitdir) && \ +@ENABLE_LOCALED_TRUE@ rm -f dbus-org.freedesktop.locale1.service && \ +@ENABLE_LOCALED_TRUE@ $(LN_S) systemd-localed.service dbus-org.freedesktop.locale1.service ) + +@ENABLE_LOCALED_TRUE@update-kbd-model-map: +@ENABLE_LOCALED_TRUE@ src/locale/generate-kbd-model-map > src/locale/kbd-model-map + +@ENABLE_TIMEDATED_TRUE@org.freedesktop.timedate1.xml: systemd-timedated +@ENABLE_TIMEDATED_TRUE@ $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.timedate1 $< $@.tmp && \ +@ENABLE_TIMEDATED_TRUE@ $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \ +@ENABLE_TIMEDATED_TRUE@ $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp + +@ENABLE_TIMEDATED_TRUE@timedated-install-data-hook: +@ENABLE_TIMEDATED_TRUE@ ( cd $(DESTDIR)$(systemunitdir) && \ +@ENABLE_TIMEDATED_TRUE@ rm -f dbus-org.freedesktop.timedate1.service && \ +@ENABLE_TIMEDATED_TRUE@ $(LN_S) systemd-timedated.service dbus-org.freedesktop.timedate1.service ) + +# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed +@ENABLE_LOGIND_TRUE@libsystemd-login-install-hook: +@ENABLE_LOGIND_TRUE@ if test "$(libdir)" != "$(rootlibdir)"; then \ +@ENABLE_LOGIND_TRUE@ mkdir -p $(DESTDIR)$(rootlibdir) && \ +@ENABLE_LOGIND_TRUE@ so_img_name=$$(readlink $(DESTDIR)$(libdir)/libsystemd-login.so) && \ +@ENABLE_LOGIND_TRUE@ so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \ +@ENABLE_LOGIND_TRUE@ ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libsystemd-login.so && \ +@ENABLE_LOGIND_TRUE@ mv $(DESTDIR)$(libdir)/libsystemd-login.so.* $(DESTDIR)$(rootlibdir); \ +@ENABLE_LOGIND_TRUE@ fi + +@ENABLE_LOGIND_TRUE@libsystemd-login-uninstall-hook: +@ENABLE_LOGIND_TRUE@ rm -f $(DESTDIR)$(rootlibdir)/libsystemd-login.so* + +@ENABLE_LOGIND_TRUE@logind-install-data-hook: +@ENABLE_LOGIND_TRUE@ $(MKDIR_P) -m 0755 \ +@ENABLE_LOGIND_TRUE@ $(DESTDIR)$(systemunitdir)/multi-user.target.wants \ +@ENABLE_LOGIND_TRUE@ $(DESTDIR)$(localstatedir)/lib/systemd +@ENABLE_LOGIND_TRUE@ ( cd $(DESTDIR)$(systemunitdir) && \ +@ENABLE_LOGIND_TRUE@ rm -f dbus-org.freedesktop.login1.service && \ +@ENABLE_LOGIND_TRUE@ $(LN_S) systemd-logind.service dbus-org.freedesktop.login1.service) +@ENABLE_LOGIND_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \ +@ENABLE_LOGIND_TRUE@ rm -f systemd-logind.service systemd-user-sessions.service && \ +@ENABLE_LOGIND_TRUE@ $(LN_S) ../systemd-logind.service systemd-logind.service && \ +@ENABLE_LOGIND_TRUE@ $(LN_S) ../systemd-user-sessions.service systemd-user-sessions.service ) + +@ENABLE_LOGIND_TRUE@man/sd_login_monitor_unref.3: man/sd_login_monitor_new.3 +@ENABLE_LOGIND_TRUE@man/sd_login_monitor_flush.3: man/sd_login_monitor_new.3 +@ENABLE_LOGIND_TRUE@man/sd_login_monitor_get_fd.3: man/sd_login_monitor_new.3 +@ENABLE_LOGIND_TRUE@man/sd_session_get_uid.3: man/sd_session_is_active.3 +@ENABLE_LOGIND_TRUE@man/sd_session_get_seat.3: man/sd_session_is_active.3 +@ENABLE_LOGIND_TRUE@man/sd_pid_get_owner_uid.3: man/sd_pid_get_session.3 +@ENABLE_LOGIND_TRUE@man/sd_pid_get_unit.3: man/sd_pid_get_session.3 +@ENABLE_LOGIND_TRUE@man/sd_uid_is_on_seat.3: man/sd_uid_get_state.3 +@ENABLE_LOGIND_TRUE@man/sd_uid_get_sessions.3: man/sd_uid_get_state.3 +@ENABLE_LOGIND_TRUE@man/sd_uid_get_seats.3: man/sd_uid_get_state.3 +@ENABLE_LOGIND_TRUE@man/sd_seat_get_sessions.3: man/sd_seat_get_active.3 +@ENABLE_LOGIND_TRUE@man/sd_seat_can_multi_session.3: man/sd_seat_get_active.3 +@ENABLE_LOGIND_TRUE@man/sd_get_sessions.3: man/sd_get_seats.3 +@ENABLE_LOGIND_TRUE@man/sd_get_uids.3: man/sd_get_seats.3 + +units/%: units/%.in Makefile + $(SED_PROCESS) + +man/%: man/%.in Makefile + $(SED_PROCESS) + +sysctl.d/%: sysctl.d/%.in Makefile + $(SED_PROCESS) + +%.pc: %.pc.in Makefile + $(SED_PROCESS) + +src/%.policy.in: src/%.policy.in.in Makefile + $(SED_PROCESS) + +src/%.rules: src/%.rules.in Makefile + $(SED_PROCESS) + +src/%.c: src/%.gperf + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(GPERF) < $< > $@ + +src/%: src/%.m4 + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(M4) -P $(M4_DEFINES) < $< > $@ || rm $@ + +src/load-fragment-gperf-nulstr.c: src/load-fragment-gperf.gperf + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(AWK) 'BEGIN{ keywords=0 ; FS="," ; print "extern const char load_fragment_gperf_nulstr[];" ; print "const char load_fragment_gperf_nulstr[] ="} ; keyword==1 { print "\"" $$1 "\\0\"" } ; /%%/ { keyword=1} ; END { print ";" }' < $< > $@ || rm $@ + +units/%: units/%.m4 Makefile + $(M4_PROCESS_SYSTEM) + +units/user/%: units/%.m4 Makefile + $(M4_PROCESS_USER) + +@HAVE_XSLTPROC_TRUE@man/%.1: man/%.xml +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC_PROCESS_MAN) + +@HAVE_XSLTPROC_TRUE@man/%.1.in: man/%.xml.in +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC_PROCESS_MAN) + +@HAVE_XSLTPROC_TRUE@man/%.3: man/%.xml +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC_PROCESS_MAN) + +@HAVE_XSLTPROC_TRUE@man/%.3.in: man/%.xml.in +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC_PROCESS_MAN) + +@HAVE_XSLTPROC_TRUE@man/%.5: man/%.xml +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC_PROCESS_MAN) + +@HAVE_XSLTPROC_TRUE@man/%.5.in: man/%.xml.in +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC_PROCESS_MAN) + +@HAVE_XSLTPROC_TRUE@man/%.7: man/%.xml +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC_PROCESS_MAN) + +@HAVE_XSLTPROC_TRUE@man/%.7.in: man/%.xml.in +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC_PROCESS_MAN_IN) + +@HAVE_XSLTPROC_TRUE@man/%.8: man/%.xml +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC_PROCESS_MAN) + +@HAVE_XSLTPROC_TRUE@man/%.8.in: man/%.xml.in +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC_PROCESS_MAN_IN) + +@HAVE_XSLTPROC_TRUE@man/%.html: man/%.xml +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC_PROCESS_HTML) + +@HAVE_XSLTPROC_TRUE@man/%.html.in: man/%.xml.in +@HAVE_XSLTPROC_TRUE@ $(XSLTPROC_PROCESS_HTML_IN) + +org.freedesktop.systemd1.%.xml: systemd + $(AM_V_GEN)$(LIBTOOL) --mode=execute $(OBJCOPY) -O binary -j introspect.$* $< $@.tmp && \ + $(STRINGS) $@.tmp | $(AWK) -f $(srcdir)/introspect.awk | \ + $(DBUS_PREPROCESS) -o $@ - && rm $@.tmp + +systemd-install-data-hook: + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(tmpfilesdir) \ + $(DESTDIR)$(sysconfdir)/tmpfiles.d \ + $(DESTDIR)$(prefix)/lib/modules-load.d \ + $(DESTDIR)$(sysconfdir)/modules-load.d \ + $(DESTDIR)$(prefix)/lib/sysctl.d \ + $(DESTDIR)$(sysconfdir)/sysctl.d \ + $(DESTDIR)$(systemshutdowndir) \ + $(DESTDIR)$(systemgeneratordir) \ + $(DESTDIR)$(usergeneratordir) + $(MKDIR_P) -m 0755 \ + $(DESTDIR)$(systemunitdir) \ + $(DESTDIR)$(userunitdir) \ + $(DESTDIR)$(systemunitdir)/sysinit.target.wants \ + $(DESTDIR)$(systemunitdir)/sockets.target.wants \ + $(DESTDIR)$(systemunitdir)/basic.target.wants \ + $(DESTDIR)$(systemunitdir)/shutdown.target.wants \ + $(DESTDIR)$(systemunitdir)/local-fs.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel1.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel2.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel3.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel4.target.wants \ + $(DESTDIR)$(systemunitdir)/runlevel5.target.wants \ + $(DESTDIR)$(systemunitdir)/multi-user.target.wants \ + $(DESTDIR)$(systemunitdir)/graphical.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/system \ + $(DESTDIR)$(pkgsysconfdir)/system/sysinit.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/system/local-fs.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/system/getty.target.wants \ + $(DESTDIR)$(pkgsysconfdir)/user \ + $(DESTDIR)$(dbussessionservicedir) \ + $(DESTDIR)$(sysconfdir)/xdg/systemd + ( cd $(DESTDIR)$(sysconfdir)/xdg/systemd/ && \ + rm -f user && \ + $(LN_S) $(pkgsysconfdir)/user user ) + ( cd $(DESTDIR)$(systemunitdir)/sockets.target.wants && \ + rm -f systemd-initctl.socket systemd-shutdownd.socket && \ + $(LN_S) ../systemd-initctl.socket systemd-initctl.socket && \ + $(LN_S) ../systemd-shutdownd.socket systemd-shutdownd.socket ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel1.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel2.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel3.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel4.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/runlevel5.target.wants && \ + rm -f systemd-update-utmp-runlevel.service && \ + $(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service ) + ( cd $(DESTDIR)$(systemunitdir)/shutdown.target.wants && \ + rm -f systemd-update-utmp-shutdown.service && \ + $(LN_S) ../systemd-update-utmp-shutdown.service systemd-update-utmp-shutdown.service ) + ( cd $(DESTDIR)$(systemunitdir)/local-fs.target.wants && \ + rm -f systemd-remount-api-vfs.service \ + fsck-root.service \ + remount-rootfs.service \ + var-run.mount \ + media.mount && \ + $(LN_S) ../systemd-remount-api-vfs.service systemd-remount-api-vfs.service && \ + $(LN_S) ../fsck-root.service fsck-root.service && \ + $(LN_S) ../remount-rootfs.service remount-rootfs.service && \ + $(LN_S) ../var-run.mount var-run.mount && \ + $(LN_S) ../media.mount media.mount ) + ( cd $(DESTDIR)$(userunitdir) && \ + rm -f shutdown.target sockets.target bluetooth.target printer.target sound.target && \ + $(LN_S) $(systemunitdir)/shutdown.target shutdown.target && \ + $(LN_S) $(systemunitdir)/sockets.target sockets.target && \ + $(LN_S) $(systemunitdir)/bluetooth.target bluetooth.target && \ + $(LN_S) $(systemunitdir)/printer.target printer.target && \ + $(LN_S) $(systemunitdir)/sound.target sound.target ) + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f runlevel0.target runlevel1.target runlevel2.target runlevel3.target runlevel4.target runlevel5.target runlevel6.target && \ + $(LN_S) poweroff.target runlevel0.target && \ + $(LN_S) rescue.target runlevel1.target && \ + $(LN_S) multi-user.target runlevel2.target && \ + $(LN_S) multi-user.target runlevel3.target && \ + $(LN_S) multi-user.target runlevel4.target && \ + $(LN_S) graphical.target runlevel5.target && \ + $(LN_S) reboot.target runlevel6.target ) + ( cd $(DESTDIR)$(systemunitdir) && \ + rm -f default.target ctrl-alt-del.target autovt@.service && \ + $(LN_S) graphical.target default.target && \ + $(LN_S) reboot.target ctrl-alt-del.target && \ + $(LN_S) getty@.service autovt@.service ) + ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \ + rm -f getty.target systemd-ask-password-wall.path && \ + $(LN_S) ../getty.target getty.target && \ + $(LN_S) ../systemd-ask-password-wall.path systemd-ask-password-wall.path) + ( cd $(DESTDIR)$(pkgsysconfdir)/system/getty.target.wants && \ + rm -f getty@tty1.service && \ + $(LN_S) $(systemunitdir)/getty@.service getty@tty1.service ) + ( cd $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants && \ + rm -f remote-fs.target && \ + $(LN_S) $(systemunitdir)/remote-fs.target remote-fs.target ) + ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ + rm -f dev-hugepages.mount \ + dev-mqueue.mount \ + sys-kernel-config.mount \ + sys-kernel-debug.mount \ + sys-kernel-security.mount \ + sys-fs-fuse-connections.mount \ + systemd-modules-load.service \ + systemd-tmpfiles-setup.service \ + systemd-sysctl.service \ + systemd-ask-password-console.path && \ + $(LN_S) ../dev-hugepages.mount dev-hugepages.mount && \ + $(LN_S) ../dev-mqueue.mount dev-mqueue.mount && \ + $(LN_S) ../sys-kernel-config.mount sys-kernel-config.mount && \ + $(LN_S) ../sys-kernel-debug.mount sys-kernel-debug.mount && \ + $(LN_S) ../sys-kernel-security.mount sys-kernel-security.mount && \ + $(LN_S) ../sys-fs-fuse-connections.mount sys-fs-fuse-connections.mount && \ + $(LN_S) ../systemd-modules-load.service systemd-modules-load.service && \ + $(LN_S) ../systemd-tmpfiles-setup.service systemd-tmpfiles-setup.service && \ + $(LN_S) ../systemd-sysctl.service systemd-sysctl.service && \ + $(LN_S) ../systemd-ask-password-console.path systemd-ask-password-console.path ) + ( cd $(DESTDIR)$(systemunitdir)/basic.target.wants && \ + rm -f systemd-tmpfiles-clean.timer && \ + $(LN_S) ../systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.timer ) + ( cd $(DESTDIR)$(dbussessionservicedir) && \ + rm -f org.freedesktop.systemd1.service && \ + $(LN_S) ../system-services/org.freedesktop.systemd1.service org.freedesktop.systemd1.service ) +@HAVE_PLYMOUTH_TRUE@ $(MKDIR_P) -m 0755 \ +@HAVE_PLYMOUTH_TRUE@ $(DESTDIR)$(SYSTEM_SYSVINIT_PATH) \ +@HAVE_PLYMOUTH_TRUE@ $(DESTDIR)$(systemunitdir)/reboot.target.wants \ +@HAVE_PLYMOUTH_TRUE@ $(DESTDIR)$(systemunitdir)/kexec.target.wants \ +@HAVE_PLYMOUTH_TRUE@ $(DESTDIR)$(systemunitdir)/poweroff.target.wants \ +@HAVE_PLYMOUTH_TRUE@ $(DESTDIR)$(systemunitdir)/halt.target.wants +@HAVE_PLYMOUTH_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/sysinit.target.wants && \ +@HAVE_PLYMOUTH_TRUE@ rm -f plymouth-start.service plymouth-read-write.service && \ +@HAVE_PLYMOUTH_TRUE@ $(LN_S) ../plymouth-start.service plymouth-start.service && \ +@HAVE_PLYMOUTH_TRUE@ $(LN_S) ../plymouth-read-write.service plymouth-read-write.service ) +@HAVE_PLYMOUTH_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \ +@HAVE_PLYMOUTH_TRUE@ rm -f plymouth-quit.service plymouth-quit-wait.service && \ +@HAVE_PLYMOUTH_TRUE@ $(LN_S) ../plymouth-quit.service plymouth-quit.service && \ +@HAVE_PLYMOUTH_TRUE@ $(LN_S) ../plymouth-quit-wait.service plymouth-quit-wait.service ) +@HAVE_PLYMOUTH_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/reboot.target.wants && \ +@HAVE_PLYMOUTH_TRUE@ rm -f plymouth-reboot.service && \ +@HAVE_PLYMOUTH_TRUE@ $(LN_S) ../plymouth-reboot.service plymouth-reboot.service ) +@HAVE_PLYMOUTH_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/kexec.target.wants && \ +@HAVE_PLYMOUTH_TRUE@ rm -f plymouth-kexec.service && \ +@HAVE_PLYMOUTH_TRUE@ $(LN_S) ../plymouth-kexec.service plymouth-kexec.service ) +@HAVE_PLYMOUTH_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/poweroff.target.wants && \ +@HAVE_PLYMOUTH_TRUE@ rm -f plymouth-poweroff.service && \ +@HAVE_PLYMOUTH_TRUE@ $(LN_S) ../plymouth-poweroff.service plymouth-poweroff.service ) +@HAVE_PLYMOUTH_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/halt.target.wants && \ +@HAVE_PLYMOUTH_TRUE@ rm -f plymouth-halt.service && \ +@HAVE_PLYMOUTH_TRUE@ $(LN_S) ../plymouth-halt.service plymouth-halt.service ) +@TARGET_MEEGO_TRUE@ $(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants +@TARGET_MEEGO_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \ +@TARGET_MEEGO_TRUE@ rm -f network.target && \ +@TARGET_MEEGO_TRUE@ $(LN_S) $(systemunitdir)/network.target network.target ) +@TARGET_MEEGO_TRUE@ ( cd $(DESTDIR)$(pkgsysconfdir)/system/sysinit.target.wants && \ +@TARGET_MEEGO_TRUE@ rm -f * ) +@TARGET_MEEGO_TRUE@ ( cd $(DESTDIR)$(pkgsysconfdir)/system/local-fs.target.wants && \ +@TARGET_MEEGO_TRUE@ rm -f * ) +@TARGET_MEEGO_TRUE@ ( cd $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants && \ +@TARGET_MEEGO_TRUE@ rm -f * ) +@TARGET_MEEGO_TRUE@ ( cd $(DESTDIR)$(pkgsysconfdir)/system/getty.target.wants && \ +@TARGET_MEEGO_TRUE@ rm -f * ) + +@TARGET_FEDORA_TRUE@ $(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants +@TARGET_FEDORA_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/final.target.wants && \ +@TARGET_FEDORA_TRUE@ rm -f halt-local.service && \ +@TARGET_FEDORA_TRUE@ $(LN_S) $(systemunitdir)/halt-local.service halt-local.service ) +@TARGET_FEDORA_TRUE@ ( cd $(DESTDIR)$(systemunitdir) && \ +@TARGET_FEDORA_TRUE@ rm -f display-manager.service single.service && \ +@TARGET_FEDORA_TRUE@ $(LN_S) prefdm.service display-manager.service && \ +@TARGET_FEDORA_TRUE@ $(LN_S) rescue.service single.service ) +@TARGET_FEDORA_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/graphical.target.wants && \ +@TARGET_FEDORA_TRUE@ rm -f display-manager.service && \ +@TARGET_FEDORA_TRUE@ $(LN_S) $(systemunitdir)/display-manager.service display-manager.service ) + +@TARGET_MANDRIVA_TRUE@ $(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants +@TARGET_MANDRIVA_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/final.target.wants && \ +@TARGET_MANDRIVA_TRUE@ rm -f halt-local.service && \ +@TARGET_MANDRIVA_TRUE@ $(LN_S) $(systemunitdir)/halt-local.service halt-local.service ) +@TARGET_MANDRIVA_TRUE@ ( cd $(DESTDIR)$(systemunitdir) && \ +@TARGET_MANDRIVA_TRUE@ rm -f display-manager.service dm.service single.service && \ +@TARGET_MANDRIVA_TRUE@ $(LN_S) prefdm.service display-manager.service && \ +@TARGET_MANDRIVA_TRUE@ $(LN_S) prefdm.service dm.service && \ +@TARGET_MANDRIVA_TRUE@ $(LN_S) rescue.service single.service ) +@TARGET_MANDRIVA_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/graphical.target.wants && \ +@TARGET_MANDRIVA_TRUE@ rm -f display-manager.service && \ +@TARGET_MANDRIVA_TRUE@ $(LN_S) $(systemunitdir)/display-manager.service display-manager.service ) + +@TARGET_DEBIAN_OR_UBUNTU_TRUE@ ( cd $(DESTDIR)$(systemunitdir) && \ +@TARGET_DEBIAN_OR_UBUNTU_TRUE@ rm -f runlevel5.target && \ +@TARGET_DEBIAN_OR_UBUNTU_TRUE@ $(LN_S) multi-user.target runlevel5.target ) + +@TARGET_SUSE_TRUE@ $(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants +@TARGET_SUSE_TRUE@ ( cd $(DESTDIR)$(systemunitdir) && \ +@TARGET_SUSE_TRUE@ rm -f local.service && \ +@TARGET_SUSE_TRUE@ $(LN_S) rc-local.service local.service ) +@TARGET_SUSE_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/final.target.wants && \ +@TARGET_SUSE_TRUE@ rm -f halt-local.service && \ +@TARGET_SUSE_TRUE@ $(LN_S) $(systemunitdir)/halt-local.service halt-local.service ) + +@TARGET_MAGEIA_TRUE@ $(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants +@TARGET_MAGEIA_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/final.target.wants && \ +@TARGET_MAGEIA_TRUE@ rm -f halt-local.service && \ +@TARGET_MAGEIA_TRUE@ $(LN_S) $(systemunitdir)/halt-local.service halt-local.service ) +@TARGET_MAGEIA_TRUE@ ( cd $(DESTDIR)$(systemunitdir) && \ +@TARGET_MAGEIA_TRUE@ rm -f display-manager.service && \ +@TARGET_MAGEIA_TRUE@ $(LN_S) prefdm.service display-manager.service && \ +@TARGET_MAGEIA_TRUE@ $(LN_S) prefdm.service dm.service ) +@TARGET_MAGEIA_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/graphical.target.wants && \ +@TARGET_MAGEIA_TRUE@ rm -f display-manager.service && \ +@TARGET_MAGEIA_TRUE@ $(LN_S) $(systemunitdir)/display-manager.service display-manager.service ) + +@HAVE_SYSV_COMPAT_TRUE@ ( cd $(DESTDIR)$(systemunitdir)/local-fs.target.wants && \ +@HAVE_SYSV_COMPAT_TRUE@ rm -f var-lock.mount && \ +@HAVE_SYSV_COMPAT_TRUE@ $(LN_S) ../var-lock.mount var-lock.mount ) + +install-exec-hook: $(INSTALL_EXEC_HOOKS) + +uninstall-hook: $(UNINSTALL_EXEC_HOOKS) + +install-data-hook: systemd-install-data-hook $(INSTALL_DATA_HOOKS) + +upload: all distcheck + cp -v systemd-$(VERSION).tar.xz /home/lennart/git.fedora/systemd/ + scp systemd-$(VERSION).tar.xz fdo:/srv/www.freedesktop.org/www/software/systemd/ + scp man/*.html fdo:/srv/www.freedesktop.org/www/software/systemd/man/ + scp man/*.html tango:public/systemd-man/ + +git-tag: + git tag "v$(VERSION)" -m "systemd $(VERSION)" + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..53ef982 --- /dev/null +++ b/NEWS @@ -0,0 +1,225 @@ +systemd System and Service Manager + +CHANGES WITH 43: + * This is mostly a bugfix release + + * systems lacking /etc/os-release are no longer supported. + + * Various functionality updates to libsystemd-login.so + + * Track class of PAM logins to distuingish greeters from + normal user logins. + + Contributions from: Kay Sievers, Lennart Poettering, Michael + Biebl + +CHANGES WITH 42: + * This is an important bugfix release for v41. + + * Building man pages is now optional which should be useful + for those building systemd from git but unwilling to install + xsltproc. + + * Watchdog support for supervising services is now usable. In + a future release support for hardware watchdogs + (i.e. /dev/watchdog) will be added building on this. + + * Service start rate limiting is now configurable and can be + turned off per service. When a start rate limit is hit a + reboot can automatically be triggered. + + * New CanReboot(), CanPowerOff() bus calls in systemd-logind. + + Contributions from: Benjamin Franzke, Bill Nottingham, + Frederic Crozat, Lennart Poettering, Michael Olbrich, Michal + Schmidt, Michał Górny, Piotr Drąg + +CHANGES WITH 41: + * The systemd binary is installed /usr/lib/systemd/systemd now; + An existing /sbin/init symlink needs to be adapted with the + package update. + + * The code that loads kernel modules has been ported to invoke + libkmod directly, instead of modprobe. This means we do not + support systems with module-init-tools anymore. + + * Watchdog support is now already useful, but still not + complete. + + * A new kernel command line option systemd.setenv= is + understood to set system wide environment variables + dynamically at boot. + + * We now limit the set of capabilities of systemd-journald. + + * We now set SIGPIPE to ignore by default, since it only is + useful in shell pipelines, and has little use in general + code. This can be disabled with IgnoreSIPIPE=no in unit + files. + + Contributions from: Benjamin Franzke, Kay Sievers, Lennart + Poettering, Michael Olbrich, Michal Schmidt, Tom Gundersen, + William Douglas + +CHANGES WITH 40: + * This is mostly a bugfix release + + * We now expose the reason why a service failed in the + "Result" D-Bus property. + + * Rudimentary service watchdog support (will be completed over + the next few releases.) + + * When systemd forks off in order execute some service we will + now immediately changes its argv[0] to reflect which process + it will execute. This is useful to minimize the time window + with a generic argv[0], which makes bootcharts more useful + + Contributions from: Alvaro Soliverez, Chris Paulson-Ellis, Kay + Sievers, Lennart Poettering, Michael Olbrich, Michal Schmidt, + Mike Kazantsev, Ray Strode + +CHANGES WITH 39: + * This is mostly a test release, but incorporates many + bugfixes. + + * New systemd-cgtop tool to show control groups by their + resource usage. + + * Linking against libacl for ACLs is optional again. If + disabled, support tracking device access for active logins + goes becomes unavailable, and so does access to the user + journals by the respective users. + + * If a group "adm" exists, journal files are automatically + owned by them, thus allow members of this group full access + to the system journal as well as all user journals. + + * The journal now stores the SELinux context of the logging + client for all entries. + + * Add C++ inclusion guards to all public headers + + * New output mode "cat" in the journal to print only text + messages, without any meta data like date or time. + + * Include tiny X server wrapper as a temporary stop-gap to + teach XOrg udev display enumeration. This is used by display + managers such as gdm, and will go away as soon as XOrg + learned native udev hotplugging for display devices. + + * Add new systemd-cat tool for executing arbitrary programs + with STDERR/STDOUT connected to the journal. Can also act as + BSD logger replacement, and does so by default. + + * Optionally store all locally generated coredumps in the + journal along with meta data. + + * systemd-tmpfiles learnt four new commands: n, L, c, b, for + writing short strings to files (for usage for /sys), and for + creating symlinks, character and block device nodes. + + * New unit file option ControlGroupPersistent= to make cgroups + persistent, following the mechanisms outlined in + http://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups + + * Support multiple local RTCs in a sane way + + * No longer monopolize IO when replaying readahead data on + rotating disks, since we might starve non-file-system IO to + death, since fanotify() will not see accesses done by blkid, + or fsck. + + * Don't show kernel threads in systemd-cgls anymore, unless + requested with new -k switch. + + Contributions from: Dan Horák, Kay Sievers, Lennart + Poettering, Michal Schmidt + +CHANGES WITH 38: + * This is mostly a test release, but incorporates many + bugfixes. + + * The git repository moved to: + git://anongit.freedesktop.org/systemd/systemd + ssh://git.freedesktop.org/git/systemd/systemd + + * First release with the journal + http://0pointer.de/blog/projects/the-journal.html + + * The journal replaces both systemd-kmsg-syslogd and + systemd-stdout-bridge. + + * New sd_pid_get_unit() API call in libsystemd-logind + + * Many systemadm clean-ups + + * Introduce remote-fs-pre.target which is ordered before all + remote mounts and may be used to start services before all + remote mounts. + + * Added Mageia support + + * Add bash completion for systemd-loginctl + + * Actively monitor PID file creation for daemons which exit in + the parent process before having finished writing the PID + file in the daemon process. Daemons which do this need to be + fixed (i.e. PID file creation must have finished before the + parent exits), but we now react a bit more gracefully to them. + + * Add colourful boot output, mimicking the well-known output + of existing distributions. + + * New option PassCredentials= for socket units, for + compatibility with a recent kernel ABI breakage. + + * /etc/rc.local is now hooked in via a generator binary, and + thus will no longer act as synchronization point during + boot. + + * systemctl list-unit-files now supports --root=. + + * systemd-tmpfiles now understands two new commands: z, Z for + relabelling files according to the SELinux database. This is + useful to apply SELinux labels to specific files in /sys, + among other things. + + * Output of SysV services is now forwarded to both the console + and the journal by default, not only just the console. + + * New man pages for all APIs from libsystemd-login. + + * The build tree got reorganized and a the build system is a + lot more modular allowing embedded setups to specifically + select the components of systemd they are interested in. + + * Support for Linux systems lacking the kernel VT subsystem is + restored. + + * configure's --with-rootdir= got renamed to + --with-rootprefix= to follow the naming used by udev and + kmod + + * Unless specified otherwise we'll now install to /usr instead + of /usr/local by default. + + * Processes with '@' in argv[0][0] are now excluded from the + final shut-down killing spree, following the logic explained + in: + http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons + + * All processes remaining in a service cgroup when we enter + the START or START_PRE states are now killed with + SIGKILL. That means it is no longer possible to spawn + background processes from ExecStart= lines (which was never + supported anyway, and bad style). + + * New PropagateReloadTo=/PropagateReloadFrom= options to bind + reloading of units together. + + Contributions from: Bill Nottingham, Daniel Walsh, Dave + Reisner, Dexter Morgan, Gregs Gregs, Jonathan Nieder, Kay + Sievers, Lennart Poettering, Michael Biebl, Michal Schmidt, + Michał Górny, Ran Benita, Thomas Jarosch, Tim Waugh, Tollef + Fog Heen, Tom Gundersen, Zbigniew Jędrzejewski-Szmek diff --git a/README b/README new file mode 100644 index 0000000..10cbc56 --- /dev/null +++ b/README @@ -0,0 +1,107 @@ +systemd System and Service Manager + +DETAILS: + http://0pointer.de/blog/projects/systemd.html + +WEB SITE: + http://www.freedesktop.org/wiki/Software/systemd + +GIT: + git://anongit.freedesktop.org/systemd/systemd + ssh://git.freedesktop.org/git/systemd/systemd + +GITWEB: + http://cgit.freedesktop.org/systemd/systemd + +MAILING LIST: + http://lists.freedesktop.org/mailman/listinfo/systemd-devel + http://lists.freedesktop.org/mailman/listinfo/systemd-commits + +IRC: + #systemd on irc.freenode.org + +BUG REPORTS: + https://bugs.freedesktop.org/enter_bug.cgi?product=systemd + +AUTHOR: + Lennart Poettering with major support from Kay Sievers + +LICENSE: + GPLv2+ for all code, except sd-daemon.[ch] and + sd-readahead.[ch] which are MIT + +REQUIREMENTS: + Linux kernel >= 2.6.39 + with devtmpfs + with cgroups (but it's OK to disable all controllers) + optional but strongly recommended: autofs4, ipv6 + libudev >= 172 + dbus >= 1.4.0 + libcap + gtk+ >= 2.20 (optional) + PAM >= 1.1.2 (optional) + libcryptsetup (optional) + libaudit (optional) + libselinux (optional) + tcpwrappers (optional) + libnotify (optional) + + When you build from git you need the following additional dependencies: + + vala >= 0.10 + docbook-xsl + xsltproc + automake + autoconf + libtool + gperf + make, gcc, and similar tools + + During runtime you need the following dependencies: + + util-linux > v2.18 (requires fsck -l, agetty -s) + sulogin (from sysvinit-tools, optional but recommended) + plymouth (optional) + dracut (optional) + + When systemd-hostnamed is used it is strongly recommended to + install nss-myhostname to ensure that in a world of + dynamically changing hostnames the hostname stays resolveable + under all circumstances. In fact, systemd-hostnamed will warn + if nss-myhostname is not installed. Packagers are encouraged to + add a dependency on nss-myhostname to the package that + includes systemd-hostnamed. + + Note that D-Bus can link against libsystemd-login.so, which + results in a cyclic build dependency. To accomodate for this + please build D-Bus without systemd first, then build systemd, + then rebuild D-Bus with systemd support. + +WARNINGS: + systemd will warn you during boot if /etc/mtab is not a + symlink to /proc/mounts. Please ensure that /etc/mtab is a + proper symlink. + + systemd will warn you during boot if /usr is on a different + file system than /. While in systemd itself very little will + break if /usr is on a separate partition many of its + dependencies very likely will break sooner or later in one + form or another. For example udev rules tend to refer to + binaries in /usr, binaries that link to libraries in /usr or + binaries that refer to data files in /usr. Since these + breakages are not always directly visible systemd will warn + about this, since this kind of file system setup is not really + supported anymore by the basic set of Linux OS components. + + For more information on this issue consult + http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken + +ENGINEERING AND CONSULTING SERVICES: + ProFUSION offers professional + engineering and consulting services for systemd for embedded + and other use. Please contact Gustavo Barbieri + for more information. + + Disclaimer: This notice is not a recommendation or official + endorsement. However, ProFUSION's upstream work has been very + beneficial for the systemd project. diff --git a/TODO b/TODO new file mode 100644 index 0000000..cba2c8c --- /dev/null +++ b/TODO @@ -0,0 +1,307 @@ +Bugfixes: + +* swap units that are activated by one name but shown in the kernel under another are semi-broken + +* NM should pull in network.target (PENDING) + https://bugzilla.redhat.com/show_bug.cgi?id=692008 + +* make anaconda write timeout=0 for encrypted devices + +* service: pid file reading after reload doesn't work, since we don't reset the pid variable + +* make sure timeouts are applied to Type=oneshot services. + +* Dangling symlinks of .automount unit files in .wants/ directories, set up + automount points even when the original .automount file did not exist + anymore. Only the .mount unit was still around. + +* make polkit checks async + +* properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point. + +Features: + +* systemctl reboot -ff should trigger an immediate reboot + +* support units generated by a generator and placed in /run/systemd/system/; the directory is + currently ignored because it is empty before the generatores are executed + +* let 'systemctl reboot' called as non-root talk to logind instead of systemd, to get polkit + system policy in the loop of privilege checking, so normal users can possibly use /sbin/reboot + +* Possibly, detect whether SysV init scripts can do reloading by looking for "echo Usage:" lines + +* figure out whether we should leave dbus around during shutdown + +* support closing all fds via RLIMIT_NOFILE instead of /proc, in order to make chroot stuff work. + +* add interface to allow immediate rotation of the journal, and even flushing. + +* don't log coredumps of PID 1 into the journal + +* if a journal file is corrupt, rotate it and create a new one + +* dbus: in fedora, make the machine a symlink to /etc/machine-id + +* journald: reuse XZ context + +* logind: add equivalent to sd_pid_get_owner_uid() to the D-Bus API + +* write RPM spec macros for presets + +* write man pages for systemd-cat + +* journal: write man pages for API + +* journal: OR matches are borked + +* journal: extend hash tables as we go + +* journal: API for looking for retrieving "all values of this field" + +* journal: deal nicely with byte-by-byte copied files, especially regards header + +* journal: local deserializer of export mode, http server + +* journal: message catalog + +* journal: forward-secure signatures + +* document the exit codes when services fail before they are exec()ed + +* rework namespace support, don't use pivot_root, and mount things after creating the namespace, not before + +* systemctl journal command + +* journalctl: --cursor support, priority filtering + +* systemctl status: show coredumps + +* systemctl status: show whether journal was rotated since service started + +* save coredump in Windows/Mozilla minidump format + +* support crash reporting operation modes (https://live.gnome.org/GnomeOS/Design/Whiteboards/ProblemReporting) + +* allow per-entry control on /var vs. /run (think incognito browser mode) + +* clean up session cgroups that remain after logout (think sshd), but eventually run empty + +* support "systemctl stop foobar@.service" to stop all units matching a certain template + +* move to LGPL2+ + +* logind: allow showing logout dialog from system + +* document that %% can be used to write % in a string that is specifier extended + +* check utf8 everywhere + +* when an instanced service exits, remove its parent cgroup too if possible. + +* Make libselinux, libattr, libcap, libdl dependencies only of the tools which actually need them. + +* as Tom Gundersen pointed out there's a always a dep loop if people use crypto file systems with random keys + +* unset container= in PID1? + +* automatically escape unit names passed on the service (i.e. think "systemctl start serial-getty.service@serial/by-path/jshdfjsdfhkjh" being automatically escaped as necessary. + +* if we can not get user quota for tmpfs, mount a separate tmpfs instance + for every user in /run/user/$USER with a configured maximum size + +* default to actual 32bit PIDs, via /proc/sys/kernel/pid_max + +* add an option to make mounts private/shareable and so on, enable this for root by default + +* internal restart counter for units (focus on auto-respawn) + +* finer-grained auto-respawn settings (rate-limit) + +* be able to specify a forced restart of service A where service B depends on, in case B + needs to be auto-respawned? + +* Something is wrong with symlink handling of "autovt@.service" in "systemctl list-unit-files" + +* when a bus name of a service disappears from the bus make sure to queue further activation requests + +* something like ConditionExec= or ExecStartPre= without failure state + +* service restart retry configuration + +* tmpfiles: apply "x" on "D" too (see patch from William Douglas) + +* don't set $HOME in services unless requested + +* hide PAM/TCPWrap options in fragment parser when compile time disabled + +* when we automatically restart a service, ensure we retsart its rdeps, too. + +* allow Type=simple with PIDFile= + https://bugzilla.redhat.com/show_bug.cgi?id=723942 + +* move PAM code into its own binary + +* warn if the user stops a service but not its associated socket + +* logind: spawn user@..service on login + +* logind: non-local X11 server handling + +* implement Register= switch in .socket units to enable registration + in Avahi, RPC and other socket registration services. + +* make sure systemd-ask-password-wall does not shutdown systemd-ask-password-console too early + +* readahead: use BTRFS_IOC_DEFRAG_RANGE instead of BTRFS_IOC_DEFRAG ioctl, with START_IO + +* readahead: check whether a btrfs volume includes ssd by checking mount flag "ssd" + +* support sd_notify() style notification when reload begins (RELOADING=1), reload is finished (READY=1), and add ReloadSignal= then to use in combination + +* support sd_notify() style notification when shutting down, to make auto-exit bus services work (STOPPING=1) + +* verify that the AF_UNIX sockets of a service in the fs still exist + when we start a service in order to avoid confusion when a user + assumes starting a service is enough to make it accessible + +* Make it possible to set the keymap independently from the font on + the kernel cmdline. Right now setting one resets also the other. + +* move nss-myhostname into systemd + +* and a dbus call to generate target from current state + +* drop /.readahead on bigger upgrades with yum + +* add inode nr check to readahead to suppress preloading changed files + +* add support for /bin/mount -s + +* GC unreferenced jobs (such as .device jobs) + +* when failing to start a service due to ratelimiting, try again later, if restart=always is set + +* write blog stories about: + - enabling dbus services + - status update + - how to make changes to sysctl and sysfs attributes + - remote access + - how to pass throw-away units to systemd, or dynamically change properties of existing units + - how to integrate cgconfig and suchlike with systemd + - resource control in systemd + +* allow port=0 in .socket units + +* move readahead files into /var, look for them with .path units + +* teach dbus to activate all services it finds in /etc/systemd/services/org-*.service + +* support systemd.mask= on the kernel command line. + +* when key file cannot be found, read it from kbd in cryptsetup + +* reuse mkdtemp namespace dirs in /tmp? + +* recreate systemd's D-Bus private socket file on SIGUSR2 + +* Support --test based on current system state + +* investigate whether the gnome pty helper should be moved into systemd, to provide cgroup support. + +* maybe introduce ExecRestartPre= + +* configurable jitter for timer events + +* timer events with system resume + +* timer events on calendar time + +* dot output for --test showing the 'initial transaction' + +* calendar time support in timer, iCalendar semantics for the timer stuff (RFC2445) + http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=99ee5315dac6211e972fa3f23bcc9a0343ff58c4 + +* implicitly import "defaults" settings file into all types +* exec settings override +* writable cgroups dbus properties for live changes + +* read config fragments for all units from /lib/systemd/system/foobar.service.d/ to override/extend specific settings + +* port over to LISTEN_FDS/LISTEN_PID: + - rpcbind (/var/run/rpcbind.sock!) HAVEPATCH + - cups HAVEPATCH + - postfix, saslauthd + - apache/samba + - libvirtd (/var/run/libvirt/libvirt-sock-ro) + - bluetoothd (/var/run/sdp! @/org/bluez/audio!) + - distccd + +* auditd service files + +* fingerprint.target, wireless.target, gps.target, netdevice.target + +* io priority during initialization + +* if a service fails too often, make the service enter failed mode, and the socket, too. + +* systemctl list-jobs - show dependencies + +* add systemctl switch to dump transaction without executing it + +* suspend, resume support? + +* drop cap bounding set in readahead and other services + +External: + +* dbus: + - get process transport into dbus for systemctl -P/-H (PENDING) + - dbus --user + - natively watch for dbus-*.service symlinks (PENDING) + - allow specification of socket mode/umask when allocating DBusServer + - allow disabling of fd passing when connecting a AF_UNIX connection + - allow disabling of UID passing for AUTH EXTERNAL + +* systemd --user + PR_SET_CHILD_REAPER patch: https://lkml.org/lkml/2011/7/28/426 + +* fix alsa mixer restore to not print error when no config is stored + +* udisks should not use udisks-part-id, instead use blkid. also not probe /dev/loopxxx + +* snd-seq should go, https://bugzilla.redhat.com/show_bug.cgi?id=676095 + +* gnome-shell python script/glxinfo/is-accelerated must die + +* make cryptsetup lower --iter-time + +* patch kernel for xattr support in /dev, /proc/, /sys and /sys/fs/cgroup? + +* NTP: the kernel's 11-minutes-mode syncs the system time to the RTC, but only + in an ~30 minutes window. It does not adjust larger differences. Find a way + to tell the kernel, to always do a full time sync when the RTC is in UTC and + we are in 11-minutes-mode. When we trust the system time to NTP we also want + the RTC to sync up. + +* patch kernel for cpu feature modalias for autoloading aes/kvm/... + (patches in linux-next, on the way to the next kernel) + +* kernel: add /proc/sys file exposing CAP_LAST_CAP? sysconf? + merged: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=73efc0394e148d0e15583e13712637831f926720 + +* kernel: add device_type = "fb", "fbcon" to class "graphics" + +Regularly: + +* look for close() vs. close_nointr() vs. close_nointr_nofail() + +* check for strerror(r) instead of strerror(-r) + +* Use PR_SET_PROCTITLE_AREA if it becomes available in the kernel + +* %m in printf() instead of strerror(); + +* pahole + +* set_put(), hashmap_put() return values check. i.e. == 0 doesn't free()! diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..476d532 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1311 @@ +# generated automatically by aclocal 1.11.3 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# nls.m4 serial 5 (gettext-0.18) +dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation, +dnl Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2003. + +AC_PREREQ([2.50]) + +AC_DEFUN([AM_NLS], +[ + AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE([nls], + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT([$USE_NLS]) + AC_SUBST([USE_NLS]) +]) + +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT]) + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .]) + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])# PKG_CHECK_MODULES + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.3], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.3])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, +# 2010, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_PROG_CC_C_O +# -------------- +# Like AC_PROG_CC_C_O, but changed for automake. +AC_DEFUN([AM_PROG_CC_C_O], +[AC_REQUIRE([AC_PROG_CC_C_O])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +dnl Make sure AC_PROG_CC is never called again, or it will override our +dnl setting of CC. +m4_define([AC_PROG_CC], + [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2009, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# (`yes' being less verbose, `no' or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], +[ --enable-silent-rules less verbose build output (undo: `make V=1') + --disable-silent-rules verbose build output (undo: `make V=0')]) +case $enable_silent_rules in +yes) AM_DEFAULT_VERBOSITY=0;; +no) AM_DEFAULT_VERBOSITY=1;; +*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few `make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using `$V' instead of `$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +# Autoconf support for the Vala compiler + +# Copyright (C) 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# Check whether the Vala compiler exists in `PATH'. If it is found, the +# variable VALAC is set. Optionally a minimum release number of the +# compiler can be requested. +# +# AM_PROG_VALAC([MINIMUM-VERSION]) +# -------------------------------- +AC_DEFUN([AM_PROG_VALAC], +[AC_PATH_PROG([VALAC], [valac], []) + AS_IF([test -z "$VALAC"], + [AC_MSG_WARN([No Vala compiler found. You will not be able to compile .vala source files.])], + [AS_IF([test -n "$1"], + [AC_MSG_CHECKING([$VALAC is at least version $1]) + am__vala_version=`$VALAC --version | sed 's/Vala *//'` + AS_VERSION_COMPARE([$1], ["$am__vala_version"], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + AC_MSG_ERROR([Vala $1 not found.])])])]) +]) + +m4_include([m4/acx_libwrap.m4]) +m4_include([m4/attributes.m4]) +m4_include([m4/intltool.m4]) +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) diff --git a/compile b/compile new file mode 100755 index 0000000..b1f4749 --- /dev/null +++ b/compile @@ -0,0 +1,310 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-01-04.17; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010, 2012 Free +# Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l*) + lib=${1#-l} + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + set x "$@" "$dir/$lib.dll.lib" + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + set x "$@" "$dir/$lib.lib" + break + fi + done + IFS=$save_IFS + + test "$found" != yes && set x "$@" "$lib.lib" + shift + ;; + -L*) + func_file_conv "${1#-L}" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..49ba16f --- /dev/null +++ b/config.guess @@ -0,0 +1,1522 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-01-01' + +# This file 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. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..e2fd99c --- /dev/null +++ b/config.h.in @@ -0,0 +1,205 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Whether on mips arch */ +#undef ARCH_MIPS + +/* Canonical host string. */ +#undef CANONICAL_HOST + +/* Target Distribution */ +#undef DISTRIBUTION + +/* ACL available */ +#undef HAVE_ACL + +/* Define to 1 if you have the header file. */ +#undef HAVE_ACL_LIBACL_H + +/* AUDIT available */ +#undef HAVE_AUDIT + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define if GTK is available */ +#undef HAVE_GTK + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBAUDIT_H + +/* Define if libcryptsetup is available */ +#undef HAVE_LIBCRYPTSETUP + +/* Have tcpwrap? */ +#undef HAVE_LIBWRAP + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* PAM available */ +#undef HAVE_PAM + +/* Define to 1 if you have the header file. */ +#undef HAVE_SECURITY_PAM_EXT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SECURITY_PAM_MODULES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SECURITY_PAM_MODUTIL_H + +/* Define if SELinux is available */ +#undef HAVE_SELINUX + +/* Define if /bin, /sbin aren't symlinks into /usr */ +#undef HAVE_SPLIT_USR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* SysV init scripts and rcN.d links are supported. */ +#undef HAVE_SYSV_COMPAT + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_ACL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_CAPABILITY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define if XZ is available */ +#undef HAVE_XZ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#undef NO_MINUS_C_MINUS_O + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Target is ALTLinux */ +#undef TARGET_ALTLINUX + +/* Target is Ångström */ +#undef TARGET_ANGSTROM + +/* Target is ArchLinux */ +#undef TARGET_ARCH + +/* Target is Debian */ +#undef TARGET_DEBIAN + +/* Target is Fedora/RHEL */ +#undef TARGET_FEDORA + +/* Target is Frugalware */ +#undef TARGET_FRUGALWARE + +/* Target is Gentoo */ +#undef TARGET_GENTOO + +/* Target is Mageia */ +#undef TARGET_MAGEIA + +/* Target is Mandriva */ +#undef TARGET_MANDRIVA + +/* Target is MeeGo */ +#undef TARGET_MEEGO + +/* Target is Slackware */ +#undef TARGET_SLACKWARE + +/* Target is openSUSE/SLE */ +#undef TARGET_SUSE + +/* Target is Ubuntu */ +#undef TARGET_UBUNTU + +/* GID of the 'tty' group */ +#undef TTY_GID + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Version number of package */ +#undef VERSION + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..d6b6b3c --- /dev/null +++ b/config.sub @@ -0,0 +1,1766 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-01-01' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..70ce3da --- /dev/null +++ b/configure @@ -0,0 +1,18833 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.68 for systemd 43. +# +# Report bugs to . +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: systemd-devel@lists.freedesktop.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + +as_awk_strverscmp=' + # Use only awk features that work with 7th edition Unix awk (1978). + # My, what an old awk you have, Mr. Solaris! + END { + while (length(v1) && length(v2)) { + # Set d1 to be the next thing to compare from v1, and likewise for d2. + # Normally this is a single character, but if v1 and v2 contain digits, + # compare them as integers and fractions as strverscmp does. + if (v1 ~ /^[0-9]/ && v2 ~ /^[0-9]/) { + # Split v1 and v2 into their leading digit string components d1 and d2, + # and advance v1 and v2 past the leading digit strings. + for (len1 = 1; substr(v1, len1 + 1) ~ /^[0-9]/; len1++) continue + for (len2 = 1; substr(v2, len2 + 1) ~ /^[0-9]/; len2++) continue + d1 = substr(v1, 1, len1); v1 = substr(v1, len1 + 1) + d2 = substr(v2, 1, len2); v2 = substr(v2, len2 + 1) + if (d1 ~ /^0/) { + if (d2 ~ /^0/) { + # Compare two fractions. + while (d1 ~ /^0/ && d2 ~ /^0/) { + d1 = substr(d1, 2); len1-- + d2 = substr(d2, 2); len2-- + } + if (len1 != len2 && ! (len1 && len2 && substr(d1, 1, 1) == substr(d2, 1, 1))) { + # The two components differ in length, and the common prefix + # contains only leading zeros. Consider the longer to be less. + d1 = -len1 + d2 = -len2 + } else { + # Otherwise, compare as strings. + d1 = "x" d1 + d2 = "x" d2 + } + } else { + # A fraction is less than an integer. + exit 1 + } + } else { + if (d2 ~ /^0/) { + # An integer is greater than a fraction. + exit 2 + } else { + # Compare two integers. + d1 += 0 + d2 += 0 + } + } + } else { + # The normal case, without worrying about digits. + d1 = substr(v1, 1, 1); v1 = substr(v1, 2) + d2 = substr(v2, 1, 1); v2 = substr(v2, 2) + } + if (d1 < d2) exit 1 + if (d1 > d2) exit 2 + } + # Beware Solaris /usr/xgp4/bin/awk (at least through Solaris 10), + # which mishandles some comparisons of empty strings to integers. + if (length(v2)) exit 1 + if (length(v1)) exit 2 + } +' + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='systemd' +PACKAGE_TARNAME='systemd' +PACKAGE_VERSION='43' +PACKAGE_STRING='systemd 43' +PACKAGE_BUGREPORT='systemd-devel@lists.freedesktop.org' +PACKAGE_URL='' + +ac_unique_file="src/main.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_default_prefix=/usr +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +rootlibdir +rootprefix +pamlibdir +udevrulesdir +dbusinterfacedir +dbussystemservicedir +dbussessionservicedir +dbuspolicydir +HAVE_SYSV_COMPAT_FALSE +HAVE_SYSV_COMPAT_TRUE +HAVE_PLYMOUTH_FALSE +HAVE_PLYMOUTH_TRUE +TARGET_MAGEIA_FALSE +TARGET_MAGEIA_TRUE +TARGET_ANGSTROM_FALSE +TARGET_ANGSTROM_TRUE +TARGET_MEEGO_FALSE +TARGET_MEEGO_TRUE +TARGET_MANDRIVA_FALSE +TARGET_MANDRIVA_TRUE +TARGET_ALTLINUX_FALSE +TARGET_ALTLINUX_TRUE +TARGET_FRUGALWARE_FALSE +TARGET_FRUGALWARE_TRUE +TARGET_SLACKWARE_FALSE +TARGET_SLACKWARE_TRUE +TARGET_GENTOO_FALSE +TARGET_GENTOO_TRUE +TARGET_ARCH_FALSE +TARGET_ARCH_TRUE +TARGET_DEBIAN_OR_UBUNTU_FALSE +TARGET_DEBIAN_OR_UBUNTU_TRUE +TARGET_UBUNTU_FALSE +TARGET_UBUNTU_TRUE +TARGET_DEBIAN_FALSE +TARGET_DEBIAN_TRUE +TARGET_SUSE_FALSE +TARGET_SUSE_TRUE +TARGET_FEDORA_FALSE +TARGET_FEDORA_TRUE +M4_DEFINES +SYSTEM_SYSVRCND_PATH +SYSTEM_SYSVINIT_PATH +M4 +HAVE_XSLTPROC_FALSE +HAVE_XSLTPROC_TRUE +XSLTPROC +HAVE_VALAC_FALSE +HAVE_VALAC_TRUE +VAPIDIR +VALAC +LIBNOTIFY_LIBS +LIBNOTIFY_CFLAGS +HAVE_GTK_FALSE +HAVE_GTK_TRUE +GTK_LIBS +GTK_CFLAGS +ENABLE_MANPAGES_FALSE +ENABLE_MANPAGES_TRUE +ENABLE_COREDUMP_FALSE +ENABLE_COREDUMP_TRUE +ENABLE_LOCALED_FALSE +ENABLE_LOCALED_TRUE +ENABLE_TIMEDATED_FALSE +ENABLE_TIMEDATED_TRUE +ENABLE_HOSTNAMED_FALSE +ENABLE_HOSTNAMED_TRUE +ENABLE_LOGIND_FALSE +ENABLE_LOGIND_TRUE +ENABLE_RANDOMSEED_FALSE +ENABLE_RANDOMSEED_TRUE +ENABLE_QUOTACHECK_FALSE +ENABLE_QUOTACHECK_TRUE +ENABLE_READAHEAD_FALSE +ENABLE_READAHEAD_TRUE +ENABLE_VCONSOLE_FALSE +ENABLE_VCONSOLE_TRUE +ENABLE_BINFMT_FALSE +ENABLE_BINFMT_TRUE +HAVE_LIBCRYPTSETUP_FALSE +HAVE_LIBCRYPTSETUP_TRUE +LIBCRYPTSETUP_LIBS +LIBCRYPTSETUP_CFLAGS +AUDIT_LIBS +HAVE_ACL_FALSE +HAVE_ACL_TRUE +ACL_LIBS +HAVE_PAM_FALSE +HAVE_PAM_TRUE +PAM_LIBS +LIBWRAP_LIBS +HAVE_XZ_FALSE +HAVE_XZ_TRUE +XZ_LIBS +XZ_CFLAGS +HAVE_SELINUX_FALSE +HAVE_SELINUX_TRUE +SELINUX_LIBS +SELINUX_CFLAGS +KMOD_LIBS +KMOD_CFLAGS +DBUS_LIBS +DBUS_CFLAGS +UDEV_LIBS +UDEV_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG +CAP_LIBS +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +LIBTOOL +GPERF +STRINGS +OBJCOPY +SED +LN_S +GETTEXT_PACKAGE +DATADIRNAME +ALL_LINGUAS +INTLTOOL_PERL +GMSGFMT +MSGFMT +MSGMERGE +XGETTEXT +INTLTOOL_POLICY_RULE +INTLTOOL_SERVICE_RULE +INTLTOOL_THEME_RULE +INTLTOOL_SCHEMAS_RULE +INTLTOOL_CAVES_RULE +INTLTOOL_XML_NOMERGE_RULE +INTLTOOL_XML_RULE +INTLTOOL_KBD_RULE +INTLTOOL_XAM_RULE +INTLTOOL_UI_RULE +INTLTOOL_SOUNDLIST_RULE +INTLTOOL_SHEET_RULE +INTLTOOL_SERVER_RULE +INTLTOOL_PONG_RULE +INTLTOOL_OAF_RULE +INTLTOOL_PROP_RULE +INTLTOOL_KEYS_RULE +INTLTOOL_DIRECTORY_RULE +INTLTOOL_DESKTOP_RULE +INTLTOOL_EXTRACT +INTLTOOL_MERGE +INTLTOOL_UPDATE +USE_NLS +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_largefile +enable_dependency_tracking +enable_silent_rules +enable_nls +enable_shared +enable_static +with_pic +enable_fast_install +with_gnu_ld +with_sysroot +enable_libtool_lock +enable_selinux +enable_xz +enable_tcpwrap +enable_pam +enable_acl +enable_audit +enable_libcryptsetup +enable_binfmt +enable_vconsole +enable_readahead +enable_quotacheck +enable_randomseed +enable_logind +enable_hostnamed +enable_timedated +enable_localed +enable_coredump +enable_manpages +enable_gtk +with_distro +with_sysvinit_path +with_sysvrcd_path +with_tty_gid +enable_plymouth +with_dbuspolicydir +with_dbussessionservicedir +with_dbussystemservicedir +with_dbusinterfacedir +with_udevrulesdir +with_rootprefix +with_rootlibdir +with_pamlibdir +enable_split_usr +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +UDEV_CFLAGS +UDEV_LIBS +DBUS_CFLAGS +DBUS_LIBS +KMOD_CFLAGS +KMOD_LIBS +SELINUX_CFLAGS +SELINUX_LIBS +XZ_CFLAGS +XZ_LIBS +LIBCRYPTSETUP_CFLAGS +LIBCRYPTSETUP_LIBS +GTK_CFLAGS +GTK_LIBS +LIBNOTIFY_CFLAGS +LIBNOTIFY_LIBS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures systemd 43 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/systemd] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of systemd 43:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-largefile omit support for large files + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --enable-silent-rules less verbose build output (undo: `make V=1') + --disable-silent-rules verbose build output (undo: `make V=0') + --disable-nls do not use Native Language Support + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --disable-selinux Disable optional SELINUX support + --disable-xz Disable optional XZ support + --disable-tcpwrap Disable optional TCP wrappers support + --disable-pam Disable optional PAM support + --disable-acl Disable optional ACL support + --disable-audit Disable optional AUDIT support + --disable-libcryptsetup disable libcryptsetup tools + --disable-binfmt disable binfmt tool + --disable-vconsole disable vconsole tool + --disable-readahead disable readahead tools + --disable-quotacheck disable quotacheck tools + --disable-randomseed disable randomseed tools + --disable-logind disable login daemon + --disable-hostnamed disable hostname daemon + --disable-timedated disable timedate daemon + --disable-localed disable locale daemon + --disable-coredump disable coredump hook + --disable-manpages disable manpages + --disable-gtk disable GTK tools + --enable-plymouth enable plymouth support + --enable-split-usr Assume that /bin, /sbin aren\'t symlinks into /usr + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + --with-distro=DISTRO Specify the distribution to target: One of fedora, + suse, debian, ubuntu, arch, gentoo, slackware, + altlinuxi, mandriva, meego, mageia, angstrom or + other + --with-sysvinit-path=PATH + Specify the path to where the SysV init scripts are + located [default=based on distro] + --with-sysvrcd-path=PATH + Specify the path to the base directory for the SysV + rcN.d directories [default=based on distro] + --with-tty-gid=GID Specify the numeric GID of the 'tty' group + --with-dbuspolicydir=DIR + D-Bus policy directory + --with-dbussessionservicedir=DIR + D-Bus session service directory + --with-dbussystemservicedir=DIR + D-Bus system service directory + --with-dbusinterfacedir=DIR + D-Bus interface directory + --with-udevrulesdir=DIR Directory for udev rules + --with-rootprefix=DIR rootfs directory prefix for config files and kernel + modules + --with-rootlibdir=DIR Root directory for libraries necessary for boot + --with-pamlibdir=DIR Directory for PAM modules + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + UDEV_CFLAGS C compiler flags for UDEV, overriding pkg-config + UDEV_LIBS linker flags for UDEV, overriding pkg-config + DBUS_CFLAGS C compiler flags for DBUS, overriding pkg-config + DBUS_LIBS linker flags for DBUS, overriding pkg-config + KMOD_CFLAGS C compiler flags for KMOD, overriding pkg-config + KMOD_LIBS linker flags for KMOD, overriding pkg-config + SELINUX_CFLAGS + C compiler flags for SELINUX, overriding pkg-config + SELINUX_LIBS + linker flags for SELINUX, overriding pkg-config + XZ_CFLAGS C compiler flags for XZ, overriding pkg-config + XZ_LIBS linker flags for XZ, overriding pkg-config + LIBCRYPTSETUP_CFLAGS + C compiler flags for LIBCRYPTSETUP, overriding pkg-config + LIBCRYPTSETUP_LIBS + linker flags for LIBCRYPTSETUP, overriding pkg-config + GTK_CFLAGS C compiler flags for GTK, overriding pkg-config + GTK_LIBS linker flags for GTK, overriding pkg-config + LIBNOTIFY_CFLAGS + C compiler flags for LIBNOTIFY, overriding pkg-config + LIBNOTIFY_LIBS + linker flags for LIBNOTIFY, overriding pkg-config + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +systemd configure 43 +generated by GNU Autoconf 2.68 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## -------------------------------------------------- ## +## Report this to systemd-devel@lists.freedesktop.org ## +## -------------------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by systemd $as_me 43, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_config_headers="$ac_config_headers config.h" + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = xyes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if ${ac_cv_safe_to_define___extensions__+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if ${ac_cv_sys_largefile_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if ${ac_cv_sys_file_offset_bits+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if ${ac_cv_sys_large_files+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi +fi + + +am__api_version='1.11' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in +yes) AM_DEFAULT_VERBOSITY=0;; +no) AM_DEFAULT_VERBOSITY=1;; +*) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='systemd' + VERSION='43' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to create a pax tar archive" >&5 +$as_echo_n "checking how to create a pax tar archive... " >&6; } +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' +_am_tools=${am_cv_prog_tar_pax-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + { echo "$as_me:$LINENO: $_am_tar --version" >&5 + ($_am_tar --version) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && break + done + am__tar="$_am_tar --format=posix -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=posix -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x pax -w "$$tardir"' + am__tar_='pax -L -x pax -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H pax -L' + am__tar_='find "$tardir" -print | cpio -o -H pax -L' + am__untar='cpio -i -H pax -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_pax}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + { echo "$as_me:$LINENO: tardir=conftest.dir && eval $am__tar_ >conftest.tar" >&5 + (tardir=conftest.dir && eval $am__tar_ >conftest.tar) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + rm -rf conftest.dir + if test -s conftest.tar; then + { echo "$as_me:$LINENO: $am__untar &5 + ($am__untar &5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +if ${am_cv_prog_tar_pax+:} false; then : + $as_echo_n "(cached) " >&6 +else + am_cv_prog_tar_pax=$_am_tool +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_pax" >&5 +$as_echo "$am_cv_prog_tar_pax" >&6; } + + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + + +PACKAGE_URL=http://www.freedesktop.org/wiki/Software/systemd + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +cat >>confdefs.h <<_ACEOF +#define CANONICAL_HOST "$host" +_ACEOF + +if test "x$host_cpu" = "xmips" || test "x$host_cpu" = "xmipsel" || + test "x$host_cpu" = "xmips64" || test "x$host_cpu" = "xmips64el"; then : + +$as_echo "#define ARCH_MIPS /**/" >>confdefs.h + +fi + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in +yes) AM_DEFAULT_VERBOSITY=0;; +no) AM_DEFAULT_VERBOSITY=1;; +*) AM_DEFAULT_VERBOSITY=0;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + + +# i18n stuff for the PolicyKit policy files + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 +$as_echo_n "checking whether NLS is requested... " >&6; } + # Check whether --enable-nls was given. +if test "${enable_nls+set}" = set; then : + enableval=$enable_nls; USE_NLS=$enableval +else + USE_NLS=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 +$as_echo "$USE_NLS" >&6; } + + + + +case "$am__api_version" in + 1.01234) + as_fn_error $? "Automake 1.5 or newer is required to use intltool" "$LINENO" 5 + ;; + *) + ;; +esac + +if test -n "0.40.0"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intltool >= 0.40.0" >&5 +$as_echo_n "checking for intltool >= 0.40.0... " >&6; } + + INTLTOOL_REQUIRED_VERSION_AS_INT=`echo 0.40.0 | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'` + INTLTOOL_APPLIED_VERSION=`intltool-update --version | head -1 | cut -d" " -f3` + INTLTOOL_APPLIED_VERSION_AS_INT=`echo $INTLTOOL_APPLIED_VERSION | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'` + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_APPLIED_VERSION found" >&5 +$as_echo "$INTLTOOL_APPLIED_VERSION found" >&6; } + test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT" || + as_fn_error $? "Your intltool is too old. You need intltool 0.40.0 or later." "$LINENO" 5 +fi + +# Extract the first word of "intltool-update", so it can be a program name with args. +set dummy intltool-update; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_INTLTOOL_UPDATE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $INTLTOOL_UPDATE in + [\\/]* | ?:[\\/]*) + ac_cv_path_INTLTOOL_UPDATE="$INTLTOOL_UPDATE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_INTLTOOL_UPDATE="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +INTLTOOL_UPDATE=$ac_cv_path_INTLTOOL_UPDATE +if test -n "$INTLTOOL_UPDATE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_UPDATE" >&5 +$as_echo "$INTLTOOL_UPDATE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "intltool-merge", so it can be a program name with args. +set dummy intltool-merge; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_INTLTOOL_MERGE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $INTLTOOL_MERGE in + [\\/]* | ?:[\\/]*) + ac_cv_path_INTLTOOL_MERGE="$INTLTOOL_MERGE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_INTLTOOL_MERGE="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +INTLTOOL_MERGE=$ac_cv_path_INTLTOOL_MERGE +if test -n "$INTLTOOL_MERGE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_MERGE" >&5 +$as_echo "$INTLTOOL_MERGE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "intltool-extract", so it can be a program name with args. +set dummy intltool-extract; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_INTLTOOL_EXTRACT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $INTLTOOL_EXTRACT in + [\\/]* | ?:[\\/]*) + ac_cv_path_INTLTOOL_EXTRACT="$INTLTOOL_EXTRACT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_INTLTOOL_EXTRACT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +INTLTOOL_EXTRACT=$ac_cv_path_INTLTOOL_EXTRACT +if test -n "$INTLTOOL_EXTRACT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_EXTRACT" >&5 +$as_echo "$INTLTOOL_EXTRACT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test -z "$INTLTOOL_UPDATE" -o -z "$INTLTOOL_MERGE" -o -z "$INTLTOOL_EXTRACT"; then + as_fn_error $? "The intltool scripts were not found. Please install intltool." "$LINENO" 5 +fi + + INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' +INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -p $(top_srcdir)/po $< $@' + INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' +INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u --no-translations $< $@' + INTLTOOL_XAM_RULE='%.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + INTLTOOL_KBD_RULE='%.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + INTLTOOL_SERVICE_RULE='%.service: %.service.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + INTLTOOL_POLICY_RULE='%.policy: %.policy.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# Check the gettext tools to make sure they are GNU +# Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_XGETTEXT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $XGETTEXT in + [\\/]* | ?:[\\/]*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_XGETTEXT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +XGETTEXT=$ac_cv_path_XGETTEXT +if test -n "$XGETTEXT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 +$as_echo "$XGETTEXT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "msgmerge", so it can be a program name with args. +set dummy msgmerge; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MSGMERGE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MSGMERGE in + [\\/]* | ?:[\\/]*) + ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_MSGMERGE="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +MSGMERGE=$ac_cv_path_MSGMERGE +if test -n "$MSGMERGE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5 +$as_echo "$MSGMERGE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MSGFMT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MSGFMT in + [\\/]* | ?:[\\/]*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_MSGFMT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +MSGFMT=$ac_cv_path_MSGFMT +if test -n "$MSGFMT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 +$as_echo "$MSGFMT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +# Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_GMSGFMT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $GMSGFMT in + [\\/]* | ?:[\\/]*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT=$ac_cv_path_GMSGFMT +if test -n "$GMSGFMT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 +$as_echo "$GMSGFMT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test -z "$XGETTEXT" -o -z "$MSGMERGE" -o -z "$MSGFMT"; then + as_fn_error $? "GNU gettext tools not found; required for intltool" "$LINENO" 5 +fi +xgversion="`$XGETTEXT --version|grep '(GNU ' 2> /dev/null`" +mmversion="`$MSGMERGE --version|grep '(GNU ' 2> /dev/null`" +mfversion="`$MSGFMT --version|grep '(GNU ' 2> /dev/null`" +if test -z "$xgversion" -o -z "$mmversion" -o -z "$mfversion"; then + as_fn_error $? "GNU gettext tools not found; required for intltool" "$LINENO" 5 +fi + +# Extract the first word of "perl", so it can be a program name with args. +set dummy perl; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_INTLTOOL_PERL+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $INTLTOOL_PERL in + [\\/]* | ?:[\\/]*) + ac_cv_path_INTLTOOL_PERL="$INTLTOOL_PERL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_INTLTOOL_PERL="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +INTLTOOL_PERL=$ac_cv_path_INTLTOOL_PERL +if test -n "$INTLTOOL_PERL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_PERL" >&5 +$as_echo "$INTLTOOL_PERL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test -z "$INTLTOOL_PERL"; then + as_fn_error $? "perl not found" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl >= 5.8.1" >&5 +$as_echo_n "checking for perl >= 5.8.1... " >&6; } +$INTLTOOL_PERL -e "use 5.8.1;" > /dev/null 2>&1 +if test $? -ne 0; then + as_fn_error $? "perl 5.8.1 is required for intltool" "$LINENO" 5 +else + IT_PERL_VERSION=`$INTLTOOL_PERL -e "printf '%vd', $^V"` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IT_PERL_VERSION" >&5 +$as_echo "$IT_PERL_VERSION" >&6; } +fi +if test "x" != "xno-xml"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML::Parser" >&5 +$as_echo_n "checking for XML::Parser... " >&6; } + if `$INTLTOOL_PERL -e "require XML::Parser" 2>/dev/null`; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } + else + as_fn_error $? "XML::Parser perl module is required for intltool" "$LINENO" 5 + fi +fi + +# Substitute ALL_LINGUAS so we can use it in po/Makefile + + +# Set DATADIRNAME correctly if it is not set yet +# (copied from glib-gettext.m4) +if test -z "$DATADIRNAME"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + DATADIRNAME=share +else + case $host in + *-*-solaris*) + ac_fn_c_check_func "$LINENO" "bind_textdomain_codeset" "ac_cv_func_bind_textdomain_codeset" +if test "x$ac_cv_func_bind_textdomain_codeset" = xyes; then : + DATADIRNAME=share +else + DATADIRNAME=lib +fi + + ;; + *) + DATADIRNAME=lib + ;; + esac +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + + + + + + +GETTEXT_PACKAGE=systemd + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 +$as_echo_n "checking for $CC option to accept ISO C99... " >&6; } +if ${ac_cv_prog_cc_c99+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +#include + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +#define debug(...) fprintf (stderr, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + your preprocessor is broken; +#endif +#if BIG_OK +#else + your preprocessor is broken; +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\0'; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static void +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str; + int number; + float fnumber; + + while (*format) + { + switch (*format++) + { + case 's': // string + str = va_arg (args_copy, const char *); + break; + case 'd': // int + number = va_arg (args_copy, int); + break; + case 'f': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); +} + +int +main () +{ + + // Check bool. + _Bool success = false; + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + test_varargs ("s, d' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' + || dynamic_array[ni.number - 1] != 543); + + ; + return 0; +} +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -xc99=all -qlanglvl=extc99 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c99" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c99" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +$as_echo "$ac_cv_prog_cc_c99" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c99" != xno; then : + +fi + + +if test "x$CC" != xcc; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 +$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 +$as_echo_n "checking whether cc understands -c and -o together... " >&6; } +fi +set dummy $CC; ac_cc=`$as_echo "$2" | + sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +# Make sure it works both with $CC and with simple cc. +# We do the test twice because some compilers refuse to overwrite an +# existing .o file with -o, though they will create one. +ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +rm -f conftest2.* +if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; +then + eval ac_cv_prog_cc_${ac_cc}_c_o=yes + if test "x$CC" != xcc; then + # Test first that cc exists at all. + if { ac_try='cc -c conftest.$ac_ext >&5' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' + rm -f conftest2.* + if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; + then + # cc works too. + : + else + # cc exists but doesn't like -o. + eval ac_cv_prog_cc_${ac_cc}_c_o=no + fi + fi + fi +else + eval ac_cv_prog_cc_${ac_cc}_c_o=no +fi +rm -f core conftest* + +fi +if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h + +fi + +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi + + +if test $ac_cv_c_compiler_gnu = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 +$as_echo_n "checking whether $CC needs -traditional... " >&6; } +if ${ac_cv_prog_gcc_traditional+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_pattern="Autoconf.*'x'" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +Autoconf TIOCGETP +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then : + ac_cv_prog_gcc_traditional=yes +else + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +Autoconf TCGETA +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then : + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 +$as_echo "$ac_cv_prog_gcc_traditional" >&6; } + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args. +set dummy ${ac_tool_prefix}objcopy; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJCOPY+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJCOPY"; then + ac_cv_prog_OBJCOPY="$OBJCOPY" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJCOPY="${ac_tool_prefix}objcopy" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJCOPY=$ac_cv_prog_OBJCOPY +if test -n "$OBJCOPY"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJCOPY" >&5 +$as_echo "$OBJCOPY" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJCOPY"; then + ac_ct_OBJCOPY=$OBJCOPY + # Extract the first word of "objcopy", so it can be a program name with args. +set dummy objcopy; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJCOPY+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJCOPY"; then + ac_cv_prog_ac_ct_OBJCOPY="$ac_ct_OBJCOPY" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJCOPY="objcopy" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJCOPY=$ac_cv_prog_ac_ct_OBJCOPY +if test -n "$ac_ct_OBJCOPY"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJCOPY" >&5 +$as_echo "$ac_ct_OBJCOPY" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJCOPY" = x; then + OBJCOPY="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJCOPY=$ac_ct_OBJCOPY + fi +else + OBJCOPY="$ac_cv_prog_OBJCOPY" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strings", so it can be a program name with args. +set dummy ${ac_tool_prefix}strings; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRINGS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRINGS"; then + ac_cv_prog_STRINGS="$STRINGS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRINGS="${ac_tool_prefix}strings" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRINGS=$ac_cv_prog_STRINGS +if test -n "$STRINGS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRINGS" >&5 +$as_echo "$STRINGS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRINGS"; then + ac_ct_STRINGS=$STRINGS + # Extract the first word of "strings", so it can be a program name with args. +set dummy strings; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRINGS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRINGS"; then + ac_cv_prog_ac_ct_STRINGS="$ac_ct_STRINGS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRINGS="strings" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRINGS=$ac_cv_prog_ac_ct_STRINGS +if test -n "$ac_ct_STRINGS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRINGS" >&5 +$as_echo "$ac_ct_STRINGS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRINGS" = x; then + STRINGS="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRINGS=$ac_ct_STRINGS + fi +else + STRINGS="$ac_cv_prog_STRINGS" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gperf", so it can be a program name with args. +set dummy ${ac_tool_prefix}gperf; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_GPERF+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$GPERF"; then + ac_cv_prog_GPERF="$GPERF" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_GPERF="${ac_tool_prefix}gperf" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +GPERF=$ac_cv_prog_GPERF +if test -n "$GPERF"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GPERF" >&5 +$as_echo "$GPERF" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_GPERF"; then + ac_ct_GPERF=$GPERF + # Extract the first word of "gperf", so it can be a program name with args. +set dummy gperf; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_GPERF+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_GPERF"; then + ac_cv_prog_ac_ct_GPERF="$ac_ct_GPERF" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_GPERF="gperf" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_GPERF=$ac_cv_prog_ac_ct_GPERF +if test -n "$ac_ct_GPERF"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_GPERF" >&5 +$as_echo "$ac_ct_GPERF" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_GPERF" = x; then + GPERF="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + GPERF=$ac_ct_GPERF + fi +else + GPERF="$ac_cv_prog_GPERF" +fi + +if test -z "$GPERF" ; then + as_fn_error $? "*** gperf not found" "$LINENO" 5 +fi + + + for flag in \ + -pipe \ + -Wall \ + -W \ + -Wextra \ + -Wno-inline \ + -Wvla \ + -Wundef \ + -Wformat=2 \ + -Wlogical-op \ + -Wsign-compare \ + -Wformat-security \ + -Wmissing-include-dirs \ + -Wformat-nonliteral \ + -Wold-style-definition \ + -Wpointer-arith \ + -Winit-self \ + -Wdeclaration-after-statement \ + -Wfloat-equal \ + -Wmissing-prototypes \ + -Wstrict-prototypes \ + -Wredundant-decls \ + -Wmissing-declarations \ + -Wmissing-noreturn \ + -Wshadow \ + -Wendif-labels \ + -Wcast-align \ + -Wstrict-aliasing=2 \ + -Wwrite-strings \ + -Wno-long-long \ + -Wno-overlength-strings \ + -Wno-unused-parameter \ + -Wno-missing-field-initializers \ + -Wno-unused-result \ + -Werror=overflow \ + -Wp,-D_FORTIFY_SOURCE=2 \ + -ffast-math \ + -fno-common \ + -fdiagnostics-show-option \ + -fno-strict-aliasing \ + -fvisibility=hidden \ + -ffunction-sections \ + -fdata-sections \ + -Wl,--as-needed \ + -Wl,--gc-sections; do + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports $flag flag" >&5 +$as_echo_n "checking if $CC supports $flag flag... " >&6; } +if { as_var=`$as_echo "cc_cv_cflags_$flag" | $as_tr_sh`; eval \${$as_var+:} false; }; then : + $as_echo_n "(cached) " >&6 +else + + if { as_var=`$as_echo "cc_cv_cflags_$flag" | $as_tr_sh`; eval \${$as_var+:} false; }; then : + $as_echo_n "(cached) " >&6 +else + ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $flag" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int a; +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "`$as_echo "cc_cv_cflags_$flag" | $as_tr_sh`='yes'" +else + eval "`$as_echo "cc_cv_cflags_$flag" | $as_tr_sh`='no'" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$ac_save_CFLAGS" + +fi + + + if eval test x$`$as_echo "cc_cv_cflags_$flag" | $as_tr_sh` = xyes; then : + +fi + +fi +eval ac_res=\$`$as_echo "cc_cv_cflags_$flag" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + + if eval test x$`$as_echo "cc_cv_cflags_$flag" | $as_tr_sh` = xyes; then : + CFLAGS="$CFLAGS $flag"; DEBUG_CFLAGS="$DEBUG_CFLAGS $flag"; +fi + + done + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.2' +macro_revision='1.3337' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Add ABI-specific directories to the system library path. + sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC="$lt_save_CC" + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 +$as_echo_n "checking for library containing clock_gettime... " >&6; } +if ${ac_cv_search_clock_gettime+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char clock_gettime (); +int +main () +{ +return clock_gettime (); + ; + return 0; +} +_ACEOF +for ac_lib in '' rt; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_clock_gettime=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_clock_gettime+:} false; then : + break +fi +done +if ${ac_cv_search_clock_gettime+:} false; then : + +else + ac_cv_search_clock_gettime=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 +$as_echo "$ac_cv_search_clock_gettime" >&6; } +ac_res=$ac_cv_search_clock_gettime +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + as_fn_error $? "*** POSIX RT library not found" "$LINENO" 5 +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlsym" >&5 +$as_echo_n "checking for library containing dlsym... " >&6; } +if ${ac_cv_search_dlsym+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlsym (); +int +main () +{ +return dlsym (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_dlsym=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_dlsym+:} false; then : + break +fi +done +if ${ac_cv_search_dlsym+:} false; then : + +else + ac_cv_search_dlsym=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlsym" >&5 +$as_echo "$ac_cv_search_dlsym" >&6; } +ac_res=$ac_cv_search_dlsym +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + as_fn_error $? "*** Dynamic linking loader library not found" "$LINENO" 5 +fi + + +save_LIBS="$LIBS" +LIBS= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing cap_init" >&5 +$as_echo_n "checking for library containing cap_init... " >&6; } +if ${ac_cv_search_cap_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char cap_init (); +int +main () +{ +return cap_init (); + ; + return 0; +} +_ACEOF +for ac_lib in '' cap; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_cap_init=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_cap_init+:} false; then : + break +fi +done +if ${ac_cv_search_cap_init+:} false; then : + +else + ac_cv_search_cap_init=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_cap_init" >&5 +$as_echo "$ac_cv_search_cap_init" >&6; } +ac_res=$ac_cv_search_cap_init +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + as_fn_error $? "*** POSIX caps library not found" "$LINENO" 5 +fi + +for ac_header in sys/capability.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/capability.h" "ac_cv_header_sys_capability_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_capability_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_CAPABILITY_H 1 +_ACEOF + +else + as_fn_error $? "*** POSIX caps headers not found" "$LINENO" 5 +fi + +done + +CAP_LIBS="$LIBS" +LIBS="$save_LIBS" + + +# This makes sure pkg.m4 is available. + + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for UDEV" >&5 +$as_echo_n "checking for UDEV... " >&6; } + +if test -n "$UDEV_CFLAGS"; then + pkg_cv_UDEV_CFLAGS="$UDEV_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" libudev >= 172 \""; } >&5 + ($PKG_CONFIG --exists --print-errors " libudev >= 172 ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_UDEV_CFLAGS=`$PKG_CONFIG --cflags " libudev >= 172 " 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$UDEV_LIBS"; then + pkg_cv_UDEV_LIBS="$UDEV_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" libudev >= 172 \""; } >&5 + ($PKG_CONFIG --exists --print-errors " libudev >= 172 ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_UDEV_LIBS=`$PKG_CONFIG --libs " libudev >= 172 " 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + UDEV_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors " libudev >= 172 " 2>&1` + else + UDEV_PKG_ERRORS=`$PKG_CONFIG --print-errors " libudev >= 172 " 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$UDEV_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements ( libudev >= 172 ) were not met: + +$UDEV_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables UDEV_CFLAGS +and UDEV_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables UDEV_CFLAGS +and UDEV_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } + +else + UDEV_CFLAGS=$pkg_cv_UDEV_CFLAGS + UDEV_LIBS=$pkg_cv_UDEV_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DBUS" >&5 +$as_echo_n "checking for DBUS... " >&6; } + +if test -n "$DBUS_CFLAGS"; then + pkg_cv_DBUS_CFLAGS="$DBUS_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" dbus-1 >= 1.3.2 \""; } >&5 + ($PKG_CONFIG --exists --print-errors " dbus-1 >= 1.3.2 ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_DBUS_CFLAGS=`$PKG_CONFIG --cflags " dbus-1 >= 1.3.2 " 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$DBUS_LIBS"; then + pkg_cv_DBUS_LIBS="$DBUS_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" dbus-1 >= 1.3.2 \""; } >&5 + ($PKG_CONFIG --exists --print-errors " dbus-1 >= 1.3.2 ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_DBUS_LIBS=`$PKG_CONFIG --libs " dbus-1 >= 1.3.2 " 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + DBUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors " dbus-1 >= 1.3.2 " 2>&1` + else + DBUS_PKG_ERRORS=`$PKG_CONFIG --print-errors " dbus-1 >= 1.3.2 " 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$DBUS_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements ( dbus-1 >= 1.3.2 ) were not met: + +$DBUS_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables DBUS_CFLAGS +and DBUS_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables DBUS_CFLAGS +and DBUS_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } + +else + DBUS_CFLAGS=$pkg_cv_DBUS_CFLAGS + DBUS_LIBS=$pkg_cv_DBUS_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for KMOD" >&5 +$as_echo_n "checking for KMOD... " >&6; } + +if test -n "$KMOD_CFLAGS"; then + pkg_cv_KMOD_CFLAGS="$KMOD_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" libkmod >= 5 \""; } >&5 + ($PKG_CONFIG --exists --print-errors " libkmod >= 5 ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_KMOD_CFLAGS=`$PKG_CONFIG --cflags " libkmod >= 5 " 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$KMOD_LIBS"; then + pkg_cv_KMOD_LIBS="$KMOD_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" libkmod >= 5 \""; } >&5 + ($PKG_CONFIG --exists --print-errors " libkmod >= 5 ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_KMOD_LIBS=`$PKG_CONFIG --libs " libkmod >= 5 " 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + KMOD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors " libkmod >= 5 " 2>&1` + else + KMOD_PKG_ERRORS=`$PKG_CONFIG --print-errors " libkmod >= 5 " 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$KMOD_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements ( libkmod >= 5 ) were not met: + +$KMOD_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables KMOD_CFLAGS +and KMOD_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables KMOD_CFLAGS +and KMOD_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } + +else + KMOD_CFLAGS=$pkg_cv_KMOD_CFLAGS + KMOD_LIBS=$pkg_cv_KMOD_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +have_selinux=no +# Check whether --enable-selinux was given. +if test "${enable_selinux+set}" = set; then : + enableval=$enable_selinux; +fi + +if test "x$enable_selinux" != "xno"; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SELINUX" >&5 +$as_echo_n "checking for SELINUX... " >&6; } + +if test -n "$SELINUX_CFLAGS"; then + pkg_cv_SELINUX_CFLAGS="$SELINUX_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" libselinux \""; } >&5 + ($PKG_CONFIG --exists --print-errors " libselinux ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_SELINUX_CFLAGS=`$PKG_CONFIG --cflags " libselinux " 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$SELINUX_LIBS"; then + pkg_cv_SELINUX_LIBS="$SELINUX_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" libselinux \""; } >&5 + ($PKG_CONFIG --exists --print-errors " libselinux ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_SELINUX_LIBS=`$PKG_CONFIG --libs " libselinux " 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + SELINUX_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors " libselinux " 2>&1` + else + SELINUX_PKG_ERRORS=`$PKG_CONFIG --print-errors " libselinux " 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$SELINUX_PKG_ERRORS" >&5 + + have_selinux=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_selinux=no +else + SELINUX_CFLAGS=$pkg_cv_SELINUX_CFLAGS + SELINUX_LIBS=$pkg_cv_SELINUX_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_SELINUX 1" >>confdefs.h + have_selinux=yes +fi + if test "x$have_selinux" = xno -a "x$enable_selinux" = xyes; then + as_fn_error $? "*** SELinux support requested but libraries not found" "$LINENO" 5 + fi +fi + if test "$have_selinux" = "yes"; then + HAVE_SELINUX_TRUE= + HAVE_SELINUX_FALSE='#' +else + HAVE_SELINUX_TRUE='#' + HAVE_SELINUX_FALSE= +fi + + +have_xz=no +# Check whether --enable-xz was given. +if test "${enable_xz+set}" = set; then : + enableval=$enable_xz; +fi + +if test "x$enable_xz" != "xno"; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XZ" >&5 +$as_echo_n "checking for XZ... " >&6; } + +if test -n "$XZ_CFLAGS"; then + pkg_cv_XZ_CFLAGS="$XZ_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" liblzma \""; } >&5 + ($PKG_CONFIG --exists --print-errors " liblzma ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_XZ_CFLAGS=`$PKG_CONFIG --cflags " liblzma " 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$XZ_LIBS"; then + pkg_cv_XZ_LIBS="$XZ_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" liblzma \""; } >&5 + ($PKG_CONFIG --exists --print-errors " liblzma ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_XZ_LIBS=`$PKG_CONFIG --libs " liblzma " 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + XZ_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors " liblzma " 2>&1` + else + XZ_PKG_ERRORS=`$PKG_CONFIG --print-errors " liblzma " 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$XZ_PKG_ERRORS" >&5 + + have_xz=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_xz=no +else + XZ_CFLAGS=$pkg_cv_XZ_CFLAGS + XZ_LIBS=$pkg_cv_XZ_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_XZ 1" >>confdefs.h + have_xz=yes +fi + if test "x$have_xz" = xno -a "x$enable_xz" = xyes; then + as_fn_error $? "*** Xz support requested but libraries not found" "$LINENO" 5 + fi +fi + if test "$have_xz" = "yes"; then + HAVE_XZ_TRUE= + HAVE_XZ_FALSE='#' +else + HAVE_XZ_TRUE='#' + HAVE_XZ_FALSE= +fi + + +# Check whether --enable-tcpwrap was given. +if test "${enable_tcpwrap+set}" = set; then : + enableval=$enable_tcpwrap; case "${enableval}" in + yes) have_tcpwrap=yes ;; + no) have_tcpwrap=no ;; + *) as_fn_error $? "bad value ${enableval} for --disable-tcpwrap" "$LINENO" 5 ;; + esac +else + have_tcpwrap=auto +fi + + +if test "x${have_tcpwrap}" != xno ; then + +LIBWRAP_LIBS= +saved_LIBS="$LIBS" +LIBS="$LIBS -lwrap" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tcpwrap library and headers" >&5 +$as_echo_n "checking for tcpwrap library and headers... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +int allow_severity = LOG_INFO; +int deny_severity = LOG_WARNING; +int +main () +{ +struct request_info *req; +return hosts_access (req); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +$as_echo "#define HAVE_LIBWRAP /**/" >>confdefs.h + +LIBWRAP_LIBS="-lwrap" +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$saved_LIBS" + + if test "x${LIBWRAP_LIBS}" = x ; then + if test "x$have_tcpwrap" = xyes ; then + as_fn_error $? "*** TCP wrappers support not found." "$LINENO" 5 + fi + have_tcpwrap=no + else + have_tcpwrap=yes + fi +else + LIBWRAP_LIBS= +fi + + +# Check whether --enable-pam was given. +if test "${enable_pam+set}" = set; then : + enableval=$enable_pam; case "${enableval}" in + yes) have_pam=yes ;; + no) have_pam=no ;; + *) as_fn_error $? "bad value ${enableval} for --disable-pam" "$LINENO" 5 ;; + esac +else + have_pam=auto +fi + + +if test "x${have_pam}" != xno ; then + for ac_header in security/pam_modules.h security/pam_modutil.h security/pam_ext.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + have_pam=yes +else + if test "x$have_pam" = xyes ; then + as_fn_error $? "*** PAM headers not found." "$LINENO" 5 + fi +fi + +done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pam_syslog in -lpam" >&5 +$as_echo_n "checking for pam_syslog in -lpam... " >&6; } +if ${ac_cv_lib_pam_pam_syslog+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpam $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pam_syslog (); +int +main () +{ +return pam_syslog (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_pam_pam_syslog=yes +else + ac_cv_lib_pam_pam_syslog=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pam_pam_syslog" >&5 +$as_echo "$ac_cv_lib_pam_pam_syslog" >&6; } +if test "x$ac_cv_lib_pam_pam_syslog" = xyes; then : + have_pam=yes +else + if test "x$have_pam" = xyes ; then + as_fn_error $? "*** libpam not found." "$LINENO" 5 + fi +fi + + + if test "x$have_pam" = xyes ; then + PAM_LIBS="-lpam -lpam_misc" + +$as_echo "#define HAVE_PAM 1" >>confdefs.h + + else + have_pam=no + fi +else + PAM_LIBS= +fi + + if test "x$have_pam" != xno; then + HAVE_PAM_TRUE= + HAVE_PAM_FALSE='#' +else + HAVE_PAM_TRUE='#' + HAVE_PAM_FALSE= +fi + + +# Check whether --enable-acl was given. +if test "${enable_acl+set}" = set; then : + enableval=$enable_acl; case "${enableval}" in + yes) have_acl=yes ;; + no) have_acl=no ;; + *) as_fn_error $? "bad value ${enableval} for --disable-acl" "$LINENO" 5 ;; + esac +else + have_acl=auto +fi + + +if test "x${have_acl}" != xno ; then + for ac_header in sys/acl.h acl/libacl.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + have_acl=yes +else + if test "x$have_acl" = xyes ; then + as_fn_error $? "*** ACL headers not found." "$LINENO" 5 + fi +fi + +done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for acl_get_file in -lacl" >&5 +$as_echo_n "checking for acl_get_file in -lacl... " >&6; } +if ${ac_cv_lib_acl_acl_get_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lacl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char acl_get_file (); +int +main () +{ +return acl_get_file (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_acl_acl_get_file=yes +else + ac_cv_lib_acl_acl_get_file=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_acl_acl_get_file" >&5 +$as_echo "$ac_cv_lib_acl_acl_get_file" >&6; } +if test "x$ac_cv_lib_acl_acl_get_file" = xyes; then : + have_acl=yes +else + if test "x$have_acl" = xyes ; then + as_fn_error $? "*** libacl not found." "$LINENO" 5 + fi +fi + + + if test "x$have_acl" = xyes ; then + ACL_LIBS="-lacl" + +$as_echo "#define HAVE_ACL 1" >>confdefs.h + + else + have_acl=no + fi +else + ACL_LIBS= +fi + + if test "x$have_acl" != xno; then + HAVE_ACL_TRUE= + HAVE_ACL_FALSE='#' +else + HAVE_ACL_TRUE='#' + HAVE_ACL_FALSE= +fi + + +# Check whether --enable-audit was given. +if test "${enable_audit+set}" = set; then : + enableval=$enable_audit; case "${enableval}" in + yes) have_audit=yes ;; + no) have_audit=no ;; + *) as_fn_error $? "bad value ${enableval} for --disable-audit" "$LINENO" 5 ;; + esac +else + have_audit=auto +fi + + +if test "x${have_audit}" != xno ; then + for ac_header in libaudit.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "libaudit.h" "ac_cv_header_libaudit_h" "$ac_includes_default" +if test "x$ac_cv_header_libaudit_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBAUDIT_H 1 +_ACEOF + have_audit=yes +else + if test "x$have_audit" = xyes ; then + as_fn_error $? "*** AUDIT headers not found." "$LINENO" 5 + fi +fi + +done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for audit_open in -laudit" >&5 +$as_echo_n "checking for audit_open in -laudit... " >&6; } +if ${ac_cv_lib_audit_audit_open+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-laudit $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char audit_open (); +int +main () +{ +return audit_open (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_audit_audit_open=yes +else + ac_cv_lib_audit_audit_open=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_audit_audit_open" >&5 +$as_echo "$ac_cv_lib_audit_audit_open" >&6; } +if test "x$ac_cv_lib_audit_audit_open" = xyes; then : + have_audit=yes +else + if test "x$have_audit" = xyes ; then + as_fn_error $? "*** libaudit not found." "$LINENO" 5 + fi +fi + + + if test "x$have_audit" = xyes ; then + AUDIT_LIBS="-laudit" + +$as_echo "#define HAVE_AUDIT 1" >>confdefs.h + + else + have_audit=no + fi +else + AUDIT_LIBS= +fi + + +have_libcryptsetup=no +# Check whether --enable-libcryptsetup was given. +if test "${enable_libcryptsetup+set}" = set; then : + enableval=$enable_libcryptsetup; +fi + +if test "x$enable_libcryptsetup" != "xno"; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBCRYPTSETUP" >&5 +$as_echo_n "checking for LIBCRYPTSETUP... " >&6; } + +if test -n "$LIBCRYPTSETUP_CFLAGS"; then + pkg_cv_LIBCRYPTSETUP_CFLAGS="$LIBCRYPTSETUP_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" libcryptsetup \""; } >&5 + ($PKG_CONFIG --exists --print-errors " libcryptsetup ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBCRYPTSETUP_CFLAGS=`$PKG_CONFIG --cflags " libcryptsetup " 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBCRYPTSETUP_LIBS"; then + pkg_cv_LIBCRYPTSETUP_LIBS="$LIBCRYPTSETUP_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" libcryptsetup \""; } >&5 + ($PKG_CONFIG --exists --print-errors " libcryptsetup ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBCRYPTSETUP_LIBS=`$PKG_CONFIG --libs " libcryptsetup " 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBCRYPTSETUP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors " libcryptsetup " 2>&1` + else + LIBCRYPTSETUP_PKG_ERRORS=`$PKG_CONFIG --print-errors " libcryptsetup " 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBCRYPTSETUP_PKG_ERRORS" >&5 + + have_libcryptsetup=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_libcryptsetup=no +else + LIBCRYPTSETUP_CFLAGS=$pkg_cv_LIBCRYPTSETUP_CFLAGS + LIBCRYPTSETUP_LIBS=$pkg_cv_LIBCRYPTSETUP_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_LIBCRYPTSETUP 1" >>confdefs.h + have_libcryptsetup=yes +fi + if test "x$have_libcryptsetup" = xno -a "x$enable_libcryptsetup" = xyes; then + as_fn_error $? "*** libcryptsetup support requested but libraries not found" "$LINENO" 5 + fi +fi + if test "$have_libcryptsetup" = "yes"; then + HAVE_LIBCRYPTSETUP_TRUE= + HAVE_LIBCRYPTSETUP_FALSE='#' +else + HAVE_LIBCRYPTSETUP_TRUE='#' + HAVE_LIBCRYPTSETUP_FALSE= +fi + + +have_binfmt=no +# Check whether --enable-binfmt was given. +if test "${enable_binfmt+set}" = set; then : + enableval=$enable_binfmt; +fi + +if test "x$enable_binfmt" != "xno"; then + have_binfmt=yes +fi + if test "$have_binfmt" = "yes"; then + ENABLE_BINFMT_TRUE= + ENABLE_BINFMT_FALSE='#' +else + ENABLE_BINFMT_TRUE='#' + ENABLE_BINFMT_FALSE= +fi + + +have_vconsole=no +# Check whether --enable-vconsole was given. +if test "${enable_vconsole+set}" = set; then : + enableval=$enable_vconsole; +fi + +if test "x$enable_vconsole" != "xno"; then + have_vconsole=yes +fi + if test "$have_vconsole" = "yes"; then + ENABLE_VCONSOLE_TRUE= + ENABLE_VCONSOLE_FALSE='#' +else + ENABLE_VCONSOLE_TRUE='#' + ENABLE_VCONSOLE_FALSE= +fi + + +have_readahead=no +# Check whether --enable-readahead was given. +if test "${enable_readahead+set}" = set; then : + enableval=$enable_readahead; +fi + +if test "x$enable_readahead" != "xno"; then + have_readahead=yes +fi + if test "$have_readahead" = "yes"; then + ENABLE_READAHEAD_TRUE= + ENABLE_READAHEAD_FALSE='#' +else + ENABLE_READAHEAD_TRUE='#' + ENABLE_READAHEAD_FALSE= +fi + + +have_quotacheck=no +# Check whether --enable-quotacheck was given. +if test "${enable_quotacheck+set}" = set; then : + enableval=$enable_quotacheck; +fi + +if test "x$enable_quotacheck" != "xno"; then + have_quotacheck=yes +fi + if test "$have_quotacheck" = "yes"; then + ENABLE_QUOTACHECK_TRUE= + ENABLE_QUOTACHECK_FALSE='#' +else + ENABLE_QUOTACHECK_TRUE='#' + ENABLE_QUOTACHECK_FALSE= +fi + + +have_randomseed=no +# Check whether --enable-randomseed was given. +if test "${enable_randomseed+set}" = set; then : + enableval=$enable_randomseed; +fi + +if test "x$enable_randomseed" != "xno"; then + have_randomseed=yes +fi + if test "$have_randomseed" = "yes"; then + ENABLE_RANDOMSEED_TRUE= + ENABLE_RANDOMSEED_FALSE='#' +else + ENABLE_RANDOMSEED_TRUE='#' + ENABLE_RANDOMSEED_FALSE= +fi + + +have_logind=no +# Check whether --enable-logind was given. +if test "${enable_logind+set}" = set; then : + enableval=$enable_logind; +fi + +if test "x$enable_logind" != "xno"; then + have_logind=yes +fi + if test "$have_logind" = "yes"; then + ENABLE_LOGIND_TRUE= + ENABLE_LOGIND_FALSE='#' +else + ENABLE_LOGIND_TRUE='#' + ENABLE_LOGIND_FALSE= +fi + + +have_hostnamed=no +# Check whether --enable-hostnamed was given. +if test "${enable_hostnamed+set}" = set; then : + enableval=$enable_hostnamed; +fi + +if test "x$enable_hostnamed" != "xno"; then + have_hostnamed=yes +fi + if test "$have_hostnamed" = "yes"; then + ENABLE_HOSTNAMED_TRUE= + ENABLE_HOSTNAMED_FALSE='#' +else + ENABLE_HOSTNAMED_TRUE='#' + ENABLE_HOSTNAMED_FALSE= +fi + + +have_timedated=no +# Check whether --enable-timedated was given. +if test "${enable_timedated+set}" = set; then : + enableval=$enable_timedated; +fi + +if test "x$enable_timedated" != "xno"; then + have_timedated=yes +fi + if test "$have_timedated" = "yes"; then + ENABLE_TIMEDATED_TRUE= + ENABLE_TIMEDATED_FALSE='#' +else + ENABLE_TIMEDATED_TRUE='#' + ENABLE_TIMEDATED_FALSE= +fi + + +have_localed=no +# Check whether --enable-localed was given. +if test "${enable_localed+set}" = set; then : + enableval=$enable_localed; +fi + +if test "x$enable_localed" != "xno"; then + have_localed=yes +fi + if test "$have_localed" = "yes"; then + ENABLE_LOCALED_TRUE= + ENABLE_LOCALED_FALSE='#' +else + ENABLE_LOCALED_TRUE='#' + ENABLE_LOCALED_FALSE= +fi + + +have_coredump=no +# Check whether --enable-coredump was given. +if test "${enable_coredump+set}" = set; then : + enableval=$enable_coredump; +fi + +if test "x$enable_coredump" != "xno"; then + have_coredump=yes +fi + if test "$have_coredump" = "yes"; then + ENABLE_COREDUMP_TRUE= + ENABLE_COREDUMP_FALSE='#' +else + ENABLE_COREDUMP_TRUE='#' + ENABLE_COREDUMP_FALSE= +fi + + +have_manpages=no +# Check whether --enable-manpages was given. +if test "${enable_manpages+set}" = set; then : + enableval=$enable_manpages; +fi + +if test "x$enable_manpages" != "xno"; then + have_manpages=yes +fi + if test "$have_manpages" = "yes"; then + ENABLE_MANPAGES_TRUE= + ENABLE_MANPAGES_FALSE='#' +else + ENABLE_MANPAGES_TRUE='#' + ENABLE_MANPAGES_FALSE= +fi + + +have_gtk=no +# Check whether --enable-gtk was given. +if test "${enable_gtk+set}" = set; then : + enableval=$enable_gtk; +fi + +if test "x$enable_gtk" != "xno"; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK" >&5 +$as_echo_n "checking for GTK... " >&6; } + +if test -n "$GTK_CFLAGS"; then + pkg_cv_GTK_CFLAGS="$GTK_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 gee-1.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors " gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 gee-1.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GTK_CFLAGS=`$PKG_CONFIG --cflags " gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 gee-1.0" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$GTK_LIBS"; then + pkg_cv_GTK_LIBS="$GTK_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 gee-1.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors " gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 gee-1.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GTK_LIBS=`$PKG_CONFIG --libs " gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 gee-1.0" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + GTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors " gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 gee-1.0" 2>&1` + else + GTK_PKG_ERRORS=`$PKG_CONFIG --print-errors " gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 gee-1.0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$GTK_PKG_ERRORS" >&5 + + have_gtk=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_gtk=no +else + GTK_CFLAGS=$pkg_cv_GTK_CFLAGS + GTK_LIBS=$pkg_cv_GTK_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define HAVE_GTK 1" >>confdefs.h + have_gtk=yes +fi + if test "x$have_gtk" = xno -a "x$enable_gtk" = xyes; then + as_fn_error $? "*** gtk support requested but libraries not found" "$LINENO" 5 + fi +fi + if test "$have_gtk" = "yes"; then + HAVE_GTK_TRUE= + HAVE_GTK_FALSE='#' +else + HAVE_GTK_TRUE='#' + HAVE_GTK_FALSE= +fi + + +if test "$have_gtk" = "yes"; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBNOTIFY" >&5 +$as_echo_n "checking for LIBNOTIFY... " >&6; } + +if test -n "$LIBNOTIFY_CFLAGS"; then + pkg_cv_LIBNOTIFY_CFLAGS="$LIBNOTIFY_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" libnotify \""; } >&5 + ($PKG_CONFIG --exists --print-errors " libnotify ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBNOTIFY_CFLAGS=`$PKG_CONFIG --cflags " libnotify " 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBNOTIFY_LIBS"; then + pkg_cv_LIBNOTIFY_LIBS="$LIBNOTIFY_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" libnotify \""; } >&5 + ($PKG_CONFIG --exists --print-errors " libnotify ") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBNOTIFY_LIBS=`$PKG_CONFIG --libs " libnotify " 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBNOTIFY_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors " libnotify " 2>&1` + else + LIBNOTIFY_PKG_ERRORS=`$PKG_CONFIG --print-errors " libnotify " 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBNOTIFY_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements ( libnotify ) were not met: + +$LIBNOTIFY_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables LIBNOTIFY_CFLAGS +and LIBNOTIFY_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 + +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables LIBNOTIFY_CFLAGS +and LIBNOTIFY_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } + +else + LIBNOTIFY_CFLAGS=$pkg_cv_LIBNOTIFY_CFLAGS + LIBNOTIFY_LIBS=$pkg_cv_LIBNOTIFY_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi +fi + +# Extract the first word of "valac", so it can be a program name with args. +set dummy valac; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_VALAC+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $VALAC in + [\\/]* | ?:[\\/]*) + ac_cv_path_VALAC="$VALAC" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_VALAC="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +VALAC=$ac_cv_path_VALAC +if test -n "$VALAC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $VALAC" >&5 +$as_echo "$VALAC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test -z "$VALAC"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No Vala compiler found. You will not be able to compile .vala source files." >&5 +$as_echo "$as_me: WARNING: No Vala compiler found. You will not be able to compile .vala source files." >&2;} +else + if test -n "0.10"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking $VALAC is at least version 0.10" >&5 +$as_echo_n "checking $VALAC is at least version 0.10... " >&6; } + am__vala_version=`$VALAC --version | sed 's/Vala *//'` + as_arg_v1=0.10 +as_arg_v2="$am__vala_version" +awk "$as_awk_strverscmp" v1="$as_arg_v1" v2="$as_arg_v2" /dev/null +case $? in #( + 1) : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } ;; #( + 0) : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } ;; #( + 2) : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "Vala 0.10 not found." "$LINENO" 5 ;; #( + *) : + ;; +esac +fi +fi + + + if test x"$VALAC" != x; then + HAVE_VALAC_TRUE= + HAVE_VALAC_FALSE='#' +else + HAVE_VALAC_TRUE='#' + HAVE_VALAC_FALSE= +fi + + +# Extract the first word of "xsltproc", so it can be a program name with args. +set dummy xsltproc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_XSLTPROC+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $XSLTPROC in + [\\/]* | ?:[\\/]*) + ac_cv_path_XSLTPROC="$XSLTPROC" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_XSLTPROC="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +XSLTPROC=$ac_cv_path_XSLTPROC +if test -n "$XSLTPROC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XSLTPROC" >&5 +$as_echo "$XSLTPROC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test x"$XSLTPROC" != x; then + HAVE_XSLTPROC_TRUE= + HAVE_XSLTPROC_FALSE='#' +else + HAVE_XSLTPROC_TRUE='#' + HAVE_XSLTPROC_FALSE= +fi + + +# Extract the first word of "m4", so it can be a program name with args. +set dummy m4; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_M4+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $M4 in + [\\/]* | ?:[\\/]*) + ac_cv_path_M4="$M4" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_M4="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +M4=$ac_cv_path_M4 +if test -n "$M4"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $M4" >&5 +$as_echo "$M4" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + +# Check whether --with-distro was given. +if test "${with_distro+set}" = set; then : + withval=$with_distro; +fi + +if test "z$with_distro" = "z"; then + if test "$cross_compiling" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Target distribution cannot be reliably detected when cross-compiling. You should specify it with --with-distro (see $0 --help for recognized distros)" >&5 +$as_echo "$as_me: WARNING: Target distribution cannot be reliably detected when cross-compiling. You should specify it with --with-distro (see $0 --help for recognized distros)" >&2;} + else + with_distro=$($GREP '^ID=' /etc/os-release | $SED 's/ID=//'); + fi + if test "z$with_distro" = "z"; then + with_distro=other + fi +fi +with_distro=`echo ${with_distro} | tr '[:upper:]' '[:lower:]' ` + +cat >>confdefs.h <<_ACEOF +#define DISTRIBUTION "${with_distro}" +_ACEOF + + +# Location of the init scripts as mandated by LSB +SYSTEM_SYSVINIT_PATH=/etc/init.d +SYSTEM_SYSVRCND_PATH=/etc/rc.d + +M4_DEFINES= +have_plymouth=no + +case $with_distro in + fedora) + SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d + +$as_echo "#define TARGET_FEDORA /**/" >>confdefs.h + + M4_DEFINES=-DTARGET_FEDORA=1 + have_plymouth=yes + ;; + opensuse|suse) + SYSTEM_SYSVRCND_PATH=/etc/init.d + +$as_echo "#define TARGET_SUSE /**/" >>confdefs.h + + M4_DEFINES=-DTARGET_SUSE=1 + have_plymouth=yes + ;; + debian) + SYSTEM_SYSVRCND_PATH=/etc + +$as_echo "#define TARGET_DEBIAN /**/" >>confdefs.h + + M4_DEFINES=-DTARGET_DEBIAN=1 + ;; + ubuntu) + SYSTEM_SYSVRCND_PATH=/etc + +$as_echo "#define TARGET_UBUNTU /**/" >>confdefs.h + + M4_DEFINES=-DTARGET_UBUNTU=1 + ;; + arch) + SYSTEM_SYSVINIT_PATH=/etc/rc.d + SYSTEM_SYSVRCND_PATH=/etc + +$as_echo "#define TARGET_ARCH /**/" >>confdefs.h + + M4_DEFINES=-DTARGET_ARCH=1 + ;; + gentoo) + SYSTEM_SYSVINIT_PATH= + SYSTEM_SYSVRCND_PATH= + +$as_echo "#define TARGET_GENTOO /**/" >>confdefs.h + + M4_DEFINES=-DTARGET_GENTOO=1 + ;; + slackware) + SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d + +$as_echo "#define TARGET_SLACKWARE /**/" >>confdefs.h + + M4_DEFINES=-DTARGET_SLACKWARE=1 + ;; + frugalware) + SYSTEM_SYSVINIT_PATH=/etc/rc.d + +$as_echo "#define TARGET_FRUGALWARE /**/" >>confdefs.h + + M4_DEFINES=-DTARGET_FRUGALWARE=1 + have_plymouth=yes + ;; + altlinux) + SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d + +$as_echo "#define TARGET_ALTLINUX /**/" >>confdefs.h + + M4_DEFINES=-DTARGET_ALTLINUX=1 + have_plymouth=yes + ;; + mandriva) + SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d + +$as_echo "#define TARGET_MANDRIVA /**/" >>confdefs.h + + M4_DEFINES=-DTARGET_MANDRIVA=1 + have_plymouth=yes + ;; + meego) + SYSTEM_SYSVINIT_PATH= + SYSTEM_SYSVRCND_PATH= + +$as_echo "#define TARGET_MEEGO /**/" >>confdefs.h + + M4_DEFINES=-DTARGET_MEEGO=1 + ;; + angstrom) + SYSTEM_SYSVRCND_PATH=/etc + +$as_echo "#define TARGET_ANGSTROM /**/" >>confdefs.h + + M4_DEFINES=-DTARGET_ANGSTROM=1 + ;; + mageia) + SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d + +$as_echo "#define TARGET_MAGEIA /**/" >>confdefs.h + + M4_DISTRO_FLAG=-DTARGET_MAGEIA=1 + have_plymouth=yes + ;; + other) + ;; + *) + as_fn_error $? "Your distribution (${with_distro}) is not yet supported, SysV init scripts could not be found! (patches welcome); you can specify --with-distro=other to skip this check" "$LINENO" 5 + ;; +esac + + +# Check whether --with-sysvinit-path was given. +if test "${with_sysvinit_path+set}" = set; then : + withval=$with_sysvinit_path; SYSTEM_SYSVINIT_PATH="$withval" +fi + + + +# Check whether --with-sysvrcd-path was given. +if test "${with_sysvrcd_path+set}" = set; then : + withval=$with_sysvrcd_path; SYSTEM_SYSVRCND_PATH="$withval" +fi + + + + + + +if test "x${SYSTEM_SYSVINIT_PATH}" != "x" -a "x${SYSTEM_SYSVRCND_PATH}" != "x"; then + +$as_echo "#define HAVE_SYSV_COMPAT /**/" >>confdefs.h + + SYSTEM_SYSV_COMPAT="yes" + M4_DEFINES="$M4_DEFINES -DHAVE_SYSV_COMPAT" +elif test "x${SYSTEM_SYSVINIT_PATH}" != "x" -o "x${SYSTEM_SYSVRCND_PATH}" != "x"; then + as_fn_error $? "*** You need both --with-sysvinit-path=PATH and --with-sysvrcd-path=PATH to enable SysV compatibility support, or both empty to disable it." "$LINENO" 5 +else + SYSTEM_SYSV_COMPAT="no" +fi + + +# Check whether --with-tty-gid was given. +if test "${with_tty_gid+set}" = set; then : + withval=$with_tty_gid; +cat >>confdefs.h <<_ACEOF +#define TTY_GID $withval +_ACEOF + +fi + + +# Check whether --enable-plymouth was given. +if test "${enable_plymouth+set}" = set; then : + enableval=$enable_plymouth; +fi + +if test -n "$enable_plymouth"; then + have_plymouth="$enable_plymouth" +fi + + if test x"$with_distro" = xfedora; then + TARGET_FEDORA_TRUE= + TARGET_FEDORA_FALSE='#' +else + TARGET_FEDORA_TRUE='#' + TARGET_FEDORA_FALSE= +fi + + if test x"$with_distro" = xsuse; then + TARGET_SUSE_TRUE= + TARGET_SUSE_FALSE='#' +else + TARGET_SUSE_TRUE='#' + TARGET_SUSE_FALSE= +fi + + if test x"$with_distro" = xdebian; then + TARGET_DEBIAN_TRUE= + TARGET_DEBIAN_FALSE='#' +else + TARGET_DEBIAN_TRUE='#' + TARGET_DEBIAN_FALSE= +fi + + if test x"$with_distro" = xubuntu; then + TARGET_UBUNTU_TRUE= + TARGET_UBUNTU_FALSE='#' +else + TARGET_UBUNTU_TRUE='#' + TARGET_UBUNTU_FALSE= +fi + + if test x"$with_distro" = xdebian -o x"$with_distro" = xubuntu; then + TARGET_DEBIAN_OR_UBUNTU_TRUE= + TARGET_DEBIAN_OR_UBUNTU_FALSE='#' +else + TARGET_DEBIAN_OR_UBUNTU_TRUE='#' + TARGET_DEBIAN_OR_UBUNTU_FALSE= +fi + + if test x"$with_distro" = xarch; then + TARGET_ARCH_TRUE= + TARGET_ARCH_FALSE='#' +else + TARGET_ARCH_TRUE='#' + TARGET_ARCH_FALSE= +fi + + if test x"$with_distro" = xgentoo; then + TARGET_GENTOO_TRUE= + TARGET_GENTOO_FALSE='#' +else + TARGET_GENTOO_TRUE='#' + TARGET_GENTOO_FALSE= +fi + + if test x"$with_distro" = xslackware; then + TARGET_SLACKWARE_TRUE= + TARGET_SLACKWARE_FALSE='#' +else + TARGET_SLACKWARE_TRUE='#' + TARGET_SLACKWARE_FALSE= +fi + + if test x"$with_distro" = xfrugalware; then + TARGET_FRUGALWARE_TRUE= + TARGET_FRUGALWARE_FALSE='#' +else + TARGET_FRUGALWARE_TRUE='#' + TARGET_FRUGALWARE_FALSE= +fi + + if test x"$with_distro" = xaltlinux; then + TARGET_ALTLINUX_TRUE= + TARGET_ALTLINUX_FALSE='#' +else + TARGET_ALTLINUX_TRUE='#' + TARGET_ALTLINUX_FALSE= +fi + + if test x"$with_distro" = xmandriva; then + TARGET_MANDRIVA_TRUE= + TARGET_MANDRIVA_FALSE='#' +else + TARGET_MANDRIVA_TRUE='#' + TARGET_MANDRIVA_FALSE= +fi + + if test x"$with_distro" = xmeego; then + TARGET_MEEGO_TRUE= + TARGET_MEEGO_FALSE='#' +else + TARGET_MEEGO_TRUE='#' + TARGET_MEEGO_FALSE= +fi + + if test x"$with_distro" = xangstrom; then + TARGET_ANGSTROM_TRUE= + TARGET_ANGSTROM_FALSE='#' +else + TARGET_ANGSTROM_TRUE='#' + TARGET_ANGSTROM_FALSE= +fi + + if test x"$with_distro" = xmageia; then + TARGET_MAGEIA_TRUE= + TARGET_MAGEIA_FALSE='#' +else + TARGET_MAGEIA_TRUE='#' + TARGET_MAGEIA_FALSE= +fi + + + if test "$have_plymouth" = "yes"; then + HAVE_PLYMOUTH_TRUE= + HAVE_PLYMOUTH_FALSE='#' +else + HAVE_PLYMOUTH_TRUE='#' + HAVE_PLYMOUTH_FALSE= +fi + + if test "$SYSTEM_SYSV_COMPAT" = "yes"; then + HAVE_SYSV_COMPAT_TRUE= + HAVE_SYSV_COMPAT_FALSE='#' +else + HAVE_SYSV_COMPAT_TRUE='#' + HAVE_SYSV_COMPAT_FALSE= +fi + + + +# Check whether --with-dbuspolicydir was given. +if test "${with_dbuspolicydir+set}" = set; then : + withval=$with_dbuspolicydir; +else + with_dbuspolicydir=`pkg-config --variable=sysconfdir dbus-1`/dbus-1/system.d +fi + + + +# Check whether --with-dbussessionservicedir was given. +if test "${with_dbussessionservicedir+set}" = set; then : + withval=$with_dbussessionservicedir; +else + with_dbussessionservicedir=`pkg-config --variable=session_bus_services_dir dbus-1` +fi + + + +# Check whether --with-dbussystemservicedir was given. +if test "${with_dbussystemservicedir+set}" = set; then : + withval=$with_dbussystemservicedir; +else + with_dbussystemservicedir=`pkg-config --variable=session_bus_services_dir dbus-1`/../system-services +fi + + + +# Check whether --with-dbusinterfacedir was given. +if test "${with_dbusinterfacedir+set}" = set; then : + withval=$with_dbusinterfacedir; +else + with_dbusinterfacedir=`pkg-config --variable=session_bus_services_dir dbus-1`/../interfaces +fi + + + +# Check whether --with-udevrulesdir was given. +if test "${with_udevrulesdir+set}" = set; then : + withval=$with_udevrulesdir; +else + with_udevrulesdir=`pkg-config --variable=udevdir udev`/rules.d +fi + + + +# Check whether --with-rootprefix was given. +if test "${with_rootprefix+set}" = set; then : + withval=$with_rootprefix; +else + with_rootprefix=${ac_default_prefix} +fi + + + +# Check whether --with-rootlibdir was given. +if test "${with_rootlibdir+set}" = set; then : + withval=$with_rootlibdir; +else + with_rootlibdir=${libdir} +fi + + + +# Check whether --with-pamlibdir was given. +if test "${with_pamlibdir+set}" = set; then : + withval=$with_pamlibdir; +else + with_pamlibdir=${with_rootlibdir}/security +fi + + +# Check whether --enable-split-usr was given. +if test "${enable_split_usr+set}" = set; then : + enableval=$enable_split_usr; +else + if test "x${ac_default_prefix}" != "x${with_rootprefix}"; then : + + enable_split_usr=yes + +else + + enable_split_usr=no + +fi +fi + + +if test "x${enable_split_usr}" = "xyes"; then : + + +$as_echo "#define HAVE_SPLIT_USR 1" >>confdefs.h + + +fi + +dbuspolicydir=$with_dbuspolicydir + +dbussessionservicedir=$with_dbussessionservicedir + +dbussystemservicedir=$with_dbussystemservicedir + +dbusinterfacedir=$with_dbusinterfacedir + +udevrulesdir=$with_udevrulesdir + +pamlibdir=$with_pamlibdir + +rootprefix=$with_rootprefix + +rootlibdir=$with_rootlibdir + + +ac_config_files="$ac_config_files Makefile po/Makefile.in" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + + + ac_config_commands="$ac_config_commands po/stamp-it" + + +if test -z "${HAVE_SELINUX_TRUE}" && test -z "${HAVE_SELINUX_FALSE}"; then + as_fn_error $? "conditional \"HAVE_SELINUX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_XZ_TRUE}" && test -z "${HAVE_XZ_FALSE}"; then + as_fn_error $? "conditional \"HAVE_XZ\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_PAM_TRUE}" && test -z "${HAVE_PAM_FALSE}"; then + as_fn_error $? "conditional \"HAVE_PAM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_ACL_TRUE}" && test -z "${HAVE_ACL_FALSE}"; then + as_fn_error $? "conditional \"HAVE_ACL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_LIBCRYPTSETUP_TRUE}" && test -z "${HAVE_LIBCRYPTSETUP_FALSE}"; then + as_fn_error $? "conditional \"HAVE_LIBCRYPTSETUP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_BINFMT_TRUE}" && test -z "${ENABLE_BINFMT_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_BINFMT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_VCONSOLE_TRUE}" && test -z "${ENABLE_VCONSOLE_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_VCONSOLE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_READAHEAD_TRUE}" && test -z "${ENABLE_READAHEAD_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_READAHEAD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_QUOTACHECK_TRUE}" && test -z "${ENABLE_QUOTACHECK_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_QUOTACHECK\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_RANDOMSEED_TRUE}" && test -z "${ENABLE_RANDOMSEED_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_RANDOMSEED\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_LOGIND_TRUE}" && test -z "${ENABLE_LOGIND_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_LOGIND\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_HOSTNAMED_TRUE}" && test -z "${ENABLE_HOSTNAMED_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_HOSTNAMED\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_TIMEDATED_TRUE}" && test -z "${ENABLE_TIMEDATED_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_TIMEDATED\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_LOCALED_TRUE}" && test -z "${ENABLE_LOCALED_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_LOCALED\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_COREDUMP_TRUE}" && test -z "${ENABLE_COREDUMP_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_COREDUMP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${ENABLE_MANPAGES_TRUE}" && test -z "${ENABLE_MANPAGES_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_MANPAGES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_GTK_TRUE}" && test -z "${HAVE_GTK_FALSE}"; then + as_fn_error $? "conditional \"HAVE_GTK\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_VALAC_TRUE}" && test -z "${HAVE_VALAC_FALSE}"; then + as_fn_error $? "conditional \"HAVE_VALAC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_XSLTPROC_TRUE}" && test -z "${HAVE_XSLTPROC_FALSE}"; then + as_fn_error $? "conditional \"HAVE_XSLTPROC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TARGET_FEDORA_TRUE}" && test -z "${TARGET_FEDORA_FALSE}"; then + as_fn_error $? "conditional \"TARGET_FEDORA\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TARGET_SUSE_TRUE}" && test -z "${TARGET_SUSE_FALSE}"; then + as_fn_error $? "conditional \"TARGET_SUSE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TARGET_DEBIAN_TRUE}" && test -z "${TARGET_DEBIAN_FALSE}"; then + as_fn_error $? "conditional \"TARGET_DEBIAN\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TARGET_UBUNTU_TRUE}" && test -z "${TARGET_UBUNTU_FALSE}"; then + as_fn_error $? "conditional \"TARGET_UBUNTU\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TARGET_DEBIAN_OR_UBUNTU_TRUE}" && test -z "${TARGET_DEBIAN_OR_UBUNTU_FALSE}"; then + as_fn_error $? "conditional \"TARGET_DEBIAN_OR_UBUNTU\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TARGET_ARCH_TRUE}" && test -z "${TARGET_ARCH_FALSE}"; then + as_fn_error $? "conditional \"TARGET_ARCH\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TARGET_GENTOO_TRUE}" && test -z "${TARGET_GENTOO_FALSE}"; then + as_fn_error $? "conditional \"TARGET_GENTOO\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TARGET_SLACKWARE_TRUE}" && test -z "${TARGET_SLACKWARE_FALSE}"; then + as_fn_error $? "conditional \"TARGET_SLACKWARE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TARGET_FRUGALWARE_TRUE}" && test -z "${TARGET_FRUGALWARE_FALSE}"; then + as_fn_error $? "conditional \"TARGET_FRUGALWARE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TARGET_ALTLINUX_TRUE}" && test -z "${TARGET_ALTLINUX_FALSE}"; then + as_fn_error $? "conditional \"TARGET_ALTLINUX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TARGET_MANDRIVA_TRUE}" && test -z "${TARGET_MANDRIVA_FALSE}"; then + as_fn_error $? "conditional \"TARGET_MANDRIVA\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TARGET_MEEGO_TRUE}" && test -z "${TARGET_MEEGO_FALSE}"; then + as_fn_error $? "conditional \"TARGET_MEEGO\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TARGET_ANGSTROM_TRUE}" && test -z "${TARGET_ANGSTROM_FALSE}"; then + as_fn_error $? "conditional \"TARGET_ANGSTROM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TARGET_MAGEIA_TRUE}" && test -z "${TARGET_MAGEIA_FALSE}"; then + as_fn_error $? "conditional \"TARGET_MAGEIA\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_PLYMOUTH_TRUE}" && test -z "${HAVE_PLYMOUTH_FALSE}"; then + as_fn_error $? "conditional \"HAVE_PLYMOUTH\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_SYSV_COMPAT_TRUE}" && test -z "${HAVE_SYSV_COMPAT_FALSE}"; then + as_fn_error $? "conditional \"HAVE_SYSV_COMPAT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by systemd $as_me 43, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +systemd config.status 43 +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; + "po/stamp-it") CONFIG_COMMANDS="$CONFIG_COMMANDS po/stamp-it" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="" + +# ### BEGIN LIBTOOL CONFIG + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + ;; + "po/stamp-it":C) + if ! grep "^# INTLTOOL_MAKEFILE$" "po/Makefile.in" > /dev/null ; then + as_fn_error $? "po/Makefile.in.in was not created by intltoolize." "$LINENO" 5 + fi + rm -f "po/stamp-it" "po/stamp-it.tmp" "po/POTFILES" "po/Makefile.tmp" + >"po/stamp-it.tmp" + sed '/^#/d + s/^[[].*] *// + /^[ ]*$/d + '"s|^| $ac_top_srcdir/|" \ + "$srcdir/po/POTFILES.in" | sed '$!s/$/ \\/' >"po/POTFILES" + + sed '/^POTFILES =/,/[^\\]$/ { + /^POTFILES =/!d + r po/POTFILES + } + ' "po/Makefile.in" >"po/Makefile" + rm -f "po/Makefile.tmp" + mv "po/stamp-it.tmp" "po/stamp-it" + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: + $PACKAGE_NAME $VERSION + + Distribution: ${with_distro} + SysV compatibility: ${SYSTEM_SYSV_COMPAT} + SysV init scripts: ${SYSTEM_SYSVINIT_PATH} + SysV rc?.d directories: ${SYSTEM_SYSVRCND_PATH} + Gtk: ${have_gtk} + libcryptsetup: ${have_libcryptsetup} + tcpwrap: ${have_tcpwrap} + PAM: ${have_pam} + AUDIT: ${have_audit} + SELinux: ${have_selinux} + XZ: ${have_xz} + ACL: ${have_acl} + binfmt: ${have_binfmt} + vconsole: ${have_vconsole} + readahead: ${have_readahead} + quotacheck: ${have_quotacheck} + randomseed: ${have_randomseed} + logind: ${have_logind} + hostnamed: ${have_hostnamed} + timedated: ${have_timedated} + localed: ${have_localed} + coredump: ${have_coredump} + plymouth: ${have_plymouth} + prefix: ${prefix} + rootprefix: ${with_rootprefix} + libexec dir: ${libexecdir} + lib dir: ${libdir} + rootlib dir: ${with_rootlibdir} + PAM modules dir: ${with_pamlibdir} + udev rules dir: ${with_udevrulesdir} + D-Bus policy dir: ${with_dbuspolicydir} + D-Bus session dir: ${with_dbussessionservicedir} + D-Bus system dir: ${with_dbussystemservicedir} + D-Bus interfaces dir: ${with_dbusinterfacedir} + Split /usr: ${enable_split_usr} + Build man pages: ${have_manpages} +" >&5 +$as_echo " + $PACKAGE_NAME $VERSION + + Distribution: ${with_distro} + SysV compatibility: ${SYSTEM_SYSV_COMPAT} + SysV init scripts: ${SYSTEM_SYSVINIT_PATH} + SysV rc?.d directories: ${SYSTEM_SYSVRCND_PATH} + Gtk: ${have_gtk} + libcryptsetup: ${have_libcryptsetup} + tcpwrap: ${have_tcpwrap} + PAM: ${have_pam} + AUDIT: ${have_audit} + SELinux: ${have_selinux} + XZ: ${have_xz} + ACL: ${have_acl} + binfmt: ${have_binfmt} + vconsole: ${have_vconsole} + readahead: ${have_readahead} + quotacheck: ${have_quotacheck} + randomseed: ${have_randomseed} + logind: ${have_logind} + hostnamed: ${have_hostnamed} + timedated: ${have_timedated} + localed: ${have_localed} + coredump: ${have_coredump} + plymouth: ${have_plymouth} + prefix: ${prefix} + rootprefix: ${with_rootprefix} + libexec dir: ${libexecdir} + lib dir: ${libdir} + rootlib dir: ${with_rootlibdir} + PAM modules dir: ${with_pamlibdir} + udev rules dir: ${with_udevrulesdir} + D-Bus policy dir: ${with_dbuspolicydir} + D-Bus session dir: ${with_dbussessionservicedir} + D-Bus system dir: ${with_dbussystemservicedir} + D-Bus interfaces dir: ${with_dbusinterfacedir} + Split /usr: ${enable_split_usr} + Build man pages: ${have_manpages} +" >&6; } diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..62e8cdf --- /dev/null +++ b/configure.ac @@ -0,0 +1,658 @@ +# This file is part of systemd. +# +# Copyright 2010 Lennart Poettering +# +# systemd 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. +# +# systemd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with systemd; If not, see . + +AC_PREREQ(2.63) + +AC_INIT([systemd],[43],[systemd-devel@lists.freedesktop.org]) +AC_CONFIG_SRCDIR([src/main.c]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_HEADERS([config.h]) +AC_USE_SYSTEM_EXTENSIONS +AC_SYS_LARGEFILE +AC_PREFIX_DEFAULT([/usr]) +AM_INIT_AUTOMAKE([foreign 1.11 -Wall -Wno-portability silent-rules tar-pax no-dist-gzip dist-xz subdir-objects check-news]) + +AC_SUBST(PACKAGE_URL, [http://www.freedesktop.org/wiki/Software/systemd]) + +AC_CANONICAL_HOST +AC_DEFINE_UNQUOTED([CANONICAL_HOST], "$host", [Canonical host string.]) +AS_IF([test "x$host_cpu" = "xmips" || test "x$host_cpu" = "xmipsel" || + test "x$host_cpu" = "xmips64" || test "x$host_cpu" = "xmips64el"], + [AC_DEFINE(ARCH_MIPS, [], [Whether on mips arch])]) + +AM_SILENT_RULES([yes]) + +# i18n stuff for the PolicyKit policy files +IT_PROG_INTLTOOL([0.40.0]) + +GETTEXT_PACKAGE=systemd +AC_SUBST(GETTEXT_PACKAGE) + +AC_PROG_MKDIR_P +AC_PROG_LN_S +AC_PROG_SED +AC_PROG_GREP +AC_PROG_AWK + +AC_PROG_CC +AC_PROG_CC_C99 +AM_PROG_CC_C_O +AC_PROG_GCC_TRADITIONAL + +AC_CHECK_TOOL(OBJCOPY, objcopy) +AC_CHECK_TOOL(STRINGS, strings) +AC_CHECK_TOOL(GPERF, gperf) +if test -z "$GPERF" ; then + AC_MSG_ERROR([*** gperf not found]) +fi + +CC_CHECK_CFLAGS_APPEND([ \ + -pipe \ + -Wall \ + -W \ + -Wextra \ + -Wno-inline \ + -Wvla \ + -Wundef \ + -Wformat=2 \ + -Wlogical-op \ + -Wsign-compare \ + -Wformat-security \ + -Wmissing-include-dirs \ + -Wformat-nonliteral \ + -Wold-style-definition \ + -Wpointer-arith \ + -Winit-self \ + -Wdeclaration-after-statement \ + -Wfloat-equal \ + -Wmissing-prototypes \ + -Wstrict-prototypes \ + -Wredundant-decls \ + -Wmissing-declarations \ + -Wmissing-noreturn \ + -Wshadow \ + -Wendif-labels \ + -Wcast-align \ + -Wstrict-aliasing=2 \ + -Wwrite-strings \ + -Wno-long-long \ + -Wno-overlength-strings \ + -Wno-unused-parameter \ + -Wno-missing-field-initializers \ + -Wno-unused-result \ + -Werror=overflow \ + -Wp,-D_FORTIFY_SOURCE=2 \ + -ffast-math \ + -fno-common \ + -fdiagnostics-show-option \ + -fno-strict-aliasing \ + -fvisibility=hidden \ + -ffunction-sections \ + -fdata-sections \ + -Wl,--as-needed \ + -Wl,--gc-sections]) + +LT_PREREQ(2.2) +LT_INIT + +AC_SEARCH_LIBS([clock_gettime], [rt], [], [AC_MSG_ERROR([*** POSIX RT library not found])]) +AC_SEARCH_LIBS([dlsym], [dl], [], [AC_MSG_ERROR([*** Dynamic linking loader library not found])]) + +save_LIBS="$LIBS" +LIBS= +AC_SEARCH_LIBS([cap_init], [cap], [], [AC_MSG_ERROR([*** POSIX caps library not found])]) +AC_CHECK_HEADERS([sys/capability.h], [], [AC_MSG_ERROR([*** POSIX caps headers not found])]) +CAP_LIBS="$LIBS" +LIBS="$save_LIBS" +AC_SUBST(CAP_LIBS) + +# This makes sure pkg.m4 is available. +m4_pattern_forbid([^_?PKG_[A-Z_]+$],[*** pkg.m4 missing, please install pkg-config]) + +PKG_CHECK_MODULES(UDEV, [ libudev >= 172 ]) +PKG_CHECK_MODULES(DBUS, [ dbus-1 >= 1.3.2 ]) +PKG_CHECK_MODULES(KMOD, [ libkmod >= 5 ]) + +have_selinux=no +AC_ARG_ENABLE(selinux, AS_HELP_STRING([--disable-selinux], [Disable optional SELINUX support])) +if test "x$enable_selinux" != "xno"; then + PKG_CHECK_MODULES(SELINUX, [ libselinux ], + [AC_DEFINE(HAVE_SELINUX, 1, [Define if SELinux is available]) have_selinux=yes], have_selinux=no) + if test "x$have_selinux" = xno -a "x$enable_selinux" = xyes; then + AC_MSG_ERROR([*** SELinux support requested but libraries not found]) + fi +fi +AM_CONDITIONAL(HAVE_SELINUX, [test "$have_selinux" = "yes"]) + +have_xz=no +AC_ARG_ENABLE(xz, AS_HELP_STRING([--disable-xz], [Disable optional XZ support])) +if test "x$enable_xz" != "xno"; then + PKG_CHECK_MODULES(XZ, [ liblzma ], + [AC_DEFINE(HAVE_XZ, 1, [Define if XZ is available]) have_xz=yes], have_xz=no) + if test "x$have_xz" = xno -a "x$enable_xz" = xyes; then + AC_MSG_ERROR([*** Xz support requested but libraries not found]) + fi +fi +AM_CONDITIONAL(HAVE_XZ, [test "$have_xz" = "yes"]) + +AC_ARG_ENABLE([tcpwrap], + AS_HELP_STRING([--disable-tcpwrap],[Disable optional TCP wrappers support]), + [case "${enableval}" in + yes) have_tcpwrap=yes ;; + no) have_tcpwrap=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-tcpwrap) ;; + esac], + [have_tcpwrap=auto]) + +if test "x${have_tcpwrap}" != xno ; then + ACX_LIBWRAP + if test "x${LIBWRAP_LIBS}" = x ; then + if test "x$have_tcpwrap" = xyes ; then + AC_MSG_ERROR([*** TCP wrappers support not found.]) + fi + have_tcpwrap=no + else + have_tcpwrap=yes + fi +else + LIBWRAP_LIBS= +fi +AC_SUBST(LIBWRAP_LIBS) + +AC_ARG_ENABLE([pam], + AS_HELP_STRING([--disable-pam],[Disable optional PAM support]), + [case "${enableval}" in + yes) have_pam=yes ;; + no) have_pam=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-pam) ;; + esac], + [have_pam=auto]) + +if test "x${have_pam}" != xno ; then + AC_CHECK_HEADERS( + [security/pam_modules.h security/pam_modutil.h security/pam_ext.h], + [have_pam=yes], + [if test "x$have_pam" = xyes ; then + AC_MSG_ERROR([*** PAM headers not found.]) + fi]) + + AC_CHECK_LIB( + [pam], + [pam_syslog], + [have_pam=yes], + [if test "x$have_pam" = xyes ; then + AC_MSG_ERROR([*** libpam not found.]) + fi]) + + if test "x$have_pam" = xyes ; then + PAM_LIBS="-lpam -lpam_misc" + AC_DEFINE(HAVE_PAM, 1, [PAM available]) + else + have_pam=no + fi +else + PAM_LIBS= +fi +AC_SUBST(PAM_LIBS) +AM_CONDITIONAL([HAVE_PAM], [test "x$have_pam" != xno]) + +AC_ARG_ENABLE([acl], + AS_HELP_STRING([--disable-acl],[Disable optional ACL support]), + [case "${enableval}" in + yes) have_acl=yes ;; + no) have_acl=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-acl) ;; + esac], + [have_acl=auto]) + +if test "x${have_acl}" != xno ; then + AC_CHECK_HEADERS( + [sys/acl.h acl/libacl.h], + [have_acl=yes], + [if test "x$have_acl" = xyes ; then + AC_MSG_ERROR([*** ACL headers not found.]) + fi]) + + AC_CHECK_LIB( + [acl], + [acl_get_file], + [have_acl=yes], + [if test "x$have_acl" = xyes ; then + AC_MSG_ERROR([*** libacl not found.]) + fi]) + + if test "x$have_acl" = xyes ; then + ACL_LIBS="-lacl" + AC_DEFINE(HAVE_ACL, 1, [ACL available]) + else + have_acl=no + fi +else + ACL_LIBS= +fi +AC_SUBST(ACL_LIBS) +AM_CONDITIONAL([HAVE_ACL], [test "x$have_acl" != xno]) + +AC_ARG_ENABLE([audit], + AS_HELP_STRING([--disable-audit],[Disable optional AUDIT support]), + [case "${enableval}" in + yes) have_audit=yes ;; + no) have_audit=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-audit) ;; + esac], + [have_audit=auto]) + +if test "x${have_audit}" != xno ; then + AC_CHECK_HEADERS( + [libaudit.h], + [have_audit=yes], + [if test "x$have_audit" = xyes ; then + AC_MSG_ERROR([*** AUDIT headers not found.]) + fi]) + + AC_CHECK_LIB( + [audit], + [audit_open], + [have_audit=yes], + [if test "x$have_audit" = xyes ; then + AC_MSG_ERROR([*** libaudit not found.]) + fi]) + + if test "x$have_audit" = xyes ; then + AUDIT_LIBS="-laudit" + AC_DEFINE(HAVE_AUDIT, 1, [AUDIT available]) + else + have_audit=no + fi +else + AUDIT_LIBS= +fi +AC_SUBST(AUDIT_LIBS) + +have_libcryptsetup=no +AC_ARG_ENABLE(libcryptsetup, AS_HELP_STRING([--disable-libcryptsetup], [disable libcryptsetup tools])) +if test "x$enable_libcryptsetup" != "xno"; then + PKG_CHECK_MODULES(LIBCRYPTSETUP, [ libcryptsetup ], + [AC_DEFINE(HAVE_LIBCRYPTSETUP, 1, [Define if libcryptsetup is available]) have_libcryptsetup=yes], have_libcryptsetup=no) + if test "x$have_libcryptsetup" = xno -a "x$enable_libcryptsetup" = xyes; then + AC_MSG_ERROR([*** libcryptsetup support requested but libraries not found]) + fi +fi +AM_CONDITIONAL(HAVE_LIBCRYPTSETUP, [test "$have_libcryptsetup" = "yes"]) + +have_binfmt=no +AC_ARG_ENABLE(binfmt, AS_HELP_STRING([--disable-binfmt], [disable binfmt tool])) +if test "x$enable_binfmt" != "xno"; then + have_binfmt=yes +fi +AM_CONDITIONAL(ENABLE_BINFMT, [test "$have_binfmt" = "yes"]) + +have_vconsole=no +AC_ARG_ENABLE(vconsole, AS_HELP_STRING([--disable-vconsole], [disable vconsole tool])) +if test "x$enable_vconsole" != "xno"; then + have_vconsole=yes +fi +AM_CONDITIONAL(ENABLE_VCONSOLE, [test "$have_vconsole" = "yes"]) + +have_readahead=no +AC_ARG_ENABLE(readahead, AS_HELP_STRING([--disable-readahead], [disable readahead tools])) +if test "x$enable_readahead" != "xno"; then + have_readahead=yes +fi +AM_CONDITIONAL(ENABLE_READAHEAD, [test "$have_readahead" = "yes"]) + +have_quotacheck=no +AC_ARG_ENABLE(quotacheck, AS_HELP_STRING([--disable-quotacheck], [disable quotacheck tools])) +if test "x$enable_quotacheck" != "xno"; then + have_quotacheck=yes +fi +AM_CONDITIONAL(ENABLE_QUOTACHECK, [test "$have_quotacheck" = "yes"]) + +have_randomseed=no +AC_ARG_ENABLE(randomseed, AS_HELP_STRING([--disable-randomseed], [disable randomseed tools])) +if test "x$enable_randomseed" != "xno"; then + have_randomseed=yes +fi +AM_CONDITIONAL(ENABLE_RANDOMSEED, [test "$have_randomseed" = "yes"]) + +have_logind=no +AC_ARG_ENABLE(logind, AS_HELP_STRING([--disable-logind], [disable login daemon])) +if test "x$enable_logind" != "xno"; then + have_logind=yes +fi +AM_CONDITIONAL(ENABLE_LOGIND, [test "$have_logind" = "yes"]) + +have_hostnamed=no +AC_ARG_ENABLE(hostnamed, AS_HELP_STRING([--disable-hostnamed], [disable hostname daemon])) +if test "x$enable_hostnamed" != "xno"; then + have_hostnamed=yes +fi +AM_CONDITIONAL(ENABLE_HOSTNAMED, [test "$have_hostnamed" = "yes"]) + +have_timedated=no +AC_ARG_ENABLE(timedated, AS_HELP_STRING([--disable-timedated], [disable timedate daemon])) +if test "x$enable_timedated" != "xno"; then + have_timedated=yes +fi +AM_CONDITIONAL(ENABLE_TIMEDATED, [test "$have_timedated" = "yes"]) + +have_localed=no +AC_ARG_ENABLE(localed, AS_HELP_STRING([--disable-localed], [disable locale daemon])) +if test "x$enable_localed" != "xno"; then + have_localed=yes +fi +AM_CONDITIONAL(ENABLE_LOCALED, [test "$have_localed" = "yes"]) + +have_coredump=no +AC_ARG_ENABLE(coredump, AS_HELP_STRING([--disable-coredump], [disable coredump hook])) +if test "x$enable_coredump" != "xno"; then + have_coredump=yes +fi +AM_CONDITIONAL(ENABLE_COREDUMP, [test "$have_coredump" = "yes"]) + +have_manpages=no +AC_ARG_ENABLE(manpages, AS_HELP_STRING([--disable-manpages], [disable manpages])) +if test "x$enable_manpages" != "xno"; then + have_manpages=yes +fi +AM_CONDITIONAL(ENABLE_MANPAGES, [test "$have_manpages" = "yes"]) + +have_gtk=no +AC_ARG_ENABLE(gtk, AS_HELP_STRING([--disable-gtk], [disable GTK tools])) +if test "x$enable_gtk" != "xno"; then + PKG_CHECK_MODULES(GTK, [ gtk+-2.0 glib-2.0 > 2.26 gio-unix-2.0 gee-1.0], + [AC_DEFINE(HAVE_GTK, 1, [Define if GTK is available]) have_gtk=yes], have_gtk=no) + if test "x$have_gtk" = xno -a "x$enable_gtk" = xyes; then + AC_MSG_ERROR([*** gtk support requested but libraries not found]) + fi +fi +AM_CONDITIONAL(HAVE_GTK, [test "$have_gtk" = "yes"]) + +if test "$have_gtk" = "yes"; then + PKG_CHECK_MODULES(LIBNOTIFY, [ libnotify ]) +fi + +AM_PROG_VALAC([0.10]) +AC_SUBST(VAPIDIR) +AM_CONDITIONAL(HAVE_VALAC, test x"$VALAC" != x) + +AC_PATH_PROG([XSLTPROC], [xsltproc]) +AM_CONDITIONAL(HAVE_XSLTPROC, test x"$XSLTPROC" != x) + +AC_PATH_PROG([M4], [m4]) + +AC_ARG_WITH(distro, AS_HELP_STRING([--with-distro=DISTRO],[Specify the distribution to target: One of fedora, suse, debian, ubuntu, arch, gentoo, slackware, altlinuxi, mandriva, meego, mageia, angstrom or other])) +if test "z$with_distro" = "z"; then + if test "$cross_compiling" = yes; then + AC_MSG_WARN([Target distribution cannot be reliably detected when cross-compiling. You should specify it with --with-distro (see $0 --help for recognized distros)]) + else + with_distro=$($GREP '^ID=' /etc/os-release | $SED 's/ID=//'); + fi + if test "z$with_distro" = "z"; then + with_distro=other + fi +fi +with_distro=`echo ${with_distro} | tr '[[:upper:]]' '[[:lower:]]' ` +AC_DEFINE_UNQUOTED(DISTRIBUTION, ["${with_distro}"], [Target Distribution]) + +# Location of the init scripts as mandated by LSB +SYSTEM_SYSVINIT_PATH=/etc/init.d +SYSTEM_SYSVRCND_PATH=/etc/rc.d + +M4_DEFINES= +have_plymouth=no + +case $with_distro in + fedora) + SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d + AC_DEFINE(TARGET_FEDORA, [], [Target is Fedora/RHEL]) + M4_DEFINES=-DTARGET_FEDORA=1 + have_plymouth=yes + ;; + opensuse|suse) + SYSTEM_SYSVRCND_PATH=/etc/init.d + AC_DEFINE(TARGET_SUSE, [], [Target is openSUSE/SLE]) + M4_DEFINES=-DTARGET_SUSE=1 + have_plymouth=yes + ;; + debian) + SYSTEM_SYSVRCND_PATH=/etc + AC_DEFINE(TARGET_DEBIAN, [], [Target is Debian]) + M4_DEFINES=-DTARGET_DEBIAN=1 + ;; + ubuntu) + SYSTEM_SYSVRCND_PATH=/etc + AC_DEFINE(TARGET_UBUNTU, [], [Target is Ubuntu]) + M4_DEFINES=-DTARGET_UBUNTU=1 + ;; + arch) + SYSTEM_SYSVINIT_PATH=/etc/rc.d + SYSTEM_SYSVRCND_PATH=/etc + AC_DEFINE(TARGET_ARCH, [], [Target is ArchLinux]) + M4_DEFINES=-DTARGET_ARCH=1 + ;; + gentoo) + SYSTEM_SYSVINIT_PATH= + SYSTEM_SYSVRCND_PATH= + AC_DEFINE(TARGET_GENTOO, [], [Target is Gentoo]) + M4_DEFINES=-DTARGET_GENTOO=1 + ;; + slackware) + SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d + AC_DEFINE(TARGET_SLACKWARE, [], [Target is Slackware]) + M4_DEFINES=-DTARGET_SLACKWARE=1 + ;; + frugalware) + SYSTEM_SYSVINIT_PATH=/etc/rc.d + AC_DEFINE(TARGET_FRUGALWARE, [], [Target is Frugalware]) + M4_DEFINES=-DTARGET_FRUGALWARE=1 + have_plymouth=yes + ;; + altlinux) + SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d + AC_DEFINE(TARGET_ALTLINUX, [], [Target is ALTLinux]) + M4_DEFINES=-DTARGET_ALTLINUX=1 + have_plymouth=yes + ;; + mandriva) + SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d + AC_DEFINE(TARGET_MANDRIVA, [], [Target is Mandriva]) + M4_DEFINES=-DTARGET_MANDRIVA=1 + have_plymouth=yes + ;; + meego) + SYSTEM_SYSVINIT_PATH= + SYSTEM_SYSVRCND_PATH= + AC_DEFINE(TARGET_MEEGO, [], [Target is MeeGo]) + M4_DEFINES=-DTARGET_MEEGO=1 + ;; + angstrom) + SYSTEM_SYSVRCND_PATH=/etc + AC_DEFINE(TARGET_ANGSTROM, [], [Target is Ångström]) + M4_DEFINES=-DTARGET_ANGSTROM=1 + ;; + mageia) + SYSTEM_SYSVINIT_PATH=/etc/rc.d/init.d + AC_DEFINE(TARGET_MAGEIA, [], [Target is Mageia]) + M4_DISTRO_FLAG=-DTARGET_MAGEIA=1 + have_plymouth=yes + ;; + other) + ;; + *) + AC_MSG_ERROR([Your distribution (${with_distro}) is not yet supported, SysV init scripts could not be found! (patches welcome); you can specify --with-distro=other to skip this check]) + ;; +esac + +AC_ARG_WITH([sysvinit-path], + [AS_HELP_STRING([--with-sysvinit-path=PATH], + [Specify the path to where the SysV init scripts are located @<:@default=based on distro@:>@])], + [SYSTEM_SYSVINIT_PATH="$withval"], + []) + +AC_ARG_WITH([sysvrcd-path], + [AS_HELP_STRING([--with-sysvrcd-path=PATH], + [Specify the path to the base directory for the SysV rcN.d directories @<:@default=based on distro@:>@])], + [SYSTEM_SYSVRCND_PATH="$withval"], + []) + +AC_SUBST(SYSTEM_SYSVINIT_PATH) +AC_SUBST(SYSTEM_SYSVRCND_PATH) +AC_SUBST(M4_DEFINES) + +if test "x${SYSTEM_SYSVINIT_PATH}" != "x" -a "x${SYSTEM_SYSVRCND_PATH}" != "x"; then + AC_DEFINE(HAVE_SYSV_COMPAT, [], [SysV init scripts and rcN.d links are supported.]) + SYSTEM_SYSV_COMPAT="yes" + M4_DEFINES="$M4_DEFINES -DHAVE_SYSV_COMPAT" +elif test "x${SYSTEM_SYSVINIT_PATH}" != "x" -o "x${SYSTEM_SYSVRCND_PATH}" != "x"; then + AC_MSG_ERROR([*** You need both --with-sysvinit-path=PATH and --with-sysvrcd-path=PATH to enable SysV compatibility support, or both empty to disable it.]) +else + SYSTEM_SYSV_COMPAT="no" +fi + +AC_ARG_WITH([tty-gid], + [AS_HELP_STRING([--with-tty-gid=GID], + [Specify the numeric GID of the 'tty' group])], + [AC_DEFINE_UNQUOTED(TTY_GID, [$withval], [GID of the 'tty' group])], + []) + +AC_ARG_ENABLE(plymouth, AS_HELP_STRING([--enable-plymouth], [enable plymouth support])) +if test -n "$enable_plymouth"; then + have_plymouth="$enable_plymouth" +fi + +AM_CONDITIONAL(TARGET_FEDORA, test x"$with_distro" = xfedora) +AM_CONDITIONAL(TARGET_SUSE, test x"$with_distro" = xsuse) +AM_CONDITIONAL(TARGET_DEBIAN, test x"$with_distro" = xdebian) +AM_CONDITIONAL(TARGET_UBUNTU, test x"$with_distro" = xubuntu) +AM_CONDITIONAL(TARGET_DEBIAN_OR_UBUNTU, test x"$with_distro" = xdebian -o x"$with_distro" = xubuntu) +AM_CONDITIONAL(TARGET_ARCH, test x"$with_distro" = xarch) +AM_CONDITIONAL(TARGET_GENTOO, test x"$with_distro" = xgentoo) +AM_CONDITIONAL(TARGET_SLACKWARE, test x"$with_distro" = xslackware) +AM_CONDITIONAL(TARGET_FRUGALWARE, test x"$with_distro" = xfrugalware) +AM_CONDITIONAL(TARGET_ALTLINUX, test x"$with_distro" = xaltlinux) +AM_CONDITIONAL(TARGET_MANDRIVA, test x"$with_distro" = xmandriva) +AM_CONDITIONAL(TARGET_MEEGO, test x"$with_distro" = xmeego) +AM_CONDITIONAL(TARGET_ANGSTROM, test x"$with_distro" = xangstrom) +AM_CONDITIONAL(TARGET_MAGEIA, test x"$with_distro" = xmageia) + +AM_CONDITIONAL(HAVE_PLYMOUTH, test "$have_plymouth" = "yes") +AM_CONDITIONAL(HAVE_SYSV_COMPAT, test "$SYSTEM_SYSV_COMPAT" = "yes") + +AC_ARG_WITH([dbuspolicydir], + AS_HELP_STRING([--with-dbuspolicydir=DIR], [D-Bus policy directory]), + [], + [with_dbuspolicydir=`pkg-config --variable=sysconfdir dbus-1`/dbus-1/system.d]) + +AC_ARG_WITH([dbussessionservicedir], + AS_HELP_STRING([--with-dbussessionservicedir=DIR], [D-Bus session service directory]), + [], + [with_dbussessionservicedir=`pkg-config --variable=session_bus_services_dir dbus-1`]) + +AC_ARG_WITH([dbussystemservicedir], + AS_HELP_STRING([--with-dbussystemservicedir=DIR], [D-Bus system service directory]), + [], + [with_dbussystemservicedir=`pkg-config --variable=session_bus_services_dir dbus-1`/../system-services]) + +AC_ARG_WITH([dbusinterfacedir], + AS_HELP_STRING([--with-dbusinterfacedir=DIR], [D-Bus interface directory]), + [], + [with_dbusinterfacedir=`pkg-config --variable=session_bus_services_dir dbus-1`/../interfaces]) + +AC_ARG_WITH([udevrulesdir], + AS_HELP_STRING([--with-udevrulesdir=DIR], [Directory for udev rules]), + [], + [with_udevrulesdir=`pkg-config --variable=udevdir udev`/rules.d]) + +AC_ARG_WITH([rootprefix], + AS_HELP_STRING([--with-rootprefix=DIR], [rootfs directory prefix for config files and kernel modules]), + [], [with_rootprefix=${ac_default_prefix}]) + +AC_ARG_WITH([rootlibdir], + AS_HELP_STRING([--with-rootlibdir=DIR], [Root directory for libraries necessary for boot]), + [], + [with_rootlibdir=${libdir}]) + +AC_ARG_WITH([pamlibdir], + AS_HELP_STRING([--with-pamlibdir=DIR], [Directory for PAM modules]), + [], + [with_pamlibdir=${with_rootlibdir}/security]) + +AC_ARG_ENABLE([split-usr], + AS_HELP_STRING([--enable-split-usr], [Assume that /bin, /sbin aren\'t symlinks into /usr]), + [], + [AS_IF([test "x${ac_default_prefix}" != "x${with_rootprefix}"], [ + enable_split_usr=yes + ], [ + enable_split_usr=no + ])]) + +AS_IF([test "x${enable_split_usr}" = "xyes"], [ + AC_DEFINE(HAVE_SPLIT_USR, 1, [Define if /bin, /sbin aren't symlinks into /usr]) +]) + +AC_SUBST([dbuspolicydir], [$with_dbuspolicydir]) +AC_SUBST([dbussessionservicedir], [$with_dbussessionservicedir]) +AC_SUBST([dbussystemservicedir], [$with_dbussystemservicedir]) +AC_SUBST([dbusinterfacedir], [$with_dbusinterfacedir]) +AC_SUBST([udevrulesdir], [$with_udevrulesdir]) +AC_SUBST([pamlibdir], [$with_pamlibdir]) +AC_SUBST([rootprefix], [$with_rootprefix]) +AC_SUBST([rootlibdir], [$with_rootlibdir]) + +AC_CONFIG_FILES([Makefile po/Makefile.in]) +AC_OUTPUT +AC_MSG_RESULT([ + $PACKAGE_NAME $VERSION + + Distribution: ${with_distro} + SysV compatibility: ${SYSTEM_SYSV_COMPAT} + SysV init scripts: ${SYSTEM_SYSVINIT_PATH} + SysV rc?.d directories: ${SYSTEM_SYSVRCND_PATH} + Gtk: ${have_gtk} + libcryptsetup: ${have_libcryptsetup} + tcpwrap: ${have_tcpwrap} + PAM: ${have_pam} + AUDIT: ${have_audit} + SELinux: ${have_selinux} + XZ: ${have_xz} + ACL: ${have_acl} + binfmt: ${have_binfmt} + vconsole: ${have_vconsole} + readahead: ${have_readahead} + quotacheck: ${have_quotacheck} + randomseed: ${have_randomseed} + logind: ${have_logind} + hostnamed: ${have_hostnamed} + timedated: ${have_timedated} + localed: ${have_localed} + coredump: ${have_coredump} + plymouth: ${have_plymouth} + prefix: ${prefix} + rootprefix: ${with_rootprefix} + libexec dir: ${libexecdir} + lib dir: ${libdir} + rootlib dir: ${with_rootlibdir} + PAM modules dir: ${with_pamlibdir} + udev rules dir: ${with_udevrulesdir} + D-Bus policy dir: ${with_dbuspolicydir} + D-Bus session dir: ${with_dbussessionservicedir} + D-Bus system dir: ${with_dbussystemservicedir} + D-Bus interfaces dir: ${with_dbusinterfacedir} + Split /usr: ${enable_split_usr} + Build man pages: ${have_manpages} +]) diff --git a/depcomp b/depcomp new file mode 100755 index 0000000..bd0ac08 --- /dev/null +++ b/depcomp @@ -0,0 +1,688 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2011-12-04.11; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test "$stat" = 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/ \1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/ / + G + p +}' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..a9244eb --- /dev/null +++ b/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-01-19.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for `test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/introspect.awk b/introspect.awk new file mode 100644 index 0000000..5931913 --- /dev/null +++ b/introspect.awk @@ -0,0 +1,13 @@ +BEGIN { + print "" + print "" +} + +// { + print +} + +END { + print "" +} diff --git a/libsystemd_basic_la_vala.stamp b/libsystemd_basic_la_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/libsystemd_basic_la_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/libsystemd_core_la_vala.stamp b/libsystemd_core_la_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/libsystemd_core_la_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/libsystemd_daemon_la_vala.stamp b/libsystemd_daemon_la_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/libsystemd_id128_la_vala.stamp b/libsystemd_id128_la_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/libsystemd_journal_la_vala.stamp b/libsystemd_journal_la_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/libsystemd_login_la_vala.stamp b/libsystemd_login_la_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/libsystemd_login_la_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/ltmain.sh b/ltmain.sh new file mode 100644 index 0000000..63ae69d --- /dev/null +++ b/ltmain.sh @@ -0,0 +1,9655 @@ + +# libtool (GNU libtool) 2.4.2 +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --no-quiet, --no-silent +# print informational messages (default) +# --no-warn don't display warning messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print more informational messages than default +# --no-verbose don't print the extra informational messages +# --version print version information +# -h, --help, --help-all print short, long, or detailed help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. When passed as first option, +# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.4.2 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . +# GNU libtool home page: . +# General help using GNU software: . + +PROGRAM=libtool +PACKAGE=libtool +VERSION=2.4.2 +TIMESTAMP="" +package_revision=1.3337 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# NLS nuisances: We save the old values to restore during execute mode. +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL + +$lt_unset CDPATH + + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + + + +: ${CP="cp -f"} +test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} # func_dirname may be replaced by extended shell implementation + + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} # func_basename may be replaced by extended shell implementation + + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` +} # func_dirname_and_basename may be replaced by extended shell implementation + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname may be replaced by extended shell implementation + + +# These SED scripts presuppose an absolute path with a trailing slash. +pathcar='s,^/\([^/]*\).*$,\1,' +pathcdr='s,^/[^/]*,,' +removedotparts=':dotsl + s@/\./@/@g + t dotsl + s,/\.$,/,' +collapseslashes='s@/\{1,\}@/@g' +finalslash='s,/*$,/,' + +# func_normal_abspath PATH +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +# value returned in "$func_normal_abspath_result" +func_normal_abspath () +{ + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` + while :; do + # Processed it all yet? + if test "$func_normal_abspath_tpath" = / ; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result" ; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + +# func_relative_path SRCDIR DSTDIR +# generates a relative path from SRCDIR to DSTDIR, with a trailing +# slash if non-empty, suitable for immediately appending a filename +# without needing to append a separator. +# value returned in "$func_relative_path_result" +func_relative_path () +{ + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=${func_dirname_result} + if test "x$func_relative_path_tlibdir" = x ; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test "x$func_stripname_result" != x ; then + func_relative_path_result=${func_relative_path_result}/${func_stripname_result} + fi + + # Normalisation. If bindir is libdir, return empty string, + # else relative path ending with a slash; either way, target + # file name can be directly appended. + if test ! -z "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result/" + func_relative_path_result=$func_stripname_result + fi +} + +# The name of this program: +func_dirname_and_basename "$progpath" +progname=$func_basename_result + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' + +# Sed substitution that converts a w32 file name or path +# which contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }$*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` + done + my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "$my_tmpdir" +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "$1" | $SED \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + +# func_tr_sh +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $opt_debug + + $SED -n '/(C)/!b go + :more + /\./!{ + N + s/\n# / / + b more + } + :go + /^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $opt_debug + + $SED -n '/^# Usage:/,/^# *.*--help/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + echo + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help [NOEXIT] +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $opt_debug + + $SED -n '/^# Usage:/,/# Report bugs to/ { + :print + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ + p + d + } + /^# .* home page:/b print + /^# General help using/b print + ' < "$progpath" + ret=$? + if test -z "$1"; then + exit $ret + fi +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $opt_debug + + func_error "missing argument for $1." + exit_cmd=exit +} + + +# func_split_short_opt shortopt +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +func_split_short_opt () +{ + my_sed_short_opt='1s/^\(..\).*$/\1/;q' + my_sed_short_rest='1s/^..\(.*\)$/\1/;q' + + func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` + func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` +} # func_split_short_opt may be replaced by extended shell implementation + + +# func_split_long_opt longopt +# Set func_split_long_opt_name and func_split_long_opt_arg shell +# variables after splitting LONGOPT at the `=' sign. +func_split_long_opt () +{ + my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' + my_sed_long_arg='1s/^--[^=]*=//' + + func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` + func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` +} # func_split_long_opt may be replaced by extended shell implementation + +exit_cmd=: + + + + + +magic="%%%MAGIC variable%%%" +magic_exe="%%%MAGIC EXE variable%%%" + +# Global variables. +nonopt= +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "${1}=\$${1}\${2}" +} # func_append may be replaced by extended shell implementation + +# func_append_quoted var value +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +func_append_quoted () +{ + func_quote_for_eval "${2}" + eval "${1}=\$${1}\\ \$func_quote_for_eval_result" +} # func_append_quoted may be replaced by extended shell implementation + + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "${@}"` +} # func_arith may be replaced by extended shell implementation + + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` +} # func_len may be replaced by extended shell implementation + + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} # func_lo2o may be replaced by extended shell implementation + + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} # func_xform may be replaced by extended shell implementation + + +# func_fatal_configuration arg... +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func_error ${1+"$@"} + func_error "See the $PACKAGE documentation for more information." + func_fatal_error "Fatal configuration error." +} + + +# func_config +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + +# func_features +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + +# func_enable_tag tagname +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname="$1" + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf="/$re_begincf/,/$re_endcf/p" + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# Shorthand for --mode=foo, only valid as the first argument +case $1 in +clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; +compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; +execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; +finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; +install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; +link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; +uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; +esac + + + +# Option defaults: +opt_debug=: +opt_dry_run=false +opt_config=false +opt_preserve_dup_deps=false +opt_features=false +opt_finish=false +opt_help=false +opt_help_all=false +opt_silent=: +opt_warning=: +opt_verbose=: +opt_silent=false +opt_verbose=false + + +# Parse options once, thoroughly. This comes as soon as possible in the +# script to make things like `--version' happen as quickly as we can. +{ + # this just eases exit handling + while test $# -gt 0; do + opt="$1" + shift + case $opt in + --debug|-x) opt_debug='set -x' + func_echo "enabling shell trace mode" + $opt_debug + ;; + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + --config) + opt_config=: +func_config + ;; + --dlopen|-dlopen) + optarg="$1" + opt_dlopen="${opt_dlopen+$opt_dlopen +}$optarg" + shift + ;; + --preserve-dup-deps) + opt_preserve_dup_deps=: + ;; + --features) + opt_features=: +func_features + ;; + --finish) + opt_finish=: +set dummy --mode finish ${1+"$@"}; shift + ;; + --help) + opt_help=: + ;; + --help-all) + opt_help_all=: +opt_help=': help-all' + ;; + --mode) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_mode="$optarg" +case $optarg in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; +esac + shift + ;; + --no-silent|--no-quiet) + opt_silent=false +func_append preserve_args " $opt" + ;; + --no-warning|--no-warn) + opt_warning=false +func_append preserve_args " $opt" + ;; + --no-verbose) + opt_verbose=false +func_append preserve_args " $opt" + ;; + --silent|--quiet) + opt_silent=: +func_append preserve_args " $opt" + opt_verbose=false + ;; + --verbose|-v) + opt_verbose=: +func_append preserve_args " $opt" +opt_silent=false + ;; + --tag) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_tag="$optarg" +func_append preserve_args " $opt $optarg" +func_enable_tag "$optarg" + shift + ;; + + -\?|-h) func_usage ;; + --help) func_help ;; + --version) func_version ;; + + # Separate optargs to long options: + --*=*) + func_split_long_opt "$opt" + set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-n*|-v*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognized option \`$opt'" ;; + *) set dummy "$opt" ${1+"$@"}; shift; break ;; + esac + done + + # Validate options: + + # save first non-option argument + if test "$#" -gt 0; then + nonopt="$opt" + shift + fi + + # preserve --debug + test "$opt_debug" = : || func_append preserve_args " --debug" + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test "$opt_mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$opt_mode' for more information." + } + + + # Bail if the options were screwed + $exit_cmd $EXIT_FAILURE +} + + + + +## ----------- ## +## Main. ## +## ----------- ## + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case "$lt_sysroot:$1" in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result="=$func_stripname_result" + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$lt_sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $opt_debug + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result="" + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $opt_debug + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $opt_debug + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $opt_debug + if test -z "$2" && test -n "$1" ; then + func_error "Could not determine host file name corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result="$1" + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $opt_debug + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " \`$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result="$3" + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $opt_debug + case $4 in + $1 ) func_to_host_path_result="$3$func_to_host_path_result" + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via `$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $opt_debug + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $opt_debug + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result="$1" +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result="$func_convert_core_msys_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via `$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $opt_debug + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd="func_convert_path_${func_stripname_result}" + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $opt_debug + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result="$1" +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_mode_compile arg... +func_mode_compile () +{ + $opt_debug + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify \`-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + func_append_quoted lastarg "$arg" + done + IFS="$save_ifs" + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with \`-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj="$func_basename_result" + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from \`$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test "$opt_mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$opt_mode'" + ;; + esac + + echo + $ECHO "Try \`$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test "$opt_help" = :; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | sed -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + sed '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "\`$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument \`$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test "$opt_mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test "x$prev" = x-m && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename="" + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname" ; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename="$func_basename_result" + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename" ; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $opt_debug + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $opt_debug + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive which possess that section. Heuristic: eliminate + # all those which have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $opt_debug + if func_cygming_gnu_implib_p "$1" ; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1" ; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result="" + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + if test "$lock_old_archive_extraction" = yes; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test "$lock_old_archive_extraction" = yes; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ which is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/* declarations of non-ANSI functions */ +#if defined(__MINGW32__) +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined(__CYGWIN__) +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined (other platforms) ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined(_MSC_VER) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +# ifndef _INTPTR_T_DEFINED +# define _INTPTR_T_DEFINED +# define intptr_t int +# endif +#elif defined(__MINGW32__) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined(__CYGWIN__) +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined (other platforms) ... */ +#endif + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#if defined(LT_DEBUGWRAPPER) +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $opt_debug + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps ; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + else + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test "$prefer_static_libs" = yes || + test "$prefer_static_libs,$installed" = "built,no"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib="$l" + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$lt_sysroot$libdir" + absdir="$lt_sysroot$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + case "$host" in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + echo + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$opt_mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$absdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$opt_mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|qnx|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + func_append verstring ":${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + func_append libobjs " $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$opt_mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + # Remove ${wl} instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd1 in $cmds; do + IFS="$save_ifs" + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test "$try_normal_branch" = yes \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=${output_objdir}/${output_la}.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " ${wl}-bind_at_load" + func_append finalize_command " ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + func_append oldobjs " $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + func_resolve_sysroot "$deplib" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$opt_mode" = link || test "$opt_mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=yes ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + odir="$objdir" + else + odir="$dir/$objdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$opt_mode" = uninstall && odir="$dir" + + # Remember odir for removal later, being careful to avoid duplicates + if test "$opt_mode" = clean; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case "$opt_mode" in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$opt_mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + func_append rmfiles " $odir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$opt_mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/m4/acx_libwrap.m4 b/m4/acx_libwrap.m4 new file mode 100644 index 0000000..ccf8afc --- /dev/null +++ b/m4/acx_libwrap.m4 @@ -0,0 +1,19 @@ +AC_DEFUN([ACX_LIBWRAP], [ +LIBWRAP_LIBS= +saved_LIBS="$LIBS" +LIBS="$LIBS -lwrap" +AC_MSG_CHECKING([for tcpwrap library and headers]) +AC_LINK_IFELSE( +[AC_LANG_PROGRAM( +[#include +#include +int allow_severity = LOG_INFO; +int deny_severity = LOG_WARNING;], +[struct request_info *req; +return hosts_access (req);])], +[AC_DEFINE(HAVE_LIBWRAP, [], [Have tcpwrap?]) +LIBWRAP_LIBS="-lwrap" +AC_MSG_RESULT(yes)], +[AC_MSG_RESULT(no)]) +LIBS="$saved_LIBS" +]) diff --git a/m4/attributes.m4 b/m4/attributes.m4 new file mode 100644 index 0000000..9d561c2 --- /dev/null +++ b/m4/attributes.m4 @@ -0,0 +1,311 @@ +dnl Macros to check the presence of generic (non-typed) symbols. +dnl Copyright (c) 2006-2008 Diego Pettenò +dnl Copyright (c) 2006-2008 xine project +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +dnl 02110-1301, USA. +dnl +dnl As a special exception, the copyright owners of the +dnl macro gives unlimited permission to copy, distribute and modify the +dnl configure scripts that are the output of Autoconf when processing the +dnl Macro. You need not follow the terms of the GNU General Public +dnl License when using or distributing such scripts, even though portions +dnl of the text of the Macro appear in them. The GNU General Public +dnl License (GPL) does govern all other use of the material that +dnl constitutes the Autoconf Macro. +dnl +dnl This special exception to the GPL applies to versions of the +dnl Autoconf Macro released by this project. When you make and +dnl distribute a modified version of the Autoconf Macro, you may extend +dnl this special exception to the GPL to apply to your modified version as +dnl well. + +dnl Check if the flag is supported by compiler +dnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) + +AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [ + AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]), + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $1" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])], + [eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_cflags_$1])='no'"]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], + [$2], [$3]) +]) + +dnl Check if the flag is supported by compiler (cacheable) +dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) + +AC_DEFUN([CC_CHECK_CFLAGS], [ + AC_CACHE_CHECK([if $CC supports $1 flag], + AS_TR_SH([cc_cv_cflags_$1]), + CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! + ) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], + [$2], [$3]) +]) + +dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found]) +dnl Check for CFLAG and appends them to CFLAGS if supported +AC_DEFUN([CC_CHECK_CFLAG_APPEND], [ + AC_CACHE_CHECK([if $CC supports $1 flag], + AS_TR_SH([cc_cv_cflags_$1]), + CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! + ) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], + [CFLAGS="$CFLAGS $1"; DEBUG_CFLAGS="$DEBUG_CFLAGS $1"; $2], [$3]) +]) + +dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not]) +AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [ + for flag in $1; do + CC_CHECK_CFLAG_APPEND($flag, [$2], [$3]) + done +]) + +dnl Check if the flag is supported by linker (cacheable) +dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) + +AC_DEFUN([CC_CHECK_LDFLAGS], [ + AC_CACHE_CHECK([if $CC supports $1 flag], + AS_TR_SH([cc_cv_ldflags_$1]), + [ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $1" + AC_LINK_IFELSE([int main() { return 1; }], + [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_ldflags_$1])="]) + LDFLAGS="$ac_save_LDFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes], + [$2], [$3]) +]) + +dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for +dnl the current linker to avoid undefined references in a shared object. +AC_DEFUN([CC_NOUNDEFINED], [ + dnl We check $host for which systems to enable this for. + AC_REQUIRE([AC_CANONICAL_HOST]) + + case $host in + dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads + dnl are requested, as different implementations are present; to avoid problems + dnl use -Wl,-z,defs only for those platform not behaving this way. + *-freebsd* | *-openbsd*) ;; + *) + dnl First of all check for the --no-undefined variant of GNU ld. This allows + dnl for a much more readable commandline, so that people can understand what + dnl it does without going to look for what the heck -z defs does. + for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do + CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"]) + break + done + ;; + esac + + AC_SUBST([LDFLAGS_NOUNDEFINED]) +]) + +dnl Check for a -Werror flag or equivalent. -Werror is the GCC +dnl and ICC flag that tells the compiler to treat all the warnings +dnl as fatal. We usually need this option to make sure that some +dnl constructs (like attributes) are not simply ignored. +dnl +dnl Other compilers don't support -Werror per se, but they support +dnl an equivalent flag: +dnl - Sun Studio compiler supports -errwarn=%all +AC_DEFUN([CC_CHECK_WERROR], [ + AC_CACHE_CHECK( + [for $CC way to treat warnings as errors], + [cc_cv_werror], + [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror], + [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])]) + ]) +]) + +AC_DEFUN([CC_CHECK_ATTRIBUTE], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))], + AS_TR_SH([cc_cv_attribute_$1]), + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])], + [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes], + [AC_DEFINE( + AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1, + [Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))] + ) + $4], + [$5]) +]) + +AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [ + CC_CHECK_ATTRIBUTE( + [constructor],, + [void __attribute__((constructor)) ctor() { int a; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_FORMAT], [ + CC_CHECK_ATTRIBUTE( + [format], [format(printf, n, n)], + [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [ + CC_CHECK_ATTRIBUTE( + [format_arg], [format_arg(printf)], + [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [ + CC_CHECK_ATTRIBUTE( + [visibility_$1], [visibility("$1")], + [void __attribute__((visibility("$1"))) $1_function() { }], + [$2], [$3]) +]) + +AC_DEFUN([CC_ATTRIBUTE_NONNULL], [ + CC_CHECK_ATTRIBUTE( + [nonnull], [nonnull()], + [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_UNUSED], [ + CC_CHECK_ATTRIBUTE( + [unused], , + [void some_function(void *foo, __attribute__((unused)) void *bar);], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [ + CC_CHECK_ATTRIBUTE( + [sentinel], , + [void some_function(void *foo, ...) __attribute__((sentinel));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [ + CC_CHECK_ATTRIBUTE( + [deprecated], , + [void some_function(void *foo, ...) __attribute__((deprecated));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_ALIAS], [ + CC_CHECK_ATTRIBUTE( + [alias], [weak, alias], + [void other_function(void *foo) { } + void some_function(void *foo) __attribute__((weak, alias("other_function")));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_MALLOC], [ + CC_CHECK_ATTRIBUTE( + [malloc], , + [void * __attribute__((malloc)) my_alloc(int n);], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_PACKED], [ + CC_CHECK_ATTRIBUTE( + [packed], , + [struct astructure { char a; int b; long c; void *d; } __attribute__((packed));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_CONST], [ + CC_CHECK_ATTRIBUTE( + [const], , + [int __attribute__((const)) twopow(int n) { return 1 << n; } ], + [$1], [$2]) +]) + +AC_DEFUN([CC_FLAG_VISIBILITY], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if $CC supports -fvisibility=hidden], + [cc_cv_flag_visibility], + [cc_flag_visibility_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden], + cc_cv_flag_visibility='yes', + cc_cv_flag_visibility='no') + CFLAGS="$cc_flag_visibility_save_CFLAGS"]) + + AS_IF([test "x$cc_cv_flag_visibility" = "xyes"], + [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1, + [Define this if the compiler supports the -fvisibility flag]) + $1], + [$2]) +]) + +AC_DEFUN([CC_FUNC_EXPECT], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if compiler has __builtin_expect function], + [cc_cv_func_expect], + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + AC_COMPILE_IFELSE([AC_LANG_SOURCE( + [int some_function() { + int a = 3; + return (int)__builtin_expect(a, 3); + }])], + [cc_cv_func_expect=yes], + [cc_cv_func_expect=no]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([test "x$cc_cv_func_expect" = "xyes"], + [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1, + [Define this if the compiler supports __builtin_expect() function]) + $1], + [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported], + [cc_cv_attribute_aligned], + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + for cc_attribute_align_try in 64 32 16 8 4 2; do + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + int main() { + static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0; + return c; + }])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break]) + done + CFLAGS="$ac_save_CFLAGS" + ]) + + if test "x$cc_cv_attribute_aligned" != "x"; then + AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned], + [Define the highest alignment supported]) + fi +]) diff --git a/m4/intltool.m4 b/m4/intltool.m4 new file mode 100644 index 0000000..07af68b --- /dev/null +++ b/m4/intltool.m4 @@ -0,0 +1,216 @@ +## intltool.m4 - Configure intltool for the target system. -*-Shell-script-*- +## Copyright (C) 2001 Eazel, Inc. +## Author: Maciej Stachowiak +## Kenneth Christiansen +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +## As a special exception to the GNU General Public License, if you +## distribute this file as part of a program that contains a +## configuration script generated by Autoconf, you may include it under +## the same distribution terms that you use for the rest of that program. + +dnl IT_PROG_INTLTOOL([MINIMUM-VERSION], [no-xml]) +# serial 40 IT_PROG_INTLTOOL +AC_DEFUN([IT_PROG_INTLTOOL], [ +AC_PREREQ([2.50])dnl +AC_REQUIRE([AM_NLS])dnl + +case "$am__api_version" in + 1.[01234]) + AC_MSG_ERROR([Automake 1.5 or newer is required to use intltool]) + ;; + *) + ;; +esac + +if test -n "$1"; then + AC_MSG_CHECKING([for intltool >= $1]) + + INTLTOOL_REQUIRED_VERSION_AS_INT=`echo $1 | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'` + INTLTOOL_APPLIED_VERSION=`intltool-update --version | head -1 | cut -d" " -f3` + [INTLTOOL_APPLIED_VERSION_AS_INT=`echo $INTLTOOL_APPLIED_VERSION | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'` + ] + AC_MSG_RESULT([$INTLTOOL_APPLIED_VERSION found]) + test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT" || + AC_MSG_ERROR([Your intltool is too old. You need intltool $1 or later.]) +fi + +AC_PATH_PROG(INTLTOOL_UPDATE, [intltool-update]) +AC_PATH_PROG(INTLTOOL_MERGE, [intltool-merge]) +AC_PATH_PROG(INTLTOOL_EXTRACT, [intltool-extract]) +if test -z "$INTLTOOL_UPDATE" -o -z "$INTLTOOL_MERGE" -o -z "$INTLTOOL_EXTRACT"; then + AC_MSG_ERROR([The intltool scripts were not found. Please install intltool.]) +fi + + INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' +INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -p $(top_srcdir)/po $< [$]@' + INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' +INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u --no-translations $< [$]@' + INTLTOOL_XAM_RULE='%.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_KBD_RULE='%.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_SERVICE_RULE='%.service: %.service.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + INTLTOOL_POLICY_RULE='%.policy: %.policy.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' + +_IT_SUBST(INTLTOOL_DESKTOP_RULE) +_IT_SUBST(INTLTOOL_DIRECTORY_RULE) +_IT_SUBST(INTLTOOL_KEYS_RULE) +_IT_SUBST(INTLTOOL_PROP_RULE) +_IT_SUBST(INTLTOOL_OAF_RULE) +_IT_SUBST(INTLTOOL_PONG_RULE) +_IT_SUBST(INTLTOOL_SERVER_RULE) +_IT_SUBST(INTLTOOL_SHEET_RULE) +_IT_SUBST(INTLTOOL_SOUNDLIST_RULE) +_IT_SUBST(INTLTOOL_UI_RULE) +_IT_SUBST(INTLTOOL_XAM_RULE) +_IT_SUBST(INTLTOOL_KBD_RULE) +_IT_SUBST(INTLTOOL_XML_RULE) +_IT_SUBST(INTLTOOL_XML_NOMERGE_RULE) +_IT_SUBST(INTLTOOL_CAVES_RULE) +_IT_SUBST(INTLTOOL_SCHEMAS_RULE) +_IT_SUBST(INTLTOOL_THEME_RULE) +_IT_SUBST(INTLTOOL_SERVICE_RULE) +_IT_SUBST(INTLTOOL_POLICY_RULE) + +# Check the gettext tools to make sure they are GNU +AC_PATH_PROG(XGETTEXT, xgettext) +AC_PATH_PROG(MSGMERGE, msgmerge) +AC_PATH_PROG(MSGFMT, msgfmt) +AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) +if test -z "$XGETTEXT" -o -z "$MSGMERGE" -o -z "$MSGFMT"; then + AC_MSG_ERROR([GNU gettext tools not found; required for intltool]) +fi +xgversion="`$XGETTEXT --version|grep '(GNU ' 2> /dev/null`" +mmversion="`$MSGMERGE --version|grep '(GNU ' 2> /dev/null`" +mfversion="`$MSGFMT --version|grep '(GNU ' 2> /dev/null`" +if test -z "$xgversion" -o -z "$mmversion" -o -z "$mfversion"; then + AC_MSG_ERROR([GNU gettext tools not found; required for intltool]) +fi + +AC_PATH_PROG(INTLTOOL_PERL, perl) +if test -z "$INTLTOOL_PERL"; then + AC_MSG_ERROR([perl not found]) +fi +AC_MSG_CHECKING([for perl >= 5.8.1]) +$INTLTOOL_PERL -e "use 5.8.1;" > /dev/null 2>&1 +if test $? -ne 0; then + AC_MSG_ERROR([perl 5.8.1 is required for intltool]) +else + IT_PERL_VERSION=`$INTLTOOL_PERL -e "printf '%vd', $^V"` + AC_MSG_RESULT([$IT_PERL_VERSION]) +fi +if test "x$2" != "xno-xml"; then + AC_MSG_CHECKING([for XML::Parser]) + if `$INTLTOOL_PERL -e "require XML::Parser" 2>/dev/null`; then + AC_MSG_RESULT([ok]) + else + AC_MSG_ERROR([XML::Parser perl module is required for intltool]) + fi +fi + +# Substitute ALL_LINGUAS so we can use it in po/Makefile +AC_SUBST(ALL_LINGUAS) + +# Set DATADIRNAME correctly if it is not set yet +# (copied from glib-gettext.m4) +if test -z "$DATADIRNAME"; then + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[]], + [[extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr]])], + [DATADIRNAME=share], + [case $host in + *-*-solaris*) + dnl On Solaris, if bind_textdomain_codeset is in libc, + dnl GNU format message catalog is always supported, + dnl since both are added to the libc all together. + dnl Hence, we'd like to go with DATADIRNAME=share + dnl in this case. + AC_CHECK_FUNC(bind_textdomain_codeset, + [DATADIRNAME=share], [DATADIRNAME=lib]) + ;; + *) + [DATADIRNAME=lib] + ;; + esac]) +fi +AC_SUBST(DATADIRNAME) + +IT_PO_SUBDIR([po]) + +]) + + +# IT_PO_SUBDIR(DIRNAME) +# --------------------- +# All po subdirs have to be declared with this macro; the subdir "po" is +# declared by IT_PROG_INTLTOOL. +# +AC_DEFUN([IT_PO_SUBDIR], +[AC_PREREQ([2.53])dnl We use ac_top_srcdir inside AC_CONFIG_COMMANDS. +dnl +dnl The following CONFIG_COMMANDS should be executed at the very end +dnl of config.status. +AC_CONFIG_COMMANDS_PRE([ + AC_CONFIG_COMMANDS([$1/stamp-it], [ + if [ ! grep "^# INTLTOOL_MAKEFILE$" "$1/Makefile.in" > /dev/null ]; then + AC_MSG_ERROR([$1/Makefile.in.in was not created by intltoolize.]) + fi + rm -f "$1/stamp-it" "$1/stamp-it.tmp" "$1/POTFILES" "$1/Makefile.tmp" + >"$1/stamp-it.tmp" + [sed '/^#/d + s/^[[].*] *// + /^[ ]*$/d + '"s|^| $ac_top_srcdir/|" \ + "$srcdir/$1/POTFILES.in" | sed '$!s/$/ \\/' >"$1/POTFILES" + ] + [sed '/^POTFILES =/,/[^\\]$/ { + /^POTFILES =/!d + r $1/POTFILES + } + ' "$1/Makefile.in" >"$1/Makefile"] + rm -f "$1/Makefile.tmp" + mv "$1/stamp-it.tmp" "$1/stamp-it" + ]) +])dnl +]) + +# _IT_SUBST(VARIABLE) +# ------------------- +# Abstract macro to do either _AM_SUBST_NOTMAKE or AC_SUBST +# +AC_DEFUN([_IT_SUBST], +[ +AC_SUBST([$1]) +m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([$1])]) +] +) + +# deprecated macros +AU_ALIAS([AC_PROG_INTLTOOL], [IT_PROG_INTLTOOL]) +# A hint is needed for aclocal from Automake <= 1.9.4: +# AC_DEFUN([AC_PROG_INTLTOOL], ...) + diff --git a/m4/libtool.m4 b/m4/libtool.m4 new file mode 100644 index 0000000..56666f0 --- /dev/null +++ b/m4/libtool.m4 @@ -0,0 +1,7986 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Add ABI-specific directories to the system library path. + sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4 new file mode 100644 index 0000000..5d9acd8 --- /dev/null +++ b/m4/ltoptions.m4 @@ -0,0 +1,384 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/m4/ltsugar.m4 b/m4/ltsugar.m4 new file mode 100644 index 0000000..9000a05 --- /dev/null +++ b/m4/ltsugar.m4 @@ -0,0 +1,123 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/m4/ltversion.m4 b/m4/ltversion.m4 new file mode 100644 index 0000000..07a8602 --- /dev/null +++ b/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 3337 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.2]) +m4_define([LT_PACKAGE_REVISION], [1.3337]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.2' +macro_revision='1.3337' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/m4/lt~obsolete.m4 b/m4/lt~obsolete.m4 new file mode 100644 index 0000000..c573da9 --- /dev/null +++ b/m4/lt~obsolete.m4 @@ -0,0 +1,98 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/man/binfmt.d.5 b/man/binfmt.d.5 new file mode 100644 index 0000000..600a6de --- /dev/null +++ b/man/binfmt.d.5 @@ -0,0 +1,94 @@ +'\" t +.\" Title: binfmt.d +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: binfmt.d +.\" Source: systemd +.\" Language: English +.\" +.TH "BINFMT\&.D" "5" "02/15/2012" "systemd" "binfmt.d" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +binfmt.d \- Configure additional binary formats at boot +.SH "SYNOPSIS" +.PP +/usr/lib/binfmt\&.d/*\&.conf +.PP +/etc/binfmt\&.d/*\&.conf +.PP +/run/binfmt\&.d/*\&.conf +.SH "DESCRIPTION" +.PP +\fBsystemd\fR +uses files from the above directories to configure additional binary formats to register during boot in the kernel\&. +.SH "CONFIGURATION FORMAT" +.PP +Each file contains a list of binfmt_misc kernel binary format rules\&. Consult +\m[blue]\fBbinfmt_misc\&.txt\fR\m[]\&\s-2\u[1]\d\s+2 +for more information on registration of additional binary formats and how to write rules\&. +.PP +Empty lines and lines beginning with ; and # are ignored\&. Note that this means you may not use ; and # as delimiter in binary format rules\&. +.PP +Each configuration file is named in the style of +\&.conf\&. Files in +/etc/ +overwrite files with the same name in +/usr/lib/\&. Files in +/run +overwrite files with the same name in +/etc/ +and +/usr/lib/\&. Packages should install their configuration files in +/usr/lib/, files in +/etc/ +are reserved for the local administration, which possibly decides to overwrite the configurations installed from packages\&. All files are sorted by filename in alphabetical order, regardless in which of the directories they reside, to ensure that a specific configuration file takes precedence over another file with an alphabetically later name\&. +.SH "EXAMPLE" +.PP +\fBExample\ \&1.\ \&/etc/binfmt.d/wine.conf example:\fR +.sp +.if n \{\ +.RS 4 +.\} +.nf +# Start WINE on Windows executables +:DOSWin:M::MZ::/usr/bin/wine: +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBwine\fR(8) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE +.SH "NOTES" +.IP " 1." 4 +binfmt_misc.txt +.RS 4 +\%http://www.kernel.org/doc/Documentation/binfmt_misc.txt +.RE diff --git a/man/binfmt.d.xml b/man/binfmt.d.xml new file mode 100644 index 0000000..966778d --- /dev/null +++ b/man/binfmt.d.xml @@ -0,0 +1,111 @@ + + + + + + + + binfmt.d + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + binfmt.d + 5 + + + + binfmt.d + Configure additional binary formats at boot + + + + /usr/lib/binfmt.d/*.conf + /etc/binfmt.d/*.conf + /run/binfmt.d/*.conf + + + + Description + + systemd uses + files from the above directories to configure + additional binary formats to register during boot in + the kernel. + + + + Configuration Format + + Each file contains a list of binfmt_misc kernel + binary format rules. Consult binfmt_misc.txt + for more information on registration of additional + binary formats and how to write rules. + + Empty lines and lines beginning with ; and # are + ignored. Note that this means you may not use ; and # + as delimiter in binary format rules. + + Each configuration file is named in the style of + <program>.conf. + Files in /etc/ overwrite + files with the same name in /usr/lib/. + Files in /run overwrite files with + the same name in /etc/ and + /usr/lib/. Packages should install their + configuration files in /usr/lib/, files + in /etc/ are reserved for the local + administration, which possibly decides to overwrite the + configurations installed from packages. All files are sorted + by filename in alphabetical order, regardless in which of the + directories they reside, to ensure that a specific + configuration file takes precedence over another file with + an alphabetically later name. + + + + Example + + /etc/binfmt.d/wine.conf example: + + # Start WINE on Windows executables +:DOSWin:M::MZ::/usr/bin/wine: + + + + + See Also + + systemd1, + wine8 + + + + diff --git a/man/custom-html.xsl b/man/custom-html.xsl new file mode 100644 index 0000000..2d2f458 --- /dev/null +++ b/man/custom-html.xsl @@ -0,0 +1,29 @@ + + + + + + + + + + + + diff --git a/man/daemon.7 b/man/daemon.7 new file mode 100644 index 0000000..5faf5f5 --- /dev/null +++ b/man/daemon.7 @@ -0,0 +1,787 @@ +'\" t +.\" Title: daemon +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: daemon +.\" Source: systemd +.\" Language: English +.\" +.TH "DAEMON" "7" "02/15/2012" "systemd" "daemon" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +daemon \- Writing and Packaging System Daemons +.SH "DESCRIPTION" +.PP +A daemon is a service process that runs in the background and supervises the system or provides functionality to other processes\&. Traditionally, daemons are implemented following a scheme originating in SysV Unix\&. Modern daemons should follow a simpler yet more powerful scheme (here called "new\-style" daemons), as implemented by +\fBsystemd\fR(1)\&. This manual page covers both schemes, and in particular includes recommendations for daemons that shall be included in the systemd init system\&. +.SS "SysV Daemons" +.PP +When a traditional SysV daemon starts, it should execute the following steps as part of the initialization\&. Note that these steps are unnecessary for new\-style daemons (see below), and should only be implemented if compatibility with SysV is essential\&. +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 1." 4.2 +.\} +Close all open file descriptors except STDIN, STDOUT, STDERR (i\&.e\&. the first three file descriptors 0, 1, 2)\&. This ensures that no accidentally passed file descriptor stays around in the daemon process\&. On Linux this is best implemented by iterating through +/proc/self/fd, with a fallback of iterating from file descriptor 3 to the value returned by +\fBgetrlimit()\fR +for RLIMIT_NOFILE\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 2." 4.2 +.\} +Reset all signal handlers to their default\&. This is best done by iterating through the available signals up to the limit of _NSIG and resetting them to SIG_DFL\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 3." 4.2 +.\} +Reset the signal mask using +\fBsigprocmask()\fR\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 4.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 4." 4.2 +.\} +Sanitize the environment block, removing or resetting environment variables that might negatively impact daemon runtime\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 5.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 5." 4.2 +.\} +Call +\fBfork()\fR, to create a background process\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 6.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 6." 4.2 +.\} +In the child, call +\fBsetsid()\fR +to detach from any terminal and create an independent session\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 7.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 7." 4.2 +.\} +In the child, call +\fBfork()\fR +again, to ensure the daemon can never re\-acquire a terminal again\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 8.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 8." 4.2 +.\} +Call +\fBexit()\fR +in the first child, so that only the second child (the actual daemon process) stays around\&. This ensures that the daemon process is reparented to init/PID 1, as all daemons should be\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 9.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 9." 4.2 +.\} +In the daemon process, connect +/dev/null +to STDIN, STDOUT, STDERR\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'10.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP "10." 4.2 +.\} +In the daemon process, reset the umask to 0, so that the file modes passed to +\fBopen()\fR, +\fBmkdir()\fR +and suchlike directly control the access mode of the created files and directories\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'11.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP "11." 4.2 +.\} +In the daemon process, change the current directory to the root directory (/), in order to avoid that the daemon involuntarily blocks mount points from being unmounted\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'12.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP "12." 4.2 +.\} +In the daemon process, write the daemon PID (as returned by +\fBgetpid()\fR) to a PID file, for example +/var/run/foobar\&.pid +(for a hypothetical daemon "foobar"), to ensure that the daemon cannot be started more than once\&. This must be implemented in race\-free fashion so that the PID file is only updated when at the same time it is verified that the PID previously stored in the PID file no longer exists or belongs to a foreign process\&. Commonly some kind of file locking is employed to implement this logic\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'13.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP "13." 4.2 +.\} +In the daemon process, drop privileges, if possible and applicable\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'14.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP "14." 4.2 +.\} +From the daemon process notify the original process started that initialization is complete\&. This can be implemented via an unnamed pipe or similar communication channel that is created before the first +\fBfork()\fR +and hence available in both the original and the daemon process\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'15.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP "15." 4.2 +.\} +Call +\fBexit()\fR +in the original process\&. The process that invoked the daemon must be able to rely that this +\fBexit()\fR +happens after initialization is complete and all external communication channels established and accessible\&. +.RE +.PP +The BSD +\fBdaemon()\fR +function should not be used, as it implements only a subset of these steps\&. +.PP +A daemon that needs to provide compatibility with SysV systems should implement the scheme pointed out above\&. However, it is recommended to make this behaviour optional and configurable via a command line argument, to ease debugging as well as to simplify integration into systems using systemd\&. +.SS "New\-Style Daemons" +.PP +Modern services for Linux should be implemented as new\-style daemons\&. This makes it easier to supervise and control them at runtime and simplifies their implementation\&. +.PP +For developing a new\-style daemon none of the initialization steps recommended for SysV daemons need to be implemented\&. New\-style init systems such as systemd make all of them redundant\&. Moreover, since some of these steps interfere with process monitoring, file descriptor passing and other functionality of the init system it is recommended not to execute them when run as new\-style service\&. +.PP +Note that new\-style init systems guarantee execution of daemon processes in clean process contexts: it is guaranteed that the environment block is sanitized, that the signal handlers and mask is reset and that no left\-over file descriptors are passed\&. Daemons will be executed in their own session, and STDIN/STDOUT/STDERR connected to +/dev/null +unless otherwise configured\&. The umask is reset\&. +.PP +It is recommended for new\-style daemons to implement the following: +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 1." 4.2 +.\} +If SIGTERM is received, shut down the daemon and exit cleanly\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 2." 4.2 +.\} +If SIGHUP is received, reload the configuration files, if this applies\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 3." 4.2 +.\} +Provide a correct exit code from the main daemon process, as this is used by the init system to detect service errors and problems\&. It is recommended to follow the exit code scheme as defined in the +\m[blue]\fBLSB recommendations for SysV init scripts\fR\m[]\&\s-2\u[1]\d\s+2\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 4.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 4." 4.2 +.\} +If possible and applicable expose the daemon\*(Aqs control interface via the D\-Bus IPC system and grab a bus name as last step of initialization\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 5.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 5." 4.2 +.\} +For integration in systemd, provide a +\&.service +unit file that carries information about starting, stopping and otherwise maintaining the daemon\&. See +\fBsystemd.service\fR(5) +for details\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 6.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 6." 4.2 +.\} +As much as possible, rely on the init systemd\*(Aqs functionality to limit the access of the daemon to files, services and other resources\&. i\&.e\&. in the case of systemd, rely on systemd\*(Aqs resource limit control instead of implementing your own, rely on systemd\*(Aqs privilege dropping code instead of implementing it in the daemon, and similar\&. See +\fBsystemd.exec\fR(5) +for the available controls\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 7.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 7." 4.2 +.\} +If D\-Bus is used, make your daemon bus\-activatable, via supplying a D\-Bus service activation configuration file\&. This has multiple advantages: your daemon may be started lazily on\-demand; it may be started in parallel to other daemons requiring it \-\- which maximizes parallelization and boot\-up speed; your daemon can be restarted on failure, without losing any bus requests, as the bus queues requests for activatable services\&. See below for details\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 8.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 8." 4.2 +.\} +If your daemon provides services to other local processes or remote clients via a socket, it should be made socket\-activatable following the scheme pointed out below\&. Like D\-Bus activation this enables on\-demand starting of services as well as it allows improved parallelization of service start\-up\&. Also, for state\-less protocols (such as syslog, DNS) a daemon implementing socket\-based activation can be restarted without losing a single request\&. See below for details\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 9.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 9." 4.2 +.\} +If applicable a daemon should notify the init system about startup completion or status updates via the +\fBsd_notify\fR(3) +interface\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'10.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP "10." 4.2 +.\} +Instead of using the +\fBsyslog()\fR +call to log directly to the system syslog service, a new\-style daemon may choose to simply log to STDERR via +\fBfprintf()\fR, which is then forwarded to syslog by the init system\&. If log priorities are necessary these can be encoded by prefixing individual log lines with strings like "<4>" (for log priority 4 "WARNING" in the syslog priority scheme), following a similar style as the Linux kernel\*(Aqs +\fBprintk()\fR +priority system\&. In fact, using this style of logging also enables the init system to optionally direct all application logging to the kernel log buffer (kmsg), as accessible via +\fBdmesg\fR(1)\&. This kind of logging may be enabled by setting +\fIStandardError=syslog\fR +in the service unit file\&. For details see +\fBsd-daemon\fR(7) +and +\fBsystemd.exec\fR(5)\&. +.RE +.PP +These recommendations are similar but not identical to the +\m[blue]\fBApple MacOS X Daemon Requirements\fR\m[]\&\s-2\u[2]\d\s+2\&. +.SH "ACTIVATION" +.PP +New\-style init systems provide multiple additional mechanisms to activate services, as detailed below\&. It is common that services are configured to be activated via more than one mechanism at the same time\&. An example for systemd: +bluetoothd\&.service +might get activated either when Bluetooth hardware is plugged in, or when an application accesses its programming interfaces via D\-Bus\&. Or, a print server daemon might get activated when traffic arrives at an IPP port, or when a printer is plugged in, or when a file is queued in the printer spool directory\&. Even for services that are intended to be started on system bootup unconditionally it is a good idea to implement some of the various activation schemes outlined below, in order to maximize parallelization: if a daemon implements a D\-Bus service or listening socket, implementing the full bus and socket activation scheme allows starting of the daemon with its clients in parallel (which speeds up boot\-up), since all its communication channels are established already, and no request is lost because client requests will be queued by the bus system (in case of D\-Bus) or the kernel (in case of sockets), until the activation is completed\&. +.SS "Activation on Boot" +.PP +Old\-style daemons are usually activated exclusively on boot (and manually by the administrator) via SysV init scripts, as detailed in the +\m[blue]\fBLSB Linux Standard Base Core Specification\fR\m[]\&\s-2\u[1]\d\s+2\&. This method of activation is supported ubiquitously on Linux init systems, both old\-style and new\-style systems\&. Among other issues SysV init scripts have the disadvantage of involving shell scripts in the boot process\&. New\-style init systems generally employ updated versions of activation, both during boot\-up and during runtime and using more minimal service description files\&. +.PP +In systemd, if the developer or administrator wants to make sure a service or other unit is activated automatically on boot it is recommended to place a symlink to the unit file in the +\&.wants/ +directory of either +multi\-user\&.target +or +graphical\&.target, which are normally used as boot targets at system startup\&. See +\fBsystemd.unit\fR(5) +for details about the +\&.wants/ +directories, and +\fBsystemd.special\fR(7) +for details about the two boot targets\&. +.SS "Socket\-Based Activation" +.PP +In order to maximize the possible parallelization and robustness and simplify configuration and development, it is recommended for all new\-style daemons that communicate via listening sockets to employ socket\-based activation\&. In a socket\-based activation scheme the creation and binding of the listening socket as primary communication channel of daemons to local (and sometimes remote) clients is moved out of the daemon code and into the init system\&. Based on per\-daemon configuration the init system installs the sockets and then hands them off to the spawned process as soon as the respective daemon is to be started\&. Optionally activation of the service can be delayed until the first inbound traffic arrives at the socket, to implement on\-demand activation of daemons\&. However, the primary advantage of this scheme is that all providers and all consumers of the sockets can be started in parallel as soon as all sockets are established\&. In addition to that daemons can be restarted with losing only a minimal number of client transactions or even any client request at all (the latter is particularly true for state\-less protocols, such as DNS or syslog), because the socket stays bound and accessible during the restart, and all requests are queued while the daemon cannot process them\&. +.PP +New\-style daemons which support socket activation must be able to receive their sockets from the init system, instead of of creating and binding them themselves\&. For details about the programming interfaces for this scheme provided by systemd see +\fBsd_listen_fds\fR(3) +and +\fBsd-daemon\fR(7)\&. For details about porting existing daemons to socket\-based activation see below\&. With minimal effort it is possible to implement socket\-based activation in addition to traditional internal socket creation in the same codebase in order to support both new\-style and old\-style init systems from the same daemon binary\&. +.PP +systemd implements socket\-based activation via +\&.socket +units, which are described in +\fBsystemd.socket\fR(5)\&. When configuring socket units for socket\-based activation it is essential that all listening sockets are pulled in by the special target unit +sockets\&.target\&. It is recommended to place a +\fIWantedBy=sockets\&.target\fR +directive in the +[Install] +section, to automatically add such a dependency on installation of a socket unit\&. Unless +\fIDefaultDependencies=no\fR +is set the necessary ordering dependencies are implicitly created for all socket units\&. For more information about +sockets\&.target +see +\fBsystemd.special\fR(7)\&. It is not necessary or recommended to place any additional dependencies on socket units (for example from +multi\-user\&.target +or suchlike) when one is installed in +sockets\&.target\&. +.SS "Bus\-Based Activation" +.PP +When the D\-Bus IPC system is used for communication with clients, new\-style daemons should employ bus activation so that they are automatically activated when a client application accesses their IPC interfaces\&. This is configured in D\-Bus service files (not to be confused with systemd service unit files!)\&. To ensure that D\-Bus uses systemd to start\-up and maintain the daemon use the +\fISystemdService=\fR +directive in these service files, to configure the matching systemd service for a D\-Bus service\&. e\&.g\&.: for a D\-Bus service whose D\-Bus activation file is named +org\&.freedesktop\&.RealtimeKit\&.service, make sure to set +\fISystemdService=rtkit\-daemon\&.service\fR +in that file, to bind it to the systemd service +rtkit\-daemon\&.service\&. This is needed to make sure that the daemon is started in a race\-free fashion when activated via multiple mechanisms simultaneously\&. +.SS "Device\-Based Activation" +.PP +Often, daemons that manage a particular type of hardware should be activated only when the hardware of the respective kind is plugged in or otherwise becomes available\&. In a new\-style init system it is possible to bind activation to hardware plug/unplug events\&. In systemd, kernel devices appearing in the sysfs/udev device tree can be exposed as units if they are tagged with the string "systemd"\&. Like any other kind of unit they may then pull in other units when activated (i\&.e\&. Plugged in) and thus implement device\-based activation\&. Systemd dependencies may be encoded in the udev database via the +\fISYSTEMD_WANTS=\fR +property\&. See +\fBsystemd.device\fR(5) +for details\&. Often it is nicer to pull in services from devices only indirectly via dedicated targets\&. Example: instead of pulling in +bluetoothd\&.service +from all the various bluetooth dongles and other hardware available, pull in bluetooth\&.target from them and +bluetoothd\&.service +from that target\&. This provides for nicer abstraction and gives administrators the option to enable +bluetoothd\&.service +via controlling a +bluetooth\&.target\&.wants/ +symlink uniformly with a command like +\fBenable\fR +of +\fBsystemctl\fR(1) +instead of manipulating the udev ruleset\&. +.SS "Path\-Based Activation" +.PP +Often, runtime of daemons processing spool files or directories (such as a printing system) can be delayed until these file system objects change state, or become non\-empty\&. New\-style init systems provide a way to bind service activation to file system changes\&. systemd implements this scheme via path\-based activation configured in +\&.path +units, as outlined in +\fBsystemd.path\fR(5)\&. +.SS "Timer\-Based Activation" +.PP +Some daemons that implement clean\-up jobs that are intended to be executed in regular intervals benefit from timer\-based activation\&. In systemd, this is implemented via +\&.timer +units, as described in +\fBsystemd.timer\fR(5)\&. +.SS "Other Forms of Activation" +.PP +Other forms of activation have been suggested and implemented in some systems\&. However, often there are simpler or better alternatives, or they can be put together of combinations of the schemes above\&. Example: sometimes it appears useful to start daemons or +\&.socket +units when a specific IP address is configured on a network interface, because network sockets shall be bound to the address\&. However, an alternative to implement this is by utilizing the Linux IP_FREEBIND socket option, as accessible via +\fIFreeBind=yes\fR +in systemd socket files (see +\fBsystemd.socket\fR(5) +for details)\&. This option, when enabled, allows sockets to be bound to a non\-local, not configured IP address, and hence allows bindings to a particular IP address before it actually becomes available, making such an explicit dependency to the configured address redundant\&. Another often suggested trigger for service activation is low system load\&. However, here too, a more convincing approach might be to make proper use of features of the operating system: in particular, the CPU or IO scheduler of Linux\&. Instead of scheduling jobs from userspace based on monitoring the OS scheduler, it is advisable to leave the scheduling of processes to the OS scheduler itself\&. systemd provides fine\-grained access to the CPU and IO schedulers\&. If a process executed by the init system shall not negatively impact the amount of CPU or IO bandwidth available to other processes, it should be configured with +\fICPUSchedulingPolicy=idle\fR +and/or +\fIIOSchedulingClass=idle\fR\&. Optionally, this may be combined with timer\-based activation to schedule background jobs during runtime and with minimal impact on the system, and remove it from the boot phase itself\&. +.SH "INTEGRATION WITH SYSTEMD" +.SS "Writing Systemd Unit Files" +.PP +When writing systemd unit files, it is recommended to consider the following suggestions: +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 1." 4.2 +.\} +If possible do not use the +\fIType=forking\fR +setting in service files\&. But if you do, make sure to set the PID file path using +\fIPIDFile=\fR\&. See +\fBsystemd.service\fR(5) +for details\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 2." 4.2 +.\} +If your daemon registers a D\-Bus name on the bus, make sure to use +\fIType=dbus\fR +in the service file if possible\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 3." 4.2 +.\} +Make sure to set a good human\-readable description string with +\fIDescription=\fR\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 4.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 4." 4.2 +.\} +Do not disable +\fIDefaultDependencies=\fR, unless you really know what you do and your unit is involved in early boot or late system shutdown\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 5.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 5." 4.2 +.\} +Normally, little if any dependencies should need to be defined explicitly\&. However, if you do configure explicit dependencies, only refer to unit names listed on +\fBsystemd.special\fR(7) +or names introduced by your own package to keep the unit file operating system\-independent\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 6.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 6." 4.2 +.\} +Make sure to include an +[Install] +section including installation information for the unit file\&. See +\fBsystemd.unit\fR(5) +for details\&. To activate your service on boot make sure to add a +\fIWantedBy=multi\-user\&.target\fR +or +\fIWantedBy=graphical\&.target\fR +directive\&. To activate your socket on boot, make sure to add +\fIWantedBy=sockets\&.target\fR\&. Usually you also want to make sure that when your service is installed your socket is installed too, hence add +\fIAlso=foo\&.socket\fR +in your service file +foo\&.service, for a hypothetical program +foo\&. +.RE +.SS "Installing Systemd Service Files" +.PP +At the build installation time (e\&.g\&. +\fBmake install\fR +during package build) packages are recommended to install their systemd unit files in the directory returned by +\fBpkg\-config systemd \-\-variable=systemdsystemunitdir\fR +(for system services), resp\&. +\fBpkg\-config systemd \-\-variable=systemduserunitdir\fR +(for user services)\&. This will make the services available in the system on explicit request but not activate them automatically during boot\&. Optionally, during package installation (e\&.g\&. +\fBrpm \-i\fR +by the administrator) symlinks should be created in the systemd configuration directories via the +\fBenable\fR +command of the +\fBsystemctl\fR(1) +tool, to activate them automatically on boot\&. +.PP +Packages using +\fBautoconf\fR(1) +are recommended to use a configure script excerpt like the following to determine the unit installation path during source configuration: +.sp +.if n \{\ +.RS 4 +.\} +.nf +PKG_PROG_PKG_CONFIG +AC_ARG_WITH([systemdsystemunitdir], + AS_HELP_STRING([\-\-with\-systemdsystemunitdir=DIR], [Directory for systemd service files]), + [], [with_systemdsystemunitdir=$($PKG_CONFIG \-\-variable=systemdsystemunitdir systemd)]) +if test "x$with_systemdsystemunitdir" != xno; then + AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir]) +fi +AM_CONDITIONAL(HAVE_SYSTEMD, [test \-n "$with_systemdsystemunitdir" \-a "x$with_systemdsystemunitdir" != xno ]) +.fi +.if n \{\ +.RE +.\} +.PP +This snippet allows automatic installation of the unit files on systemd machines, and optionally allows their installation even on machines lacking systemd\&. (Modification of this snippet for the user unit directory is left as an exercise for the reader\&.) +.PP +Additionally, to ensure that +\fBmake distcheck\fR +continues to work, it is recommended to add the following to the top\-level +Makefile\&.am +file in +\fBautomake\fR(1)\-based projects: +.sp +.if n \{\ +.RS 4 +.\} +.nf +DISTCHECK_CONFIGURE_FLAGS = \e + \-\-with\-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) +.fi +.if n \{\ +.RE +.\} +.PP +Finally, unit files should be installed in the system with an automake excerpt like the following: +.sp +.if n \{\ +.RS 4 +.\} +.nf +if HAVE_SYSTEMD +systemdsystemunit_DATA = \e + foobar\&.socket \e + foobar\&.service +endif +.fi +.if n \{\ +.RE +.\} +.PP +In the +\fBrpm\fR(8) +\&.spec +file use a snippet like the following to enable/disable the service during installation/deinstallation\&. Consult the packaging guidelines of your distribution for details and the equivalent for other package managers: +.sp +.if n \{\ +.RS 4 +.\} +.nf +%post +if [ $1 \-eq 1 ]; then + # On install (not upgrade), enable (but don\*(Aqt start) the + # units by default + /bin/systemctl enable foobar\&.service foobar\&.socket >/dev/null 2>&1 || : + + # Alternatively, just call + # /bin/systemctl daemon\-reload >/dev/null 2>&1 || : + # here, if the daemon should not be enabled by default on + # installation +fi + +%preun +if [ $1 \-eq 0 ]; then + # On uninstall (not upgrade), disable and stop the units + /bin/systemctl \-\-no\-reload disable foobar\&.service foobar\&.socket >/dev/null 2>&1 || : + /bin/systemctl stop foobar\&.service foobar\&.socket >/dev/null 2>&1 || : +fi + +%postun +# Reload init system configuration, to make systemd honour changed +# or deleted unit files +/bin/systemctl daemon\-reload >/dev/null 2>&1 || : +if [ $1 \-ge 1 ] ; then + # On upgrade (not uninstall), optionally, restart the daemon + /bin/systemctl try\-restart foobar\&.service >/dev/null 2>&1 || : +fi +.fi +.if n \{\ +.RE +.\} +.PP +Depending on whether your service should or should not be started/stopped/restarted during package installation, deinstallation or upgrade, a different set of commands may be specified\&. See +\fBsystemctl\fR(1) +for details\&. +.PP +To facilitate upgrades from a package version that shipped only SysV init scripts to a package version that ships both a SysV init script and a native systemd service file, use a fragment like the following: +.sp +.if n \{\ +.RS 4 +.\} +.nf +%triggerun \-\- foobar < 0\&.47\&.11\-1 +if /sbin/chkconfig \-\-level 5 foobar ; then + /bin/systemctl \-\-no\-reload enable foobar\&.service foobar\&.socket >/dev/null 2>&1 || : +fi +.fi +.if n \{\ +.RE +.\} +.PP +Where 0\&.47\&.11\-1 is the first package version that includes the native unit file\&. This fragment will ensure that the first time the unit file is installed it will be enabled if and only if the SysV init script is enabled, thus making sure that the enable status is not changed\&. Note that +\fBchkconfig\fR +is a command specific to Fedora which can be used to check whether a SysV init script is enabled\&. Other operating systems will have to use different commands here\&. +.SH "PORTING EXISTING DAEMONS" +.PP +Since new\-style init systems such as systemd are compatible with traditional SysV init systems it is not strictly necessary to port existing daemons to the new style\&. However doing so offers additional functionality to the daemons as well as simplifying integration into new\-style init systems\&. +.PP +To port an existing SysV compatible daemon the following steps are recommended: +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 1." 4.2 +.\} +If not already implemented, add an optional command line switch to the daemon to disable daemonization\&. This is useful not only for using the daemon in new\-style init systems, but also to ease debugging\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 2." 4.2 +.\} +If the daemon offers interfaces to other software running on the local system via local AF_UNIX sockets, consider implementing socket\-based activation (see above)\&. Usually a minimal patch is sufficient to implement this: Extend the socket creation in the daemon code so that +\fBsd_listen_fds\fR(3) +is checked for already passed sockets first\&. If sockets are passed (i\&.e\&. when +\fBsd_listen_fds()\fR +returns a positive value), skip the socket creation step and use the passed sockets\&. Secondly, ensure that the file\-system socket nodes for local AF_UNIX sockets used in the socket\-based activation are not removed when the daemon shuts down, if sockets have been passed\&. Third, if the daemon normally closes all remaining open file descriptors as part of its initialization, the sockets passed from the init system must be spared\&. Since new\-style init systems guarantee that no left\-over file descriptors are passed to executed processes, it might be a good choice to simply skip the closing of all remaining open file descriptors if sockets are passed\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 3." 4.2 +.\} +Write and install a systemd unit file for the service (and the sockets if socket\-based activation is used, as well as a path unit file, if the daemon processes a spool directory), see above for details\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 4.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 4." 4.2 +.\} +If the daemon exposes interfaces via D\-Bus, write and install a D\-Bus activation file for the service, see above for details\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd-daemon\fR(7), +\fBsd_listen_fds\fR(3), +\fBsd_notify\fR(3), +\fBdaemon\fR(3), +\fBsystemd.service\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE +.SH "NOTES" +.IP " 1." 4 +LSB recommendations for SysV init scripts +.RS 4 +\%http://refspecs.freestandards.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html +.RE +.IP " 2." 4 +Apple MacOS X Daemon Requirements +.RS 4 +\%http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPSystemStartup/Articles/LaunchOnDemandDaemons.html#//apple_ref/doc/uid/TP40001762-104738 +.RE diff --git a/man/daemon.xml b/man/daemon.xml new file mode 100644 index 0000000..997ee5b --- /dev/null +++ b/man/daemon.xml @@ -0,0 +1,948 @@ + + + + + + + + + daemon + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + daemon + 7 + + + + daemon + Writing and Packaging System Daemons + + + + Description + + A daemon is a service process that runs in the + background and supervises the system or provides + functionality to other processes. Traditionally, + daemons are implemented following a scheme originating + in SysV Unix. Modern daemons should follow a simpler + yet more powerful scheme (here called "new-style" + daemons), as implemented by + systemd1. This + manual page covers both schemes, and in + particular includes recommendations for daemons that + shall be included in the systemd init system. + + + SysV Daemons + + When a traditional SysV daemon + starts, it should execute the following steps + as part of the initialization. Note that these + steps are unnecessary for new-style daemons (see below), + and should only be implemented if compatibility + with SysV is essential. + + + Close all open file + descriptors except STDIN, STDOUT, + STDERR (i.e. the first three file + descriptors 0, 1, 2). This ensures + that no accidentally passed file + descriptor stays around in the daemon + process. On Linux this is best + implemented by iterating through + /proc/self/fd, + with a fallback of iterating from file + descriptor 3 to the value returned by + getrlimit() for + RLIMIT_NOFILE. + + Reset all signal + handlers to their default. This is + best done by iterating through the + available signals up to the limit of + _NSIG and resetting them to + SIG_DFL. + + Reset the signal mask + using + sigprocmask(). + + Sanitize the + environment block, removing or + resetting environment variables that + might negatively impact daemon + runtime. + + Call fork(), + to create a background + process. + + In the child, call + setsid() to + detach from any terminal and create an + independent session. + + In the child, call + fork() again, to + ensure the daemon can never re-acquire + a terminal again. + + Call exit() in the + first child, so that only the second + child (the actual daemon process) + stays around. This ensures that the + daemon process is reparented to + init/PID 1, as all daemons should + be. + + In the daemon process, + connect /dev/null + to STDIN, STDOUT, + STDERR. + + In the daemon process, + reset the umask to 0, so that the file + modes passed to open(), mkdir() and + suchlike directly control the access + mode of the created files and + directories. + + In the daemon process, + change the current directory to the + root directory (/), in order to avoid + that the daemon involuntarily + blocks mount points from being + unmounted. + + In the daemon process, + write the daemon PID (as returned by + getpid()) to a + PID file, for example + /var/run/foobar.pid + (for a hypothetical daemon "foobar"), + to ensure that the daemon cannot be + started more than once. This must be + implemented in race-free fashion so + that the PID file is only updated when + at the same time it is verified that + the PID previously stored in the PID + file no longer exists or belongs to a + foreign process. Commonly some kind of + file locking is employed to implement + this logic. + + In the daemon process, + drop privileges, if possible and + applicable. + + From the daemon + process notify the original process + started that initialization is + complete. This can be implemented via + an unnamed pipe or similar + communication channel that is created + before the first + fork() and hence + available in both the original and the + daemon process. + + Call + exit() in the + original process. The process that + invoked the daemon must be able to + rely that this + exit() happens + after initialization is complete and + all external communication channels + established and + accessible. + + + The BSD daemon() function should not be + used, as it implements only a subset of these steps. + + A daemon that needs to provide + compatibility with SysV systems should + implement the scheme pointed out + above. However, it is recommended to make this + behaviour optional and configurable via a + command line argument, to ease debugging as + well as to simplify integration into systems + using systemd. + + + + New-Style Daemons + + Modern services for Linux should be + implemented as new-style daemons. This makes it + easier to supervise and control them at + runtime and simplifies their + implementation. + + For developing a new-style daemon none + of the initialization steps recommended for + SysV daemons need to be implemented. New-style + init systems such as systemd make all of them + redundant. Moreover, since some of these steps + interfere with process monitoring, file + descriptor passing and other functionality of + the init system it is recommended not to + execute them when run as new-style + service. + + Note that new-style init systems + guarantee execution of daemon processes in + clean process contexts: it is guaranteed that + the environment block is sanitized, that the + signal handlers and mask is reset and that no + left-over file descriptors are passed. Daemons + will be executed in their own session, and + STDIN/STDOUT/STDERR connected to + /dev/null unless + otherwise configured. The umask is reset. + + It is recommended for new-style daemons + to implement the following: + + + If SIGTERM is + received, shut down the daemon and + exit cleanly. + + If SIGHUP is received, + reload the configuration files, if + this applies. + + Provide a correct exit + code from the main daemon process, as + this is used by the init system to + detect service errors and problems. It + is recommended to follow the exit code + scheme as defined in the LSB + recommendations for SysV init + scripts. + + If possible and + applicable expose the daemon's control + interface via the D-Bus IPC system and + grab a bus name as last step of + initialization. + + For integration in + systemd, provide a + .service unit + file that carries information about + starting, stopping and otherwise + maintaining the daemon. See + systemd.service5 + for details. + + As much as possible, + rely on the init systemd's + functionality to limit the access of + the daemon to files, services and + other resources. i.e. in the case of + systemd, rely on systemd's resource + limit control instead of implementing + your own, rely on systemd's privilege + dropping code instead of implementing + it in the daemon, and similar. See + systemd.exec5 + for the available + controls. + + If D-Bus is used, make + your daemon bus-activatable, via + supplying a D-Bus service activation + configuration file. This has multiple + advantages: your daemon may be started + lazily on-demand; it may be started in + parallel to other daemons requiring it + -- which maximizes parallelization and + boot-up speed; your daemon can be + restarted on failure, without losing + any bus requests, as the bus queues + requests for activatable services. See + below for details. + + If your daemon + provides services to other local + processes or remote clients via a + socket, it should be made + socket-activatable following the + scheme pointed out below. Like D-Bus + activation this enables on-demand + starting of services as well as it + allows improved parallelization of + service start-up. Also, for state-less + protocols (such as syslog, DNS) a + daemon implementing socket-based + activation can be restarted without + losing a single request. See below for + details. + + If applicable a daemon + should notify the init system about + startup completion or status updates + via the + sd_notify3 + interface. + + Instead of using the + syslog() call to log directly to the + system syslog service, a new-style daemon may + choose to simply log to STDERR via + fprintf(), which is then forwarded to + syslog by the init system. If log + priorities are necessary these can be + encoded by prefixing individual log + lines with strings like "<4>" + (for log priority 4 "WARNING" in the + syslog priority scheme), following a + similar style as the Linux kernel's + printk() priority system. In fact, + using this style of logging also + enables the init system to optionally + direct all application logging to the + kernel log buffer (kmsg), as + accessible via + dmesg1. This + kind of logging may be enabled by + setting + StandardError=syslog + in the service unit file. For details + see + sd-daemon7 + and + systemd.exec5. + + + + These recommendations are similar but + not identical to the Apple + MacOS X Daemon Requirements. + + + + + Activation + + New-style init systems provide multiple + additional mechanisms to activate services, as + detailed below. It is common that services are + configured to be activated via more than one mechanism + at the same time. An example for systemd: + bluetoothd.service might get + activated either when Bluetooth hardware is plugged + in, or when an application accesses its programming + interfaces via D-Bus. Or, a print server daemon might + get activated when traffic arrives at an IPP port, or + when a printer is plugged in, or when a file is queued + in the printer spool directory. Even for services that + are intended to be started on system bootup + unconditionally it is a good idea to implement some of + the various activation schemes outlined below, in + order to maximize parallelization: if a daemon + implements a D-Bus service or listening socket, + implementing the full bus and socket activation scheme + allows starting of the daemon with its clients in + parallel (which speeds up boot-up), since all its + communication channels are established already, and no + request is lost because client requests will be queued + by the bus system (in case of D-Bus) or the kernel (in + case of sockets), until the activation is + completed. + + + Activation on Boot + + Old-style daemons are usually activated + exclusively on boot (and manually by the + administrator) via SysV init scripts, as + detailed in the LSB + Linux Standard Base Core + Specification. This method of + activation is supported ubiquitously on Linux + init systems, both old-style and new-style + systems. Among other issues SysV init scripts + have the disadvantage of involving shell + scripts in the boot process. New-style init + systems generally employ updated versions of + activation, both during boot-up and during + runtime and using more minimal service + description files. + + In systemd, if the developer or + administrator wants to make sure a service or + other unit is activated automatically on boot + it is recommended to place a symlink to the + unit file in the .wants/ + directory of either + multi-user.target or + graphical.target, which + are normally used as boot targets at system + startup. See + systemd.unit5 + for details about the + .wants/ directories, and + systemd.special7 + for details about the two boot targets. + + + + + Socket-Based Activation + + In order to maximize the possible + parallelization and robustness and simplify + configuration and development, it is + recommended for all new-style daemons that + communicate via listening sockets to employ + socket-based activation. In a socket-based + activation scheme the creation and binding of + the listening socket as primary communication + channel of daemons to local (and sometimes + remote) clients is moved out of the daemon + code and into the init system. Based on + per-daemon configuration the init system + installs the sockets and then hands them off + to the spawned process as soon as the + respective daemon is to be started. + Optionally activation of the service can be + delayed until the first inbound traffic + arrives at the socket, to implement on-demand + activation of daemons. However, the primary + advantage of this scheme is that all providers + and all consumers of the sockets can be + started in parallel as soon as all sockets + are established. In addition to that daemons + can be restarted with losing only a minimal + number of client transactions or even any + client request at all (the latter is + particularly true for state-less protocols, + such as DNS or syslog), because the socket + stays bound and accessible during the restart, + and all requests are queued while the daemon + cannot process them. + + New-style daemons which support socket + activation must be able to receive their + sockets from the init system, instead of of + creating and binding them themselves. For + details about the programming interfaces for + this scheme provided by systemd see + sd_listen_fds3 + and + sd-daemon7. For + details about porting existing daemons to + socket-based activation see below. With + minimal effort it is possible to implement + socket-based activation in addition to + traditional internal socket creation in the + same codebase in order to support both + new-style and old-style init systems from the + same daemon binary. + + systemd implements socket-based + activation via .socket + units, which are described in + systemd.socket5. When + configuring socket units for socket-based + activation it is essential that all listening + sockets are pulled in by the special target + unit sockets.target. It + is recommended to place a + WantedBy=sockets.target + directive in the [Install] + section, to automatically add such a + dependency on installation of a socket + unit. Unless + DefaultDependencies=no is + set the necessary ordering dependencies are + implicitly created for all socket units. For + more information about + sockets.target see + systemd.special7. It + is not necessary or recommended to place any + additional dependencies on socket units (for + example from + multi-user.target or + suchlike) when one is installed in + sockets.target. + + + + Bus-Based Activation + + When the D-Bus IPC system is used for + communication with clients, new-style daemons + should employ bus activation so that they are + automatically activated when a client + application accesses their IPC + interfaces. This is configured in D-Bus + service files (not to be confused with systemd + service unit files!). To ensure that D-Bus + uses systemd to start-up and maintain the + daemon use the + SystemdService= directive + in these service files, to configure the + matching systemd service for a D-Bus + service. e.g.: for a D-Bus service whose D-Bus + activation file is named + org.freedesktop.RealtimeKit.service, + make sure to set + SystemdService=rtkit-daemon.service + in that file, to bind it to the systemd + service + rtkit-daemon.service. This + is needed to make sure that the daemon is + started in a race-free fashion when activated + via multiple mechanisms simultaneously. + + + + Device-Based Activation + + Often, daemons that manage a particular + type of hardware should be activated only when + the hardware of the respective kind is plugged + in or otherwise becomes available. In a + new-style init system it is possible to bind + activation to hardware plug/unplug events. In + systemd, kernel devices appearing in the + sysfs/udev device tree can be exposed as units + if they are tagged with the string + "systemd". Like any other + kind of unit they may then pull in other units + when activated (i.e. Plugged in) and thus + implement device-based activation. Systemd + dependencies may be encoded in the udev + database via the + SYSTEMD_WANTS= + property. See + systemd.device5 + for details. Often it is nicer to pull in + services from devices only indirectly via + dedicated targets. Example: instead of pulling + in bluetoothd.service + from all the various bluetooth dongles and + other hardware available, pull in + bluetooth.target from them and + bluetoothd.service from + that target. This provides for nicer + abstraction and gives administrators the + option to enable + bluetoothd.service via + controlling a + bluetooth.target.wants/ + symlink uniformly with a command like + enable of + systemctl1 + instead of manipulating the udev + ruleset. + + + + Path-Based Activation + + Often, runtime of daemons processing + spool files or directories (such as a printing + system) can be delayed until these file system + objects change state, or become + non-empty. New-style init systems provide a + way to bind service activation to file system + changes. systemd implements this scheme via + path-based activation configured in + .path units, as outlined + in + systemd.path5. + + + + Timer-Based Activation + + Some daemons that implement clean-up + jobs that are intended to be executed in + regular intervals benefit from timer-based + activation. In systemd, this is implemented + via .timer units, as + described in + systemd.timer5. + + + + Other Forms of Activation + + Other forms of activation have been + suggested and implemented in some + systems. However, often there are simpler or + better alternatives, or they can be put + together of combinations of the schemes + above. Example: sometimes it appears useful to + start daemons or .socket + units when a specific IP address is configured + on a network interface, because network + sockets shall be bound to the + address. However, an alternative to implement + this is by utilizing the Linux IP_FREEBIND + socket option, as accessible via + FreeBind=yes in systemd + socket files (see + systemd.socket5 + for details). This option, when enabled, + allows sockets to be bound to a non-local, not + configured IP address, and hence allows + bindings to a particular IP address before it + actually becomes available, making such an + explicit dependency to the configured address + redundant. Another often suggested trigger for + service activation is low system + load. However, here too, a more convincing + approach might be to make proper use of + features of the operating system: in + particular, the CPU or IO scheduler of + Linux. Instead of scheduling jobs from + userspace based on monitoring the OS + scheduler, it is advisable to leave the + scheduling of processes to the OS scheduler + itself. systemd provides fine-grained access + to the CPU and IO schedulers. If a process + executed by the init system shall not + negatively impact the amount of CPU or IO + bandwidth available to other processes, it + should be configured with + CPUSchedulingPolicy=idle + and/or + IOSchedulingClass=idle. Optionally, + this may be combined with timer-based + activation to schedule background jobs during + runtime and with minimal impact on the system, + and remove it from the boot phase + itself. + + + + + Integration with Systemd + + + Writing Systemd Unit Files + + When writing systemd unit files, it is + recommended to consider the following + suggestions: + + + If possible do not use + the Type=forking + setting in service files. But if you + do, make sure to set the PID file path + using PIDFile=. See + systemd.service5 + for details. + + If your daemon + registers a D-Bus name on the bus, + make sure to use + Type=dbus in the + service file if + possible. + + Make sure to set a + good human-readable description string + with + Description=. + + Do not disable + DefaultDependencies=, + unless you really know what you do and + your unit is involved in early boot or + late system shutdown. + + Normally, little if + any dependencies should need to + be defined explicitly. However, if you + do configure explicit dependencies, only refer to + unit names listed on + systemd.special7 + or names introduced by your own + package to keep the unit file + operating + system-independent. + + Make sure to include + an [Install] + section including installation + information for the unit file. See + systemd.unit5 + for details. To activate your service + on boot make sure to add a + WantedBy=multi-user.target + or + WantedBy=graphical.target + directive. To activate your socket on + boot, make sure to add + WantedBy=sockets.target. Usually + you also want to make sure that when + your service is installed your socket + is installed too, hence add + Also=foo.socket in + your service file + foo.service, for + a hypothetical program + foo. + + + + + + Installing Systemd Service Files + + At the build installation time + (e.g. make install during + package build) packages are recommended to + install their systemd unit files in the + directory returned by pkg-config + systemd + --variable=systemdsystemunitdir (for + system services), resp. pkg-config + systemd + --variable=systemduserunitdir + (for user services). This will make the + services available in the system on explicit + request but not activate them automatically + during boot. Optionally, during package + installation (e.g. rpm -i + by the administrator) symlinks should be + created in the systemd configuration + directories via the enable + command of the + systemctl1 + tool, to activate them automatically on + boot. + + Packages using + autoconf1 + are recommended to use a configure script + excerpt like the following to determine the + unit installation path during source + configuration: + + PKG_PROG_PKG_CONFIG +AC_ARG_WITH([systemdsystemunitdir], + AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]), + [], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)]) +if test "x$with_systemdsystemunitdir" != xno; then + AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir]) +fi +AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ]) + + This snippet allows automatic + installation of the unit files on systemd + machines, and optionally allows their + installation even on machines lacking + systemd. (Modification of this snippet for the + user unit directory is left as an exercise for the + reader.) + + Additionally, to ensure that + make distcheck continues to + work, it is recommended to add the following + to the top-level Makefile.am + file in + automake1-based + projects: + + DISTCHECK_CONFIGURE_FLAGS = \ + --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) + + Finally, unit files should be installed in the system with an automake excerpt like the following: + + if HAVE_SYSTEMD +systemdsystemunit_DATA = \ + foobar.socket \ + foobar.service +endif + + In the + rpm8 + .spec file use a snippet like + the following to enable/disable the service + during installation/deinstallation. Consult + the packaging guidelines of your distribution + for details and the equivalent for other + package managers: + + %post +if [ $1 -eq 1 ]; then + # On install (not upgrade), enable (but don't start) the + # units by default + /bin/systemctl enable foobar.service foobar.socket >/dev/null 2>&1 || : + + # Alternatively, just call + # /bin/systemctl daemon-reload >/dev/null 2>&1 || : + # here, if the daemon should not be enabled by default on + # installation +fi + +%preun +if [ $1 -eq 0 ]; then + # On uninstall (not upgrade), disable and stop the units + /bin/systemctl --no-reload disable foobar.service foobar.socket >/dev/null 2>&1 || : + /bin/systemctl stop foobar.service foobar.socket >/dev/null 2>&1 || : +fi + +%postun +# Reload init system configuration, to make systemd honour changed +# or deleted unit files +/bin/systemctl daemon-reload >/dev/null 2>&1 || : +if [ $1 -ge 1 ] ; then + # On upgrade (not uninstall), optionally, restart the daemon + /bin/systemctl try-restart foobar.service >/dev/null 2>&1 || : +fi + + Depending on whether your service should + or should not be started/stopped/restarted + during package installation, deinstallation or + upgrade, a different set of commands may be + specified. See + systemctl1 + for details. + + To facilitate upgrades from a package + version that shipped only SysV init scripts to + a package version that ships both a SysV init + script and a native systemd service file, use + a fragment like the following: + + %triggerun -- foobar < 0.47.11-1 +if /sbin/chkconfig --level 5 foobar ; then + /bin/systemctl --no-reload enable foobar.service foobar.socket >/dev/null 2>&1 || : +fi + + Where 0.47.11-1 is the first package + version that includes the native unit + file. This fragment will ensure that the first + time the unit file is installed it will be + enabled if and only if the SysV init script is + enabled, thus making sure that the enable + status is not changed. Note that + chkconfig is a command + specific to Fedora which can be used to check + whether a SysV init script is enabled. Other + operating systems will have to use different + commands here. + + + + + Porting Existing Daemons + + Since new-style init systems such as systemd are + compatible with traditional SysV init systems it is + not strictly necessary to port existing daemons to the + new style. However doing so offers additional + functionality to the daemons as well as simplifying + integration into new-style init systems. + + To port an existing SysV compatible daemon the + following steps are recommended: + + + If not already implemented, + add an optional command line switch to the + daemon to disable daemonization. This is + useful not only for using the daemon in + new-style init systems, but also to ease + debugging. + + If the daemon offers + interfaces to other software running on the + local system via local AF_UNIX sockets, + consider implementing socket-based activation + (see above). Usually a minimal patch is + sufficient to implement this: Extend the + socket creation in the daemon code so that + sd_listen_fds3 + is checked for already passed sockets + first. If sockets are passed (i.e. when + sd_listen_fds() returns a + positive value), skip the socket creation step + and use the passed sockets. Secondly, ensure + that the file-system socket nodes for local + AF_UNIX sockets used in the socket-based + activation are not removed when the daemon + shuts down, if sockets have been + passed. Third, if the daemon normally closes + all remaining open file descriptors as part of + its initialization, the sockets passed from + the init system must be spared. Since + new-style init systems guarantee that no + left-over file descriptors are passed to + executed processes, it might be a good choice + to simply skip the closing of all remaining + open file descriptors if sockets are + passed. + + Write and install a systemd + unit file for the service (and the sockets if + socket-based activation is used, as well as a + path unit file, if the daemon processes a + spool directory), see above for + details. + + If the daemon exposes + interfaces via D-Bus, write and install a + D-Bus activation file for the service, see + above for details. + + + + + See Also + + systemd1, + sd-daemon7, + sd_listen_fds3, + sd_notify3, + daemon3, + systemd.service5 + + + + diff --git a/man/halt.8 b/man/halt.8 new file mode 100644 index 0000000..cbe4eb3 --- /dev/null +++ b/man/halt.8 @@ -0,0 +1,111 @@ +'\" t +.\" Title: halt +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: halt +.\" Source: systemd +.\" Language: English +.\" +.TH "HALT" "8" "02/15/2012" "systemd" "halt" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +halt, poweroff, reboot \- Halt, power\-off or reboot the machine +.SH "SYNOPSIS" +.HP \w'\fBhalt\ \fR\fB[OPTIONS...]\fR\ 'u +\fBhalt \fR\fB[OPTIONS...]\fR +.HP \w'\fBpoweroff\ \fR\fB[OPTIONS...]\fR\ 'u +\fBpoweroff \fR\fB[OPTIONS...]\fR +.HP \w'\fBreboot\ \fR\fB[OPTIONS...]\fR\ 'u +\fBreboot \fR\fB[OPTIONS...]\fR +.SH "DESCRIPTION" +.PP +\fBhalt\fR, +\fBpoweroff\fR, +\fBreboot\fR +may be used to halt, power\-off or reboot the machine\&. +.SH "OPTIONS" +.PP +The following options are understood: +.PP +\fB\-\-help\fR +.RS 4 +Prints a short help text and exits\&. +.RE +.PP +\fB\-\-halt\fR +.RS 4 +Halt the machine, regardless which one of the three commands is invoked\&. +.RE +.PP +\fB\-p\fR, \fB\-\-poweroff\fR +.RS 4 +Power\-off the machine, regardless which one of the three commands is invoked\&. +.RE +.PP +\fB\-\-reboot\fR +.RS 4 +Reboot the machine, regardless which one of the three commands is invoked\&. +.RE +.PP +\fB\-f\fR, \fB\-\-force\fR +.RS 4 +Force immediate halt, power\-off, reboot\&. Don\*(Aqt contact the init system\&. +.RE +.PP +\fB\-w\fR, \fB\-\-wtmp\-only\fR +.RS 4 +Only write wtmp shutdown entry, don\*(Aqt actually halt, power\-off, reboot\&. +.RE +.PP +\fB\-d\fR, \fB\-\-no\-wtmp\fR +.RS 4 +Don\*(Aqt write wtmp shutdown entry\&. +.RE +.PP +\fB\-n\fR, \fB\-\-no\-sync\fR +.RS 4 +Don\*(Aqt sync hard disks/storage media before halt, power\-off, reboot\&. +.RE +.PP +\fB\-\-no\-wall\fR +.RS 4 +Don\*(Aqt send wall message before halt, power\-off, reboot\&. +.RE +.SH "EXIT STATUS" +.PP +On success 0 is returned, a non\-zero failure code otherwise\&. +.SH "NOTES" +.PP +These are legacy commands available for compatibility only\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(1), +\fBshutdown\fR(8), +\fBwall\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/halt.xml b/man/halt.xml new file mode 100644 index 0000000..97a53ba --- /dev/null +++ b/man/halt.xml @@ -0,0 +1,181 @@ + + + + + + + + + halt + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + halt + 8 + + + + halt + poweroff + reboot + Halt, power-off or reboot the machine + + + + + halt OPTIONS + + + poweroff OPTIONS + + + reboot OPTIONS + + + + + Description + + halt, + poweroff, reboot + may be used to halt, power-off or reboot the + machine. + + + + + Options + + The following options are understood: + + + + + + Prints a short help + text and exits. + + + + + + Halt the machine, + regardless which one of the three + commands is invoked. + + + + + + + Power-off the machine, + regardless which one of the three + commands is invoked. + + + + + + Reboot the machine, + regardless which one of the three + commands is invoked. + + + + + + + Force immediate halt, + power-off, reboot. Don't contact the + init system. + + + + + + + Only write wtmp + shutdown entry, don't actually halt, + power-off, reboot. + + + + + + + Don't write wtmp + shutdown entry. + + + + + + + Don't sync hard disks/storage media before + halt, power-off, + reboot. + + + + + + Don't send wall + message before + halt, power-off, reboot. + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Notes + + These are legacy commands available for + compatibility only. + + + + See Also + + systemd1, + systemctl1, + shutdown8, + wall1 + + + + diff --git a/man/hostname.5 b/man/hostname.5 new file mode 100644 index 0000000..35ef7f8 --- /dev/null +++ b/man/hostname.5 @@ -0,0 +1,63 @@ +'\" t +.\" Title: hostname +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: /etc/hostname +.\" Source: systemd +.\" Language: English +.\" +.TH "HOSTNAME" "5" "02/15/2012" "systemd" "/etc/hostname" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +hostname \- Local host name configuration file +.SH "SYNOPSIS" +.PP +/etc/hostname +.SH "DESCRIPTION" +.PP +The +/etc/hostname +file configures the name of the local system that is set during boot, with the +\fBsethostname\fR(2) +system call\&. It should contain a single newline\-terminated host name string\&. The host name may be a free\-form string up to 64 characters in length, however it is recommended that it consists only of 7bit ASCII lower\-case characters and no spaces or dots, and limits itself to the format allowed for DNS domain name labels, even though this is not a strict requirement\&. +.PP +Depending on the operating system other configuration files might be checked for configuration of the host name as well, however only as fallback\&. +.SH "HISTORY" +.PP +The simple configuration file format of +/etc/hostname +originates from Debian GNU/Linux\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsethostname\fR(2), +\fBhostname\fR(1), +\fBhostname\fR(7), +\fBmachine-id\fR(5), +\fBmachine-info\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/hostname.xml b/man/hostname.xml new file mode 100644 index 0000000..1acda1a --- /dev/null +++ b/man/hostname.xml @@ -0,0 +1,95 @@ + + + + + + + + + /etc/hostname + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + hostname + 5 + + + + hostname + Local host name configuration file + + + + /etc/hostname + + + + Description + + The /etc/hostname file + configures the name of the local system that is set + during boot, with the + sethostname2 + system call. It should contain a single + newline-terminated host name string. The + host name may be a free-form string up to 64 characters + in length, however it is recommended that it consists + only of 7bit ASCII lower-case characters and no spaces or dots, + and limits itself to the format allowed for DNS domain + name labels, even though this is not a + strict requirement. + + Depending on the operating system other + configuration files might be checked for configuration + of the host name as well, however only as fallback. + + + + History + + The simple configuration file format of + /etc/hostname originates from + Debian GNU/Linux. + + + + See Also + + systemd1, + sethostname2, + hostname1, + hostname7, + machine-id5, + machine-info5 + + + + diff --git a/man/init.1 b/man/init.1 new file mode 100644 index 0000000..166bbc2 --- /dev/null +++ b/man/init.1 @@ -0,0 +1 @@ +.so man1/systemd.1 diff --git a/man/locale.conf.5 b/man/locale.conf.5 new file mode 100644 index 0000000..281baa7 --- /dev/null +++ b/man/locale.conf.5 @@ -0,0 +1,114 @@ +'\" t +.\" Title: locale.conf +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: locale.conf +.\" Source: systemd +.\" Language: English +.\" +.TH "LOCALE\&.CONF" "5" "02/15/2012" "systemd" "locale.conf" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +locale.conf \- configuration file for locale settings +.SH "SYNOPSIS" +.PP +/etc/locale\&.conf +.SH "DESCRIPTION" +.PP +The +/etc/locale\&.conf +file configures system\-wide locale settings\&. +.PP +The basic file format of +locale\&.conf +is a newline\-separated list of environment\-like shell\-compatible variable assignments\&. It is possible to source the configuration from shell scripts, however, beyond mere variable assignments no shell features are supported, allowing applications to read the file without implementing a shell compatible execution engine\&. +.PP +Note that the kernel command line options +\fIlocale\&.LANG=\fR, +\fIlocale\&.LANGUAGE=\fR, +\fIlocale\&.LC_CTYPE=\fR, +\fIlocale\&.LC_NUMERIC=\fR, +\fIlocale\&.LC_TIME=\fR, +\fIlocale\&.LC_COLLATE=\fR, +\fIlocale\&.LC_MONETARY=\fR, +\fIlocale\&.LC_MESSAGES=\fR, +\fIlocale\&.LC_PAPER=\fR, +\fIlocale\&.LC_NAME=\fR, +\fIlocale\&.LC_ADDRESS=\fR, +\fIlocale\&.LC_TELEPHONE=\fR, +\fIlocale\&.LC_MEASUREMENT=\fR, +\fIlocale\&.LC_IDENTIFICATION=\fR +may be used to override the locale settings at boot\&. +.PP +The locale settings configured in +/etc/locale\&.conf +are system\-wide and are inherited by every service or user, unless overridden or unset by individual programs or individual users\&. +.PP +Depending on the operating system other configuration files might be checked for locale configuration as well, however only as fallback\&. +.SH "OPTIONS" +.PP +The following locale settings may be set using +/etc/locale\&.conf: +\fILANG=\fR, +\fILANGUAGE=\fR, +\fILC_CTYPE=\fR, +\fILC_NUMERIC=\fR, +\fILC_TIME=\fR, +\fILC_COLLATE=\fR, +\fILC_MONETARY=\fR, +\fILC_MESSAGES=\fR, +\fILC_PAPER=\fR, +\fILC_NAME=\fR, +\fILC_ADDRESS=\fR, +\fILC_TELEPHONE=\fR, +\fILC_MEASUREMENT=\fR, +\fILC_IDENTIFICATION=\fR\&. Note that +\fILC_ALL\fR +may not be be configured in this file\&. For details about the meaning and semantics of these settings, refer to +\fBlocale\fR(7)\&. +.SH "EXAMPLE" +.PP +\fBExample\ \&1.\ \&German locale with English messages\fR +.PP +/etc/locale\&.conf: +.sp +.if n \{\ +.RS 4 +.\} +.nf +LANG=de_DE\&.UTF\-8 +LC_MESSAGES=C +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBlocale\fR(7) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/locale.conf.xml b/man/locale.conf.xml new file mode 100644 index 0000000..3723997 --- /dev/null +++ b/man/locale.conf.xml @@ -0,0 +1,146 @@ + + + + + + + + + locale.conf + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + locale.conf + 5 + + + + locale.conf + configuration file for locale settings + + + + /etc/locale.conf + + + + Description + + The /etc/locale.conf file + configures system-wide locale settings. + + The basic file format of + locale.conf is a + newline-separated list of environment-like + shell-compatible variable assignments. It is possible + to source the configuration from shell scripts, + however, beyond mere variable assignments no shell + features are supported, allowing applications to read + the file without implementing a shell compatible + execution engine. + + Note that the kernel command line options + locale.LANG=, + locale.LANGUAGE=, + locale.LC_CTYPE=, + locale.LC_NUMERIC=, + locale.LC_TIME=, + locale.LC_COLLATE=, + locale.LC_MONETARY=, + locale.LC_MESSAGES=, + locale.LC_PAPER=, + locale.LC_NAME=, + locale.LC_ADDRESS=, + locale.LC_TELEPHONE=, + locale.LC_MEASUREMENT=, + locale.LC_IDENTIFICATION= may be + used to override the locale settings at boot. + + The locale settings configured in + /etc/locale.conf are system-wide + and are inherited by every service or user, unless + overridden or unset by individual programs or + individual users. + + Depending on the operating system other + configuration files might be checked for locale + configuration as well, however only as + fallback. + + + + Options + + The following locale settings may be set using + /etc/locale.conf: + LANG=, + LANGUAGE=, + LC_CTYPE=, + LC_NUMERIC=, + LC_TIME=, + LC_COLLATE=, + LC_MONETARY=, + LC_MESSAGES=, + LC_PAPER=, + LC_NAME=, + LC_ADDRESS=, + LC_TELEPHONE=, + LC_MEASUREMENT=, + LC_IDENTIFICATION=. Note that + LC_ALL may not be be configured in + this file. For details about the meaning and semantics + of these settings, refer to + locale7. + + + + Example + + + German locale with English messages + + /etc/locale.conf: + + LANG=de_DE.UTF-8 +LC_MESSAGES=C + + + + + + See Also + + systemd1, + locale7 + + + + diff --git a/man/machine-id.5 b/man/machine-id.5 new file mode 100644 index 0000000..4c70542 --- /dev/null +++ b/man/machine-id.5 @@ -0,0 +1,104 @@ +'\" t +.\" Title: machine-id +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: /etc/machine-id +.\" Source: systemd +.\" Language: English +.\" +.TH "MACHINE\-ID" "5" "02/15/2012" "systemd" "/etc/machine-id" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +machine-id \- local machine ID configuration file +.SH "SYNOPSIS" +.PP +/etc/machine\-id +.SH "DESCRIPTION" +.PP +The +/etc/machine\-id +file contains the unique machine id of the local system that is set during installation\&. The machine ID is a single newline\-terminated, hexadecimal, lowercase 32 character machine ID string\&. (When decoded from hexadecimal this corresponds with a 16 byte/128 bit string\&.) +.PP +The machine ID is usually generated from a random source during system installation and stays constant for all subsequent boots\&. Optionally, for stateless systems it is generated during runtime at boot if it is found to be empty\&. +.PP +The machine ID does not change based on user configuration, or when hardware is replaced\&. +.PP +This machine ID adheres to the same format and logic as the D\-Bus machine ID\&. +.PP +Programs may use this ID to identify the host with a globally unique ID in the network, that does not change even if the local network configuration changes\&. Due to this and its greater length it is a more useful replacement for the +\fBgethostid\fR(3) +call POSIX specifies\&. +.SH "RELATION TO OSF UUIDS" +.PP +Note that the machine ID historically is not an OSF UUID as defined by +\m[blue]\fBRFC 4122\fR\m[]\&\s-2\u[1]\d\s+2, nor a Microsoft GUID\&. Starting with systemd v30 newly generated machine IDs however do qualify as v4 UUIDs\&. +.PP +In order to maintain compatibility with existing installations, an application requiring a UUID should decode the machine ID, and then apply the following operations to turn it into a valid OSF v4 UUID\&. With +id +being an unsigned character array: +.sp +.if n \{\ +.RS 4 +.\} +.nf +/* Set UUID version to 4 \-\-\- truly random generation */ +id[6] = (id[6] & 0x0F) | 0x40; +/* Set the UUID variant to DCE */ +id[8] = (id[8] & 0x3F) | 0x80; +.fi +.if n \{\ +.RE +.\} +.PP +(This code is inspired by +generate_random_uuid() +of +drivers/char/random\&.c +from the kernel sources\&.) +.SH "HISTORY" +.PP +The simple configuration file format of +/etc/machine\-id +originates in the +/var/lib/dbus/machine\-id +file introduced by D\-Bus\&. In fact this latter file might be a symlink to +\fI/etc/machine\-id\fR\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBgethostid\fR(3), +\fBhostname\fR(5), +\fBmachine-info\fR(5), +\fBos-release\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE +.SH "NOTES" +.IP " 1." 4 +RFC 4122 +.RS 4 +\%http://tools.ietf.org/html/rfc4122 +.RE diff --git a/man/machine-id.xml b/man/machine-id.xml new file mode 100644 index 0000000..6ca9990 --- /dev/null +++ b/man/machine-id.xml @@ -0,0 +1,137 @@ + + + + + + + + + /etc/machine-id + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + machine-id + 5 + + + + machine-id + local machine ID configuration file + + + + /etc/machine-id + + + + Description + + The /etc/machine-id file + contains the unique machine id of the local system + that is set during installation. The machine ID is a + single newline-terminated, hexadecimal, lowercase 32 + character machine ID string. (When decoded from + hexadecimal this corresponds with a 16 byte/128 bit + string.) + + The machine ID is usually generated from a + random source during system installation and stays + constant for all subsequent boots. Optionally, for + stateless systems it is generated during runtime at + boot if it is found to be empty. + + The machine ID does not change based on user + configuration, or when hardware is replaced. + + This machine ID adheres to the same format and + logic as the D-Bus machine ID. + + Programs may use this ID to identify the host + with a globally unique ID in the network, that does + not change even if the local network configuration + changes. Due to this and its greater length it is + a more useful replacement for the + gethostid3 + call POSIX specifies. + + + + Relation to OSF UUIDs + + Note that the machine ID historically is not an + OSF UUID as defined by RFC + 4122, nor a Microsoft GUID. Starting with + systemd v30 newly generated machine IDs however do + qualify as v4 UUIDs. + + In order to maintain compatibility with existing + installations, an application requiring a UUID should + decode the machine ID, and then apply the following + operations to turn it into a valid OSF v4 UUID. With + id being an unsigned character + array: + + /* Set UUID version to 4 --- truly random generation */ +id[6] = (id[6] & 0x0F) | 0x40; +/* Set the UUID variant to DCE */ +id[8] = (id[8] & 0x3F) | 0x80; + + (This code is inspired by + generate_random_uuid() of + drivers/char/random.c from the + kernel sources.) + + + + + History + + The simple configuration file format of + /etc/machine-id originates in the + /var/lib/dbus/machine-id file + introduced by D-Bus. In fact this latter file might be a + symlink to + /etc/machine-id. + + + + See Also + + systemd1, + gethostid3, + hostname5, + machine-info5, + os-release5 + + + + diff --git a/man/machine-info.5 b/man/machine-info.5 new file mode 100644 index 0000000..dc629ef --- /dev/null +++ b/man/machine-info.5 @@ -0,0 +1,104 @@ +'\" t +.\" Title: machine-info +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: machine-info +.\" Source: systemd +.\" Language: English +.\" +.TH "MACHINE\-INFO" "5" "02/15/2012" "systemd" "machine-info" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +machine-info \- Local machine information file +.SH "SYNOPSIS" +.PP +/etc/machine\-info +.SH "DESCRIPTION" +.PP +The +/etc/machine\-info +file contains machine meta data\&. +.PP +The basic file format of +machine\-info +is a newline\-separated list of environment\-like shell\-compatible variable assignments\&. It is possible to source the configuration from shell scripts, however, beyond mere variable assignments no shell features are supported, allowing applications to read the file without implementing a shell compatible execution engine\&. +.PP +/etc/machine\-info +contains meta data about the machine that is set by the user or administrator\&. +.PP +Depending on the operating system other configuration files might be checked for machine information as well, however only as fallback\&. +.SH "OPTIONS" +.PP +The following machine meta data parameters may be set using +/etc/machine\-info: +.PP +\fIPRETTY_HOSTNAME=\fR +.RS 4 +A pretty human\-readable UTF8 machine identifier string\&. This should contain a name like +Lennart\*(Aqs Laptop +which is useful to present to the user and does not suffer by the syntax limitations of internet domain names\&. If possible the internet host name as configured in +/etc/hostname +should be kept similar to this one\&. Example: if this value is +Lennart\*(Aqs Computer +an Internet host name of +lennarts\-computer +might be a good choice\&. If this parameter is not set an application should fall back to the Internet host name for presentation purposes\&. +.RE +.PP +\fIICON_NAME=\fR +.RS 4 +An icon identifying this machine according to the +\m[blue]\fBXDG Icon Naming Specification\fR\m[]\&\s-2\u[1]\d\s+2\&. If this parameter is not set an application should fall back to +computer +or a similar icon name\&. +.RE +.SH "EXAMPLE" +.sp +.if n \{\ +.RS 4 +.\} +.nf +PRETTY_NAME="Lennart\*(Aqs Computer" +ICON_NAME=computer\-laptop +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBos-release\fR(5), +\fBhostname\fR(5), +\fBmachine-id\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE +.SH "NOTES" +.IP " 1." 4 +XDG Icon Naming Specification +.RS 4 +\%http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html +.RE diff --git a/man/machine-info.xml b/man/machine-info.xml new file mode 100644 index 0000000..c6d3e92 --- /dev/null +++ b/man/machine-info.xml @@ -0,0 +1,147 @@ + + + + + + + + + machine-info + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + machine-info + 5 + + + + machine-info + Local machine information file + + + + /etc/machine-info + + + + Description + + The /etc/machine-info file + contains machine meta data. + + The basic file format of + machine-info is a + newline-separated list of environment-like + shell-compatible variable assignments. It is possible + to source the configuration from shell scripts, + however, beyond mere variable assignments no shell + features are supported, allowing applications to read + the file without implementing a shell compatible + execution engine. + + /etc/machine-info contains + meta data about the machine that is set by the user or + administrator. + + Depending on the operating system other + configuration files might be checked for machine + information as well, however only as fallback. + + + + Options + + The following machine meta data parameters may + be set using + /etc/machine-info: + + + + + PRETTY_HOSTNAME= + + A pretty + human-readable UTF8 machine identifier + string. This should contain a name + like Lennart's + Laptop which is useful to + present to the user and does not + suffer by the syntax limitations of + internet domain names. If possible the + internet host name as configured in + /etc/hostname + should be kept similar to this + one. Example: if this value is + Lennart's Computer + an Internet host name of + lennarts-computer + might be a good choice. If this + parameter is not set an application + should fall back to the Internet host + name for presentation + purposes. + + + + ICON_NAME= + + An icon identifying + this machine according to the XDG + Icon Naming Specification. If + this parameter is not set an + application should fall back to + computer or a + similar icon name. + + + + + + + + Example + + PRETTY_NAME="Lennart's Computer" +ICON_NAME=computer-laptop + + + + See Also + + systemd1, + os-release5, + hostname5, + machine-id5 + + + + diff --git a/man/modules-load.d.5 b/man/modules-load.d.5 new file mode 100644 index 0000000..51031e0 --- /dev/null +++ b/man/modules-load.d.5 @@ -0,0 +1,85 @@ +'\" t +.\" Title: modules-load.d +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: modules-load.d +.\" Source: systemd +.\" Language: English +.\" +.TH "MODULES\-LOAD\&.D" "5" "02/15/2012" "systemd" "modules-load.d" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +modules-load.d \- Configure kernel modules to load at boot +.SH "SYNOPSIS" +.PP +/usr/lib/modules\-load\&.d/*\&.conf +.PP +/etc/modules\-load\&.d/*\&.conf +.PP +/run/modules\-load\&.d/*\&.conf +.SH "DESCRIPTION" +.PP +\fBsystemd\fR +uses files from the above directories to configure kernel modules to load during boot in a static list\&. Each configuration file is named in the style of +/etc/modules\-load\&.d/\&.conf\&. Note that it is usually a better idea to use the automatic module loading by PCI ID, by DMI ID or similar triggers configured in the kernel modules themselves instead of relying on static configuration like this\&. +.SH "CONFIGURATION FORMAT" +.PP +The configuration files should simply contain a list of kernel module names to load, separated by newlines\&. Empty lines and lines whose first non\-whitespace character is # or ; are ignored\&. +.PP +Each configuration file is named in the style of +\&.conf\&. Files in +/etc/ +overwrite files with the same name in +/usr/lib/\&. Files in +/run +overwrite files with the same name in +/etc/ +and +/usr/lib/\&. Packages should install their configuration files in +/usr/lib/, files in +/etc/ +are reserved for the local administration, which possibly decides to overwrite the configurations installed from packages\&. All files are sorted by filename in alphabetical order, regardless in which of the directories they reside, to ensure that a specific configuration file takes precedence over another file with an alphabetically later name\&. +.SH "EXAMPLE" +.PP +\fBExample\ \&1.\ \&/etc/modules-load.d/virtio-net.conf example:\fR +.sp +.if n \{\ +.RS 4 +.\} +.nf +# Load virtio\-net\&.ko at boot +virtio\-net +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBmodprobe\fR(8) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/modules-load.d.xml b/man/modules-load.d.xml new file mode 100644 index 0000000..b633663 --- /dev/null +++ b/man/modules-load.d.xml @@ -0,0 +1,112 @@ + + + + + + + + modules-load.d + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + modules-load.d + 5 + + + + modules-load.d + Configure kernel modules to load at boot + + + + /usr/lib/modules-load.d/*.conf + /etc/modules-load.d/*.conf + /run/modules-load.d/*.conf + + + + Description + + systemd uses + files from the above directories to configure + kernel modules to load during boot in a static list. + Each configuration file is named in the style of + /etc/modules-load.d/<program>.conf. Note + that it is usually a better idea to use the automatic + module loading by PCI ID, by DMI ID or similar + triggers configured in the kernel modules themselves + instead of relying on static configuration like + this. + + + + Configuration Format + + The configuration files should simply contain a + list of kernel module names to load, separated by + newlines. Empty lines and lines whose first + non-whitespace character is # or ; are ignored. + + Each configuration file is named in the style of + <program>.conf. + Files in /etc/ overwrite + files with the same name in /usr/lib/. + Files in /run overwrite files with + the same name in /etc/ and + /usr/lib/. Packages should install their + configuration files in /usr/lib/, files + in /etc/ are reserved for the local + administration, which possibly decides to overwrite the + configurations installed from packages. All files are sorted + by filename in alphabetical order, regardless in which of the + directories they reside, to ensure that a specific + configuration file takes precedence over another file with + an alphabetically later name. + + + + Example + + /etc/modules-load.d/virtio-net.conf example: + + # Load virtio-net.ko at boot +virtio-net + + + + + See Also + + systemd1, + modprobe8 + + + + diff --git a/man/os-release.5 b/man/os-release.5 new file mode 100644 index 0000000..b400086 --- /dev/null +++ b/man/os-release.5 @@ -0,0 +1,161 @@ +'\" t +.\" Title: os-release +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: os-release +.\" Source: systemd +.\" Language: English +.\" +.TH "OS\-RELEASE" "5" "02/15/2012" "systemd" "os-release" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +os-release \- Operating system identification +.SH "SYNOPSIS" +.PP +/etc/os\-release +.SH "DESCRIPTION" +.PP +The +/etc/os\-release +file contains operating system identification data\&. +.PP +The basic file format of +os\-release +is a newline\-separated list of environment\-like shell\-compatible variable assignments\&. It is possible to source the configuration from shell scripts, however, beyond mere variable assignments no shell features are supported (this means variable expansion is explicitly not supported), allowing applications to read the file without implementing a shell compatible execution engine\&. Variable assignment values should be enclosed in double or single quotes if they include spaces, semicolons or other special characters outside of A\-Z, a\-z, 0\-9\&. All strings should be in UTF\-8 format, and non\-printable characters should not be used\&. If double or single quotes or backslashes are to be used within variable assignments they should be escaped with backslashes, following shell style\&. It is not supported to concatenate multiple individually quoted strings\&. Lines beginning with "#" shall be ignored as comments\&. +.PP +/etc/os\-release +contains data that is defined by the operating system vendor and should not be changed by the administrator\&. +.PP +As this file only encodes names and identifiers it should not be localized\&. +.PP +For a longer rationale for +/etc/os\-release +please refer to the +\m[blue]\fBAnnouncement of /etc/os\-release\fR\m[]\&\s-2\u[1]\d\s+2\&. +.SH "OPTIONS" +.PP +The following OS identifications parameters may be set using +/etc/os\-release: +.PP +\fINAME=\fR +.RS 4 +A string identifying the operating system, without a version component, and suitable for presentation to the user\&. If not set defaults to +NAME=Linux\&. Example: +NAME=Fedora +or +NAME="Debian GNU/Linux"\&. +.RE +.PP +\fIVERSION=\fR +.RS 4 +A string identifying the operating system version, excluding any OS name information, possibly including a release code name, and suitable for presentation to the user\&. This field is optional\&. Example: +VERSION=17 +or +VERSION="17 (Beefy Miracle)"\&. +.RE +.PP +\fIID=\fR +.RS 4 +A lower\-case string (no spaces or other characters outside of 0\-9, a\-z, "\&.", "_" and "\-") identifying the operating system, excluding any version information and suitable for processing by scripts or usage in generated file names\&. If not set defaults to +ID=linux\&. Example: +ID=fedora +or +ID=debian\&. +.RE +.PP +\fIVERSION_ID=\fR +.RS 4 +A lower\-case string (mostly numeric, no spaces or other characters outside of 0\-9, a\-z, "\&.", "_" and "\-") identifying the operating system version, excluding any OS name information or release code name, and suitable for processing by scripts or usage in generated file names\&. This field is optional\&. Example: +VERSION_ID=17 +or +VERSION_ID=11\&.04\&. +.RE +.PP +\fIPRETTY_NAME=\fR +.RS 4 +A pretty operating system name in a format suitable for presentation to the user\&. May or may not contain a release code name or OS version of some kind, as suitable\&. If not set defaults to +PRETTY_NAME="Linux"\&. Example: +PRETTY_NAME="Fedora 17 (Beefy Miracle)"\&. +.RE +.PP +\fIANSI_COLOR=\fR +.RS 4 +A suggested presentation color when showing the distribution name on the console\&. This should be specified as string suitable for inclusion in the ESC [ m ANSI/ECMA\-48 escape code for setting graphical rendition\&. This field is optional\&. Example: +ANSI_COLOR="0;31" +for red, or +ANSI_COLOR="1;34" +for light blue\&. +.RE +.PP +\fICPE_NAME=\fR +.RS 4 +A CPE name for the operating system, following the +\m[blue]\fBCommon Platform Enumeration Specification\fR\m[]\&\s-2\u[2]\d\s+2 +as proposed by the MITRE Corporation\&. This field is optional\&. Example: +CPE_NAME="cpe:/o:fedoraproject:fedora:17" +.RE +.PP +If you are reading this file from C code or a shell script to determine the OS or a specific version of it, use the ID and VERSION_ID fields\&. When looking for an OS identification string for presentation to the user use the PRETTY_NAME field\&. +.PP +Note that operating system vendors may choose not to provide version information, for example to accommodate for rolling releases\&. In this case VERSION and VERSION_ID may be unset\&. Applications should not rely on these fields to be set\&. +.SH "EXAMPLE" +.sp +.if n \{\ +.RS 4 +.\} +.nf +NAME=Fedora +VERSION="17 (Beefy Miracle)" +ID=fedora +VERSION_ID=17 +PRETTY_NAME="Fedora 17 (Beefy Miracle)" +ANSI_COLOR="0;34" +CPE_NAME="cpe:/o:fedoraproject:fedora:17" +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBlsb_release\fR(1), +\fBhostname\fR(5), +\fBmachine-id\fR(5), +\fBmachine-info\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE +.SH "NOTES" +.IP " 1." 4 +Announcement of /etc/os-release +.RS 4 +\%http://0pointer.de/blog/projects/os-release +.RE +.IP " 2." 4 +Common Platform Enumeration Specification +.RS 4 +\%http://cpe.mitre.org/specification/ +.RE diff --git a/man/os-release.xml b/man/os-release.xml new file mode 100644 index 0000000..7d79972 --- /dev/null +++ b/man/os-release.xml @@ -0,0 +1,245 @@ + + + + + + + + + os-release + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + os-release + 5 + + + + os-release + Operating system identification + + + + /etc/os-release + + + + Description + + The /etc/os-release file + contains operating system identification data. + + The basic file format of + os-release is a newline-separated + list of environment-like shell-compatible variable + assignments. It is possible to source the + configuration from shell scripts, however, beyond mere + variable assignments no shell features are supported + (this means variable expansion is explicitly not + supported), allowing applications to read the file + without implementing a shell compatible execution + engine. Variable assignment values should be enclosed + in double or single quotes if they include spaces, + semicolons or other special characters outside of A-Z, + a-z, 0-9. All strings should be in UTF-8 format, and + non-printable characters should not be used. If double + or single quotes or backslashes are to be used within + variable assignments they should be escaped with + backslashes, following shell style. It is not + supported to concatenate multiple individually quoted + strings. Lines beginning with "#" shall be ignored as + comments. + + /etc/os-release contains + data that is defined by the operating system vendor + and should not be changed by the administrator. + + As this file only encodes names and identifiers + it should not be localized. + + For a longer rationale for + /etc/os-release please refer to + the Announcement of /etc/os-release. + + + + Options + + The following OS identifications parameters may be set using + /etc/os-release: + + + + + NAME= + + A string identifying + the operating system, without a + version component, and suitable for + presentation to the user. If not set + defaults to + NAME=Linux. Example: + NAME=Fedora or + NAME="Debian + GNU/Linux". + + + + VERSION= + + A string identifying + the operating system version, + excluding any OS name information, + possibly including a release code + name, and suitable for presentation to + the user. This field is + optional. Example: + VERSION=17 or + VERSION="17 (Beefy + Miracle)". + + + + ID= + + A lower-case string + (no spaces or other characters outside + of 0-9, a-z, ".", "_" and "-") + identifying the operating system, + excluding any version information and + suitable for processing by scripts or + usage in generated file names. If not + set defaults to + ID=linux. Example: + ID=fedora or + ID=debian. + + + + VERSION_ID= + + A lower-case string + (mostly numeric, no spaces or other + characters outside of 0-9, a-z, ".", + "_" and "-") identifying the operating + system version, excluding any OS name + information or release code name, and + suitable for processing by scripts or + usage in generated file names. This + field is optional. Example: + VERSION_ID=17 or + VERSION_ID=11.04. + + + + PRETTY_NAME= + + A pretty operating + system name in a format suitable for + presentation to the user. May or may + not contain a release code name or OS + version of some kind, as suitable. If + not set defaults to + PRETTY_NAME="Linux". Example: + PRETTY_NAME="Fedora 17 (Beefy + Miracle)". + + + + ANSI_COLOR= + + A suggested + presentation color when showing the + distribution name on the console. This + should be specified as string suitable + for inclusion in the ESC [ m + ANSI/ECMA-48 escape code for setting + graphical rendition. This field is + optional. Example: + ANSI_COLOR="0;31" + for red, or + ANSI_COLOR="1;34" + for light blue. + + + + CPE_NAME= + + A CPE name for the + operating system, following the Common + Platform Enumeration + Specification as proposed by + the MITRE Corporation. This field + is optional. Example: + CPE_NAME="cpe:/o:fedoraproject:fedora:17" + + + + + If you are reading this file from C code or a + shell script to determine the OS or a specific version + of it, use the ID and VERSION_ID fields. When looking + for an OS identification string for presentation to + the user use the PRETTY_NAME field. + + Note that operating system vendors may choose + not to provide version information, for example to + accommodate for rolling releases. In this case VERSION + and VERSION_ID may be unset. Applications should not + rely on these fields to be set. + + + + Example + + NAME=Fedora +VERSION="17 (Beefy Miracle)" +ID=fedora +VERSION_ID=17 +PRETTY_NAME="Fedora 17 (Beefy Miracle)" +ANSI_COLOR="0;34" +CPE_NAME="cpe:/o:fedoraproject:fedora:17" + + + + See Also + + systemd1, + lsb_release1, + hostname5, + machine-id5, + machine-info5 + + + + diff --git a/man/pam_systemd.8 b/man/pam_systemd.8 new file mode 100644 index 0000000..0c3da26 --- /dev/null +++ b/man/pam_systemd.8 @@ -0,0 +1,234 @@ +'\" t +.\" Title: pam_systemd +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: pam_systemd +.\" Source: systemd +.\" Language: English +.\" +.TH "PAM_SYSTEMD" "8" "02/15/2012" "systemd" "pam_systemd" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +pam_systemd \- Register user sessions in the systemd control group hierarchy +.SH "SYNOPSIS" +.HP \w'\fBpam_systemd\&.so\fR\ 'u +\fBpam_systemd\&.so\fR +.SH "DESCRIPTION" +.PP +\fBpam_systemd\fR +registers user sessions in the systemd control group hierarchy\&. +.PP +On login, this module ensures the following: +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 1." 4.2 +.\} +If it does not exist yet, the user runtime directory +/run/user/$USER +is created and its ownership changed to the user that is logging in\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 2." 4.2 +.\} +The +\fI$XDG_SESSION_ID\fR +environment variable is initialized\&. If auditing is available and +\fBpam_loginuid\&.so\fR +run before this module (which is highly recommended), the variable is initialized from the auditing session id (/proc/self/sessionid)\&. Otherwise an independent session counter is used\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 3." 4.2 +.\} +A new control group +/user/$USER/$XDG_SESSION_ID +is created and the login process moved into it\&. +.RE +.PP +On logout, this module ensures the following: +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 1." 4.2 +.\} +If +\fI$XDG_SESSION_ID\fR +is set and +\fBkill\-session\-processes=1\fR +specified, all remaining processes in the +/user/$USER/$XDG_SESSION_ID +control group are killed and the control group is removed\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 2." 4.2 +.\} +If last subgroup of the +/user/$USER +control group was removed the +\fI$XDG_RUNTIME_DIR\fR +directory and all its contents are removed, too\&. +.RE +.PP +If the system was not booted up with systemd as init system, this module does nothing and immediately returns PAM_SUCCESS\&. +.SH "OPTIONS" +.PP +The following options are understood: +.PP +\fBkill\-session\-processes=\fR +.RS 4 +Takes a boolean argument\&. If true, all processes created by the user during his session and from his session will be terminated when he logs out from his session\&. +.RE +.PP +\fBkill\-only\-users=\fR +.RS 4 +Takes a comma separated list of user names or numeric user ids as argument\&. If this option is used the effect of the +\fBkill\-session\-processes=\fR +options will apply only to the listed users\&. If this option is not used the option applies to all local users\&. Note that +\fBkill\-exclude\-users=\fR +takes precedence over this list and is hence subtracted from the list specified here\&. +.RE +.PP +\fBkill\-exclude\-users=\fR +.RS 4 +Takes a comma separated list of user names or numeric user ids as argument\&. Users listed in this argument will not be subject to the effect of +\fBkill\-session\-processes=\fR\&. Note that that this option takes precedence over +\fBkill\-only\-users=\fR, and hence whatever is listed for +\fBkill\-exclude\-users=\fR +is guaranteed to never be killed by this PAM module, independent of any other configuration setting\&. +.RE +.PP +\fBcontrollers=\fR +.RS 4 +Takes a comma separated list of control group controllers in which hierarchies a user/session control group will be created by default for each user logging in, in addition to the control group in the named \*(Aqname=systemd\*(Aq hierarchy\&. If omitted, defaults to an empty list\&. +.RE +.PP +\fBreset\-controllers=\fR +.RS 4 +Takes a comma separated list of control group controllers in which hierarchies the logged in processes will be reset to the root control group\&. +.RE +.PP +\fBdebug=\fR +.RS 4 +Takes a boolean argument\&. If yes, the module will log debugging information as it operates\&. +.RE +.PP +Note that setting +\fIkill\-session\-processes=1\fR +will break tools like +\fBscreen\fR(1)\&. +.PP +Note that +\fIkill\-session\-processes=1\fR +is a stricter version of +\fIKillUserProcesses=1\fR +which may be configured system\-wide in +\fBsystemd-logind.conf\fR(5)\&. The former kills processes of a session as soon as it ends, the latter kills processes as soon as the last session of the user ends\&. +.PP +If the options are omitted they default to +\fBkill\-session\-processes=0\fR, +\fBkill\-only\-users=\fR, +\fBkill\-exclude\-users=\fR, +\fBcontrollers=\fR, +\fBreset\-controllers=\fR, +\fBdebug=no\fR\&. +.SH "MODULE TYPES PROVIDED" +.PP +Only +\fBsession\fR +is provided\&. +.SH "ENVIRONMENT" +.PP +The following environment variables are set for the processes of the user\*(Aqs session: +.PP +\fI$XDG_SESSION_ID\fR +.RS 4 +A session identifier, suitable to be used in file names\&. The string itself should be considered opaque, although often it is just the audit session ID as reported by +/proc/self/sessionid\&. Each ID will be assigned only once during machine uptime\&. It may hence be used to uniquely label files or other resources of this session\&. +.RE +.PP +\fI$XDG_RUNTIME_DIR\fR +.RS 4 +Path to a user\-private user\-writable directory that is bound to the user login time on the machine\&. It is automatically created the first time a user logs in and removed on his final logout\&. If a user logs in twice at the same time, both sessions will see the same +\fI$XDG_RUNTIME_DIR\fR +and the same contents\&. If a user logs in once, then logs out again, and logs in again, the directory contents will have been lost in between, but applications should not rely on this behaviour and must be able to deal with stale files\&. To store session\-private data in this directory the user should include the value of +\fI$XDG_SESSION_ID\fR +in the filename\&. This directory shall be used for runtime file system objects such as AF_UNIX sockets, FIFOs, PID files and similar\&. It is guaranteed that this directory is local and offers the greatest possible file system feature set the operating system provides\&. +.RE +.SH "EXAMPLE" +.sp +.if n \{\ +.RS 4 +.\} +.nf +#%PAM\-1\&.0 +auth required pam_unix\&.so +auth required pam_nologin\&.so +account required pam_unix\&.so +password required pam_unix\&.so +session required pam_unix\&.so +session required pam_loginuid\&.so +session required pam_systemd\&.so kill\-session\-processes=1 +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.PP + +\fBpam.conf\fR(5), +\fBpam.d\fR(5), +\fBpam\fR(8), +\fBpam_loginuid\fR(8), +\fBsystemd-logind.conf\fR(5), +\fBsystemd\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml new file mode 100644 index 0000000..883b50b --- /dev/null +++ b/man/pam_systemd.xml @@ -0,0 +1,316 @@ + + + + + + + + + pam_systemd + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + pam_systemd + 8 + + + + pam_systemd + Register user sessions in the systemd control group hierarchy + + + + + pam_systemd.so + + + + + Description + + pam_systemd registers user + sessions in the systemd control group + hierarchy. + + On login, this module ensures the following: + + + If it does not exist yet, the + user runtime directory + /run/user/$USER is + created and its ownership changed to the user + that is logging in. + + The + $XDG_SESSION_ID environment + variable is initialized. If auditing is + available and + pam_loginuid.so run before + this module (which is highly recommended), the + variable is initialized from the auditing + session id + (/proc/self/sessionid). Otherwise + an independent session counter is + used. + + A new control group + /user/$USER/$XDG_SESSION_ID + is created and the login process moved into + it. + + + On logout, this module ensures the following: + + + If + $XDG_SESSION_ID is set and + specified, all + remaining processes in the + /user/$USER/$XDG_SESSION_ID + control group are killed and the control group + is removed. + + If last subgroup of the + /user/$USER control group + was removed the + $XDG_RUNTIME_DIR directory + and all its contents are + removed, too. + + + If the system was not booted up with systemd as + init system, this module does nothing and immediately + returns PAM_SUCCESS. + + + + + Options + + The following options are understood: + + + + + + Takes a boolean + argument. If true, all processes + created by the user during his session + and from his session will be + terminated when he logs out from his + session. + + + + + + Takes a comma + separated list of user names or + numeric user ids as argument. If this + option is used the effect of the + options + will apply only to the listed + users. If this option is not used the + option applies to all local + users. Note that + + takes precedence over this list and is + hence subtracted from the list + specified here. + + + + + + Takes a comma + separated list of user names or + numeric user ids as argument. Users + listed in this argument will not be + subject to the effect of + . Note + that that this option takes precedence + over + , and + hence whatever is listed for + + is guaranteed to never be killed by + this PAM module, independent of any + other configuration + setting. + + + + + + Takes a comma + separated list of control group + controllers in which hierarchies a + user/session control group will be + created by default for each user + logging in, in addition to the control + group in the named 'name=systemd' + hierarchy. If omitted, defaults to an + empty list. + + + + + + Takes a comma + separated list of control group + controllers in which hierarchies the + logged in processes will be reset to + the root control + group. + + + + + + Takes a boolean + argument. If yes, the module will log + debugging information as it + operates. + + + + Note that setting + kill-session-processes=1 will break tools + like + screen1. + + Note that + kill-session-processes=1 is a + stricter version of + KillUserProcesses=1 which may be + configured system-wide in + systemd-logind.conf5. The + former kills processes of a session as soon as it + ends, the latter kills processes as soon as the last + session of the user ends. + + If the options are omitted they default to + , + , + , + , + , + . + + + + Module Types Provided + + Only is provided. + + + + Environment + + The following environment variables are set for the processes of the user's session: + + + + $XDG_SESSION_ID + + A session identifier, + suitable to be used in file names. The + string itself should be considered + opaque, although often it is just the + audit session ID as reported by + /proc/self/sessionid. Each + ID will be assigned only once during + machine uptime. It may hence be used + to uniquely label files or other + resources of this + session. + + + + $XDG_RUNTIME_DIR + + Path to a user-private + user-writable directory that is bound + to the user login time on the + machine. It is automatically created + the first time a user logs in and + removed on his final logout. If a user + logs in twice at the same time, both + sessions will see the same + $XDG_RUNTIME_DIR + and the same contents. If a user logs + in once, then logs out again, and logs + in again, the directory contents will + have been lost in between, but + applications should not rely on this + behaviour and must be able to deal with + stale files. To store session-private + data in this directory the user should + include the value of $XDG_SESSION_ID + in the filename. This directory shall + be used for runtime file system + objects such as AF_UNIX sockets, + FIFOs, PID files and similar. It is + guaranteed that this directory is + local and offers the greatest possible + file system feature set the + operating system + provides. + + + + + + Example + + #%PAM-1.0 +auth required pam_unix.so +auth required pam_nologin.so +account required pam_unix.so +password required pam_unix.so +session required pam_unix.so +session required pam_loginuid.so +session required pam_systemd.so kill-session-processes=1 + + + + See Also + + pam.conf5, + pam.d5, + pam8, + pam_loginuid8, + systemd-logind.conf5, + systemd1 + + + + diff --git a/man/poweroff.8 b/man/poweroff.8 new file mode 100644 index 0000000..41c02c1 --- /dev/null +++ b/man/poweroff.8 @@ -0,0 +1 @@ +.so man8/halt.8 diff --git a/man/reboot.8 b/man/reboot.8 new file mode 100644 index 0000000..41c02c1 --- /dev/null +++ b/man/reboot.8 @@ -0,0 +1 @@ +.so man8/halt.8 diff --git a/man/runlevel.8 b/man/runlevel.8 new file mode 100644 index 0000000..ba6ced7 --- /dev/null +++ b/man/runlevel.8 @@ -0,0 +1,94 @@ +'\" t +.\" Title: runlevel +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: runlevel +.\" Source: systemd +.\" Language: English +.\" +.TH "RUNLEVEL" "8" "02/15/2012" "systemd" "runlevel" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +runlevel \- Print previous and current SysV runlevel +.SH "SYNOPSIS" +.HP \w'\fBrunlevel\ \fR\fB[options...]\fR\ 'u +\fBrunlevel \fR\fB[options...]\fR +.SH "DESCRIPTION" +.PP +\fBrunlevel\fR +prints the previous and current SysV runlevel if they are known\&. +.PP +The two runlevel characters are separated by a single space character\&. If a runlevel cannot be determined, N is printed instead\&. If neither can be determined, the word "unknown" is printed\&. +.PP +Unless overridden in the environment, this will check the utmp database for recent runlevel changes\&. +.SH "OPTIONS" +.PP +The following option is understood: +.PP +\fB\-\-help\fR +.RS 4 +Prints a short help text and exits\&. +.RE +.SH "EXIT STATUS" +.PP +If one or both runlevels could be determined, 0 is returned, a non\-zero failure code otherwise\&. +.SH "ENVIRONMENT" +.PP +\fI$RUNLEVEL\fR +.RS 4 +If +\fI$RUNLEVEL\fR +is set, +\fBrunlevel\fR +will print this value as current runlevel and ignore utmp\&. +.RE +.PP +\fI$PREVLEVEL\fR +.RS 4 +If +\fI$PREVLEVEL\fR +is set +\fBrunlevel\fR +will print this value as previous runlevel and ignore utmp\&. +.RE +.SH "FILES" +.PP +\fI/var/run/utmp\fR +.RS 4 +The utmp database +\fBrunlevel\fR +reads the previous and current runlevel from\&. +.RE +.SH "NOTES" +.PP +This is a legacy command available for compatibility only\&. It should not be used anymore, as the concept of runlevels is obsolete\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/runlevel.xml b/man/runlevel.xml new file mode 100644 index 0000000..160d1b1 --- /dev/null +++ b/man/runlevel.xml @@ -0,0 +1,154 @@ + + + + + + + + + runlevel + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + runlevel + 8 + + + + runlevel + Print previous and current SysV runlevel + + + + + runlevel options + + + + + Description + + runlevel prints the previous + and current SysV runlevel if they are known. + + The two runlevel characters are separated by a + single space character. If a runlevel cannot be + determined, N is printed instead. If neither can be + determined, the word "unknown" is printed. + + Unless overridden in the environment, this will + check the utmp database for recent runlevel + changes. + + + + Options + + The following option is understood: + + + + + + Prints a short help + text and exits. + + + + + + + Exit status + + If one or both runlevels could be determined, 0 + is returned, a non-zero failure code otherwise. + + + + + Environment + + + + $RUNLEVEL + + If + $RUNLEVEL is set, + runlevel will print + this value as current runlevel and + ignore utmp. + + + + $PREVLEVEL + + If + $PREVLEVEL is set + runlevel will print + this value as previous runlevel and + ignore utmp. + + + + + + Files + + + + /var/run/utmp + + The utmp database + runlevel reads the + previous and current runlevel + from. + + + + + + + Notes + + This is a legacy command available for compatibility + only. It should not be used anymore, as the concept of + runlevels is obsolete. + + + + See Also + + systemd1, + systemctl1 + + + + diff --git a/man/sd-daemon.7 b/man/sd-daemon.7 new file mode 100644 index 0000000..d1df345 --- /dev/null +++ b/man/sd-daemon.7 @@ -0,0 +1,139 @@ +'\" t +.\" Title: sd-daemon +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sd-daemon +.\" Source: systemd +.\" Language: English +.\" +.TH "SD\-DAEMON" "7" "02/15/2012" "systemd" "sd-daemon" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sd-daemon \- Reference implementation of APIs for new\-style daemons +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include +.fi +.ft +.HP \w'\fBpkg\-config\ \-\-cflags\ \-\-libs\ libsystemd\-daemon\fR\ 'u +\fBpkg\-config \-\-cflags \-\-libs libsystemd\-daemon\fR +.SH "DESCRIPTION" +.PP +sd\-daemon\&.c +and +sd\-daemon\&.h +provide a reference implementation of various APIs for new\-style daemons, as implemented by the +\fBsystemd\fR(1) +init system\&. +.PP +See +\fBsd_listen_fds\fR(3), +\fBsd_notify\fR(3), +\fBsd_booted\fR(3), +\fBsd_is_fifo\fR(3) +for more information about the functions implemented\&. In addition to these functions a couple of logging prefixes are defined as macros: +.sp +.if n \{\ +.RS 4 +.\} +.nf +#define SD_EMERG "<0>" /* system is unusable */ +#define SD_ALERT "<1>" /* action must be taken immediately */ +#define SD_CRIT "<2>" /* critical conditions */ +#define SD_ERR "<3>" /* error conditions */ +#define SD_WARNING "<4>" /* warning conditions */ +#define SD_NOTICE "<5>" /* normal but significant condition */ +#define SD_INFO "<6>" /* informational */ +#define SD_DEBUG "<7>" /* debug\-level messages */ +.fi +.if n \{\ +.RE +.\} +.PP +These prefixes are intended to be used in conjunction with STDERR\-based logging as implemented by systemd\&. If a systemd service definition file is configured with +\fIStandardError=syslog\fR +or +\fIStandardError=kmsg\fR +these prefixes can be used to encode a log level in lines printed\&. This is similar to the kernel +\fBprintk()\fR\-style logging\&. See +\fBklogctl\fR(2) +for more information\&. +.PP +The log levels are identical to +\fBsyslog\fR(3)\*(Aqs log level system\&. To use these prefixes simply prefix every line with one of these strings\&. A line that is not prefixed will be logged at the default log level SD_INFO\&. +.PP +\fBExample\ \&1.\ \&Hello World\fR +.PP +A daemon may log with the log level NOTICE by issuing this call: +.sp +.if n \{\ +.RS 4 +.\} +.nf +fprintf(stderr, SD_NOTICE "Hello World!\en"); +.fi +.if n \{\ +.RE +.\} +.SH "NOTES" +.PP +These interfaces are provided by the reference implementation of APIs for new\-style daemons and distributed with the systemd package\&. The algorithms they implement are simple, and can easily be reimplemented in daemons if it is important to support this interface without using the reference implementation\&. See the respective function man pages for details\&. +.PP +In addition, for details about the algorithms check the liberally licensed reference implementation sources: +\m[blue]\fB\%http://cgit.freedesktop.org/systemd/systemd/plain/src/sd-daemon.c\fR\m[] +resp\&. +\m[blue]\fB\%http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h\fR\m[] +.PP +These APIs are implemented in the reference implementation\*(Aqs +sd\-daemon\&.c +and +sd\-daemon\&.h +files\&. These interfaces are available as shared library, which can be compiled and linked to with the +libsystemd\-daemon +\fBpkg-config\fR(1) +file\&. Alternatively, applications consuming these APIs may copy the implementation into their source tree, either verbatim or in excerpts\&. +.PP +The functions directly related to new\-style daemons become NOPs when \-DDISABLE_SYSTEMD is set during compilation and the reference implementation is used as drop\-in files\&. In addition, if +sd\-daemon\&.c +is compiled on non\-Linux systems they become NOPs\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd_listen_fds\fR(3), +\fBsd_notify\fR(3), +\fBsd_booted\fR(3), +\fBsd_is_fifo\fR(3), +\fBdaemon\fR(7), +\fBsystemd.service\fR(5), +\fBsystemd.socket\fR(5), +\fBfprintf\fR(3), +\fBsd-readahead\fR(7), +\fBpkg-config\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/sd-daemon.xml b/man/sd-daemon.xml new file mode 100644 index 0000000..4ea88e4 --- /dev/null +++ b/man/sd-daemon.xml @@ -0,0 +1,172 @@ + + + + + + + + + sd-daemon + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd-daemon + 7 + + + + sd-daemon + Reference implementation of APIs for + new-style daemons + + + + + #include <systemd/sd-daemon.h> + + + + pkg-config --cflags --libs libsystemd-daemon + + + + + + Description + + sd-daemon.c and + sd-daemon.h provide a reference + implementation of various APIs for new-style daemons, + as implemented by the + systemd1 + init system. + + See + sd_listen_fds3, + sd_notify3, + sd_booted3, + sd_is_fifo3 + for more information about the functions + implemented. In addition to these functions a couple + of logging prefixes are defined as macros: + + #define SD_EMERG "<0>" /* system is unusable */ +#define SD_ALERT "<1>" /* action must be taken immediately */ +#define SD_CRIT "<2>" /* critical conditions */ +#define SD_ERR "<3>" /* error conditions */ +#define SD_WARNING "<4>" /* warning conditions */ +#define SD_NOTICE "<5>" /* normal but significant condition */ +#define SD_INFO "<6>" /* informational */ +#define SD_DEBUG "<7>" /* debug-level messages */ + + These prefixes are intended to be used in + conjunction with STDERR-based logging as implemented + by systemd. If a systemd service definition file is + configured with StandardError=syslog + or StandardError=kmsg these + prefixes can be used to encode a log level in lines + printed. This is similar to the kernel + printk()-style logging. See + klogctl2 + for more information. + + The log levels are identical to + syslog3's + log level system. To use these prefixes simply prefix + every line with one of these strings. A line that is + not prefixed will be logged at the default log level + SD_INFO. + + + Hello World + + A daemon may log with the log level + NOTICE by issuing this call: + + fprintf(stderr, SD_NOTICE "Hello World!\n"); + + + + + Notes + + These interfaces are provided by the reference + implementation of APIs for new-style daemons and + distributed with the systemd package. The algorithms + they implement are simple, and can easily be + reimplemented in daemons if it is important to support + this interface without using the reference + implementation. See the respective function man pages + for details. + + In addition, for details about the algorithms + check the liberally licensed reference implementation + sources: + + resp. + + These APIs are implemented in the reference + implementation's sd-daemon.c and + sd-daemon.h files. These + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-daemon + pkg-config1 + file. Alternatively, applications consuming these APIs + may copy the implementation into their source tree, + either verbatim or in excerpts. + + The functions directly related to new-style + daemons become NOPs when -DDISABLE_SYSTEMD is set + during compilation and the reference implementation is + used as drop-in files. In addition, if + sd-daemon.c is compiled on + non-Linux systems they become NOPs. + + + + See Also + + systemd1, + sd_listen_fds3, + sd_notify3, + sd_booted3, + sd_is_fifo3, + daemon7, + systemd.service5, + systemd.socket5, + fprintf3, + sd-readahead7, + pkg-config1 + + + + diff --git a/man/sd-login.7 b/man/sd-login.7 new file mode 100644 index 0000000..b3b64c0 --- /dev/null +++ b/man/sd-login.7 @@ -0,0 +1,108 @@ +'\" t +.\" Title: sd-login +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sd-login +.\" Source: systemd +.\" Language: English +.\" +.TH "SD\-LOGIN" "7" "02/15/2012" "systemd" "sd-login" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sd-login \- APIs for tracking logins +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include +.fi +.ft +.HP \w'\fBpkg\-config\ \-\-cflags\ \-\-libs\ libsystemd\-login\fR\ 'u +\fBpkg\-config \-\-cflags \-\-libs libsystemd\-login\fR +.SH "DESCRIPTION" +.PP +sd\-login\&.h +provides APIs to introspect and monitor seat, login session and user status information on the local system\&. +.PP +See +\m[blue]\fBMulti\-Seat on Linux\fR\m[]\&\s-2\u[1]\d\s+2 +for an introduction into multi\-seat support on Linux, the background for this set of APIs\&. +.PP +Note that these APIs only allow purely passive access and monitoring of seats, sessions and users\&. To actively make changes to the seat configuration, terminate login sessions, or switch session on a seat you need to utilize the D\-Bus API of systemd\-logind, instead\&. +.PP +These functions synchronously access data in +/proc, +/sys/fs/cgroup +and +/run\&. All of these are virtual file systems, hence the runtime cost of the accesses is relatively cheap\&. +.PP +It is possible (and often a very good choice) to mix calls to the synchronous interface of +sd\-login\&.h +with the asynchronous D\-Bus interface of systemd\-logind\&. However, if this is done you need to think a bit about possible races since the stream of events from D\-Bus and from +sd\-login\&.h +interfaces such as the login monitor are asynchronous and not ordered against each other\&. +.PP +If the functions return string arrays, these are generally NULL terminated and need to be freed by the caller with the libc +\fBfree\fR(3) +call after use, including the strings referenced therein\&. Similar, individual strings returned need to be freed, as well\&. +.PP +As a special exception, instead of an empty string array NULL may be returned, which should be treated equivalent to an empty string array\&. +.PP +See +\fBsd_pid_get_session\fR(3), +\fBsd_uid_get_state\fR(3), +\fBsd_session_is_active\fR(3), +\fBsd_seat_get_active\fR(3), +\fBsd_get_seats\fR(3), +\fBsd_login_monitor_new\fR(3) +for more information about the functions implemented\&. +.SH "NOTES" +.PP +These APIs are implemented as shared library, which can be compiled and linked to with the +libsystemd\-login +\fBpkg-config\fR(1) +file\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd_pid_get_session\fR(3), +\fBsd_uid_get_state\fR(3), +\fBsd_session_is_active\fR(3), +\fBsd_seat_get_active\fR(3), +\fBsd_get_seats\fR(3), +\fBsd_login_monitor_new\fR(3), +\fBsd-daemon\fR(7), +\fBsd-readahead\fR(7), +\fBpkg-config\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE +.SH "NOTES" +.IP " 1." 4 +Multi-Seat on Linux +.RS 4 +\%http://www.freedesktop.org/wiki/Software/systemd/multiseat +.RE diff --git a/man/sd-login.xml b/man/sd-login.xml new file mode 100644 index 0000000..3fc0e16 --- /dev/null +++ b/man/sd-login.xml @@ -0,0 +1,146 @@ + + + + + + + + + sd-login + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd-login + 7 + + + + sd-login + APIs for + tracking logins + + + + + #include <systemd/sd-login.h> + + + + pkg-config --cflags --libs libsystemd-login + + + + + Description + + sd-login.h provides APIs to + introspect and monitor seat, login session and user + status information on the local system. + + See Multi-Seat + on Linux for an introduction into multi-seat + support on Linux, the background for this set of APIs. + + Note that these APIs only allow purely passive access + and monitoring of seats, sessions and users. To + actively make changes to the seat configuration, + terminate login sessions, or switch session on a seat + you need to utilize the D-Bus API of + systemd-logind, instead. + + These functions synchronously access data in + /proc, + /sys/fs/cgroup and + /run. All of these are virtual + file systems, hence the runtime cost of the accesses + is relatively cheap. + + It is possible (and often a very good choice) to + mix calls to the synchronous interface of + sd-login.h with the asynchronous + D-Bus interface of systemd-logind. However, if this is + done you need to think a bit about possible races + since the stream of events from D-Bus and from + sd-login.h interfaces such as the + login monitor are asynchronous and not ordered against + each other. + + If the functions return string arrays, these are + generally NULL terminated and need to be freed by the + caller with the libc + free3 + call after use, including the strings referenced + therein. Similar, individual strings returned need to + be freed, as well. + + As a special exception, instead of an empty + string array NULL may be returned, which should be + treated equivalent to an empty string array. + + See + sd_pid_get_session3, + sd_uid_get_state3, + sd_session_is_active3, + sd_seat_get_active3, + sd_get_seats3, + sd_login_monitor_new3 + for more information about the functions + implemented. + + + + Notes + + These APIs are implemented as shared library, + which can be compiled and linked to with the + libsystemd-login + pkg-config1 + file. + + + + See Also + + systemd1, + sd_pid_get_session3, + sd_uid_get_state3, + sd_session_is_active3, + sd_seat_get_active3, + sd_get_seats3, + sd_login_monitor_new3, + sd-daemon7, + sd-readahead7, + pkg-config1 + + + + diff --git a/man/sd-readahead.7 b/man/sd-readahead.7 new file mode 100644 index 0000000..0cc3914 --- /dev/null +++ b/man/sd-readahead.7 @@ -0,0 +1,80 @@ +'\" t +.\" Title: sd-readahead +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sd-readahead +.\" Source: systemd +.\" Language: English +.\" +.TH "SD\-READAHEAD" "7" "02/15/2012" "systemd" "sd-readahead" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sd-readahead \- Reference implementation of APIs for controlling boot\-time read\-ahead +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include "sd\-readahead\&.h" +.fi +.ft +.SH "DESCRIPTION" +.PP +sd\-readahead\&.c +and +sd\-readahead\&.h +provide a reference implementation for APIs for controlling boot\-time read\-ahead, as implemented by the read\-ahead subsystem of the +\fBsystemd\fR(1) +init system\&. +.PP +See +\fBsd_readahead\fR(3) +for more information about the function implemented\&. +.SH "NOTES" +.PP +This interface is provided by the reference implementation of APIs for controlling boot\-time read\-ahead and distributed with the systemd package\&. The algorithms it implements are simple, and can easily be reimplemented in daemons if it is important to support this interface without using the reference implementation\&. See the respective function man pages for details\&. +.PP +In addition, for details about the algorithms check the liberally licensed reference implementation sources: +\m[blue]\fB\%http://cgit.freedesktop.org/systemd/systemd/plain/src/readahead/sd-readahead.c\fR\m[] +resp\&. +\m[blue]\fB\%http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-readahead.h\fR\m[] +.PP +These APIs are implemented in the reference implementation\*(Aqs drop\-in +sd\-readahead\&.c +and +sd\-readahead\&.h +files\&. It is recommended that applications consuming these APIs copy the implementation into their source tree, either verbatim or in excerpts\&. These interfaces are currently not available in a dynamic library\&. +.PP +The functions provided by this interface become NOPs when \-DDISABLE_SYSTEMD is set during compilation\&. In addition, if +sd\-readhead\&.c +is compiled on non\-Linux systems it becomes NOPs\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd_readahead\fR(3), +\fBsd-daemon\fR(7) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/sd-readahead.xml b/man/sd-readahead.xml new file mode 100644 index 0000000..7fb8634 --- /dev/null +++ b/man/sd-readahead.xml @@ -0,0 +1,117 @@ + + + + + + + + + sd-readahead + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd-readahead + 7 + + + + sd-readahead + Reference implementation of APIs for + controlling boot-time read-ahead + + + + + #include "sd-readahead.h" + + + + + Description + + sd-readahead.c and + sd-readahead.h provide a + reference implementation for APIs for controlling boot-time + read-ahead, as implemented by the read-ahead subsystem + of the + systemd1 + init system. + + See + sd_readahead3 + for more information about the function + implemented. + + + + Notes + + This interface is provided by the reference + implementation of APIs for controlling boot-time + read-ahead and distributed with the systemd + package. The algorithms it implements are simple, and + can easily be reimplemented in daemons if it is + important to support this interface without using the + reference implementation. See the respective function + man pages for details. + + In addition, for details about the algorithms + check the liberally licensed reference implementation + sources: + + resp. + + These APIs are implemented in the reference + implementation's drop-in + sd-readahead.c and + sd-readahead.h files. It is + recommended that applications consuming these APIs copy + the implementation into their source tree, either + verbatim or in excerpts. These interfaces are + currently not available in a dynamic library. + + The functions provided by this interface become + NOPs when -DDISABLE_SYSTEMD is set during + compilation. In addition, if + sd-readhead.c is compiled on + non-Linux systems it becomes NOPs. + + + + See Also + + systemd1, + sd_readahead3, + sd-daemon7 + + + + diff --git a/man/sd_booted.3 b/man/sd_booted.3 new file mode 100644 index 0000000..c6ba5d9 --- /dev/null +++ b/man/sd_booted.3 @@ -0,0 +1,88 @@ +'\" t +.\" Title: sd_booted +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sd_booted +.\" Source: systemd +.\" Language: English +.\" +.TH "SD_BOOTED" "3" "02/15/2012" "systemd" "sd_booted" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sd_booted \- Test whether the system is running the systemd init system\&. +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include +.fi +.ft +.HP \w'int\ sd_booted('u +.BI "int sd_booted(void);" +.SH "DESCRIPTION" +.PP +\fBsd_booted()\fR +checks whether the system was booted up using the systemd init system\&. +.SH "RETURN VALUE" +.PP +On failure, this call returns a negative errno\-style error code\&. If the system was booted up with systemd as init system, this call returns a positive return value, zero otherwise\&. +.SH "NOTES" +.PP +This function is provided by the reference implementation of APIs for new\-style daemons and distributed with the systemd package\&. The algorithm it implements is simple, and can easily be reimplemented in daemons if it is important to support this interface without using the reference implementation\&. +.PP +Internally, this function checks whether the +/sys/fs/cgroup/systemd +virtual file system is mounted, by comparing the st_dev value of the +\fBstat()\fR +data of +/sys/fs/cgroup +and +/sys/fs/cgroup/systemd\&. +.PP +For details about the algorithm check the liberally licensed reference implementation sources: +\m[blue]\fB\%http://cgit.freedesktop.org/systemd/systemd/plain/src/sd-daemon.c\fR\m[] +resp\&. +\m[blue]\fB\%http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h\fR\m[] +.PP +\fBsd_booted()\fR +is implemented in the reference implementation\*(Aqs +sd\-daemon\&.c +and +sd\-daemon\&.h +files\&. These interfaces are available as shared library, which can be compiled and linked to with the +libsystemd\-daemon +\fBpkg-config\fR(1) +file\&. Alternatively, applications consuming these APIs may copy the implementation into their source tree\&. For more details about the reference implementation see +\fBsd_daemon\fR(7)\&. +.PP +If the reference implementation is used as drop\-in files and \-DDISABLE_SYSTEMD is set during compilation this function will always return 0 and otherwise become a NOP\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd_daemon\fR(7) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/sd_booted.xml b/man/sd_booted.xml new file mode 100644 index 0000000..141625d --- /dev/null +++ b/man/sd_booted.xml @@ -0,0 +1,128 @@ + + + + + + + + + sd_booted + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_booted + 3 + + + + sd_booted + Test whether the system is running the systemd init system. + + + + + #include <systemd/sd-daemon.h> + + + int sd_booted + void + + + + + + Description + sd_booted() checks whether + the system was booted up using the systemd init system. + + + + Return Value + + On failure, this call returns a negative + errno-style error code. If the system was booted up + with systemd as init system, this call returns a + positive return value, zero otherwise. + + + + Notes + + This function is provided by the reference + implementation of APIs for new-style daemons and + distributed with the systemd package. The algorithm it + implements is simple, and can easily be reimplemented + in daemons if it is important to support this + interface without using the reference + implementation. + + Internally, this function checks whether the + /sys/fs/cgroup/systemd virtual file + system is mounted, by comparing the st_dev value of + the stat() data of + /sys/fs/cgroup and + /sys/fs/cgroup/systemd. + + For details about the algorithm check the + liberally licensed reference implementation sources: + + resp. + + sd_booted() is implemented + in the reference implementation's + sd-daemon.c and + sd-daemon.h files. These + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-daemon + pkg-config1 + file. Alternatively, applications consuming these APIs + may copy the implementation into their source + tree. For more details about the reference + implementation see + sd_daemon7. + + If the reference implementation is used as + drop-in files and -DDISABLE_SYSTEMD is set during + compilation this function will always return 0 and + otherwise become a NOP. + + + + See Also + + systemd1, + sd_daemon7 + + + + diff --git a/man/sd_get_seats.3 b/man/sd_get_seats.3 new file mode 100644 index 0000000..7a933ec --- /dev/null +++ b/man/sd_get_seats.3 @@ -0,0 +1,89 @@ +'\" t +.\" Title: sd_get_seats +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sd_get_seats +.\" Source: systemd +.\" Language: English +.\" +.TH "SD_GET_SEATS" "3" "02/15/2012" "systemd" "sd_get_seats" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sd_get_seats, sd_get_sessions, sd_get_uids \- Determine available seats, sessions and logged in users +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include +.fi +.ft +.HP \w'int\ sd_get_seats('u +.BI "int sd_get_seats(char***\ " "seats" ");" +.HP \w'int\ sd_get_sessions('u +.BI "int sd_get_sessions(char***\ " "sessions" ");" +.HP \w'int\ sd_get_uids('u +.BI "int sd_get_uids(char***\ " "sessions" ");" +.SH "DESCRIPTION" +.PP +\fBsd_get_seats()\fR +may be used to determine all currently available local seats\&. Returns a NULL terminated array of seat identifiers\&. The returned array and all strings it references need to be freed with the libc +\fBfree\fR(3) +call after use\&. Note that instead of an empty array NULL may be returned and should be considered equivalent to an empty array\&. +.PP +Similar, +\fBsd_get_sessions()\fR +may be used to determine all current login sessions\&. +.PP +Similar, +\fBsd_get_uids()\fR +may be used to determine all Unix users who currently have login sessions\&. +.SH "RETURN VALUE" +.PP +On success +\fBsd_get_seats()\fR, +\fBsd_get_sessions()\fR +and +\fBsd_get_uids()\fR +return the number of entries in the arrays\&. On failure, these calls return a negative errno\-style error code\&. +.SH "NOTES" +.PP +The +\fBsd_get_seats()\fR, +\fBsd_get_sessions()\fR +and +\fBsd_get_uids()\fR +interfaces are available as shared library, which can be compiled and linked to with the +libsystemd\-login +\fBpkg-config\fR(1) +file\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd-login\fR(7), +\fBsd_session_get_seat\fR(3) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/sd_get_seats.xml b/man/sd_get_seats.xml new file mode 100644 index 0000000..2ac7650 --- /dev/null +++ b/man/sd_get_seats.xml @@ -0,0 +1,127 @@ + + + + + + + + + sd_get_seats + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_get_seats + 3 + + + + sd_get_seats + sd_get_sessions + sd_get_uids + Determine available seats, sessions and logged in users + + + + + #include <systemd/sd-login.h> + + + int sd_get_seats + char*** seats + + + + int sd_get_sessions + char*** sessions + + + + int sd_get_uids + char*** sessions + + + + + + + Description + + sd_get_seats() may be used + to determine all currently available local + seats. Returns a NULL terminated array of seat + identifiers. The returned array and all strings it + references need to be freed with the libc + free3 + call after use. Note that instead of an empty array + NULL may be returned and should be considered + equivalent to an empty array. + + Similar, sd_get_sessions() may + be used to determine all current login sessions. + + Similar, sd_get_uids() may + be used to determine all Unix users who currently have login sessions. + + + + Return Value + + On success sd_get_seats(), + sd_get_sessions() and + sd_get_uids() return the number + of entries in the arrays. On failure, these calls + return a negative errno-style error code. + + + + Notes + + The sd_get_seats(), + sd_get_sessions() and + sd_get_uids() interfaces + are available as shared library, which can be compiled + and linked to with the + libsystemd-login + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-login7, + sd_session_get_seat3 + + + + diff --git a/man/sd_get_sessions.3 b/man/sd_get_sessions.3 new file mode 100644 index 0000000..e7cdc2d --- /dev/null +++ b/man/sd_get_sessions.3 @@ -0,0 +1 @@ +.so man3/sd_get_seats.3 diff --git a/man/sd_get_uids.3 b/man/sd_get_uids.3 new file mode 100644 index 0000000..e7cdc2d --- /dev/null +++ b/man/sd_get_uids.3 @@ -0,0 +1 @@ +.so man3/sd_get_seats.3 diff --git a/man/sd_is_fifo.3 b/man/sd_is_fifo.3 new file mode 100644 index 0000000..7602e43 --- /dev/null +++ b/man/sd_is_fifo.3 @@ -0,0 +1,138 @@ +'\" t +.\" Title: sd_is_fifo +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sd_is_fifo +.\" Source: systemd +.\" Language: English +.\" +.TH "SD_IS_FIFO" "3" "02/15/2012" "systemd" "sd_is_fifo" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sd_is_fifo, sd_is_socket, sd_is_socket_inet, sd_is_socket_unix, sd_is_mq \- Check the type of a file descriptor +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include +.fi +.ft +.HP \w'int\ sd_is_fifo('u +.BI "int sd_is_fifo(int\ " "fd" ", const\ char\ *" "path" ");" +.HP \w'int\ sd_is_socket('u +.BI "int sd_is_socket(int\ " "fd" ", int\ " "family" ", int\ " "type" ", int\ " "listening" ");" +.HP \w'int\ sd_is_socket_inet('u +.BI "int sd_is_socket_inet(int\ " "fd" ", int\ " "family" ", int\ " "type" ", int\ " "listening" ", uint16_t\ " "port" ");" +.HP \w'int\ sd_is_socket_unix('u +.BI "int sd_is_socket_unix(int\ " "fd" ", int\ " "type" ", int\ " "listening" ", const\ char*\ " "path" ", size_t\ " "length" ");" +.HP \w'int\ sd_is_mq('u +.BI "int sd_is_mq(int\ " "fd" ", const\ char\ *" "path" ");" +.SH "DESCRIPTION" +.PP +\fBsd_is_fifo()\fR +may be called to check whether the specified file descriptor refers to a FIFO or pipe\&. If the +\fIpath\fR +parameter is not NULL, it is checked whether the FIFO is bound to the specified file system path\&. +.PP +\fBsd_is_socket()\fR +may be called to check whether the specified file descriptor refers to a socket\&. It the +\fIfamily\fR +parameter is not AF_UNSPEC it is checked whether the socket is of the specified family (AF_UNIX, AF_INET, \&.\&.\&.)\&. If the +\fItype\fR +parameter is not 0 it is checked whether the socket is of the specified type (SOCK_STREAM, SOCK_DGRAM, \&.\&.\&.)\&. If the +\fIlistening\fR +parameter is positive it is checked whether the socket is in accepting mode, i\&.e\&. +\fBlisten()\fR +has been called for it\&. If +\fIlistening\fR +is 0, it is checked whether the socket is not in this mode\&. If the parameter is negative, no such check is made\&. The +\fIlistening\fR +parameter should only be used for stream sockets and should be set to a negative value otherwise\&. +.PP +\fBsd_is_socket_inet()\fR +is similar to +\fBsd_is_socket()\fR, but optionally checks the IPv4 or IPv6 port number the socket is bound to, unless +\fIport\fR +is zero\&. For this call +\fIfamily\fR +must be passed as either AF_UNSPEC, AF_INET or AF_INET6\&. +.PP +\fBsd_is_socket_unix()\fR +is similar to +\fBsd_is_socket()\fR, but optionally checks the AF_UNIX path the socket is bound to, unless the +\fIpath\fR +parameter is NULL\&. For normal file system AF_UNIX sockets set the +\fIlength\fR +parameter to 0\&. For Linux abstract namespace sockets set the +\fIlength\fR +to the size of the address, including the initial 0 byte and set +\fIpath\fR +to the initial 0 byte of the socket address\&. +.PP +\fBsd_is_mq()\fR +may be called to check whether the specified file descriptor refers to a POSIX message queue\&. If the +\fIpath\fR +parameter is not NULL, it is checked whether the message queue is bound to the specified name\&. +.SH "RETURN VALUE" +.PP +On failure, these calls return a negative errno\-style error code\&. If the file descriptor is of the specified type and bound to the specified address a positive return value is returned, otherwise zero\&. +.SH "NOTES" +.PP +These functions are provided by the reference implementation of APIs for new\-style daemons and distributed with the systemd package\&. The algorithms they implement are simple, and can easily be reimplemented in daemons if it is important to support this interface without using the reference implementation\&. +.PP +Internally, these function use a combination of +fstat() +and +getsockname() +to check the file descriptor type and where it is bound to\&. +.PP +For details about the algorithms check the liberally licensed reference implementation sources: +\m[blue]\fB\%http://cgit.freedesktop.org/systemd/systemd/plain/src/sd-daemon.c\fR\m[] +resp\&. +\m[blue]\fB\%http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h\fR\m[] +.PP +\fBsd_is_fifo()\fR +and the related functions are implemented in the reference implementation\*(Aqs +sd\-daemon\&.c +and +sd\-daemon\&.h +files\&. These interfaces are available as shared library, which can be compiled and linked to with the +libsystemd\-daemon +\fBpkg-config\fR(1) +file\&. Alternatively, applications consuming these APIs may copy the implementation into their source tree\&. For more details about the reference implementation see +\fBsd_daemon\fR(7)\&. +.PP +These functions continue to work as described, even if \-DDISABLE_SYSTEMD is set during compilation\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd-daemon\fR(7), +\fBsd_listen_fds\fR(3), +\fBsystemd.service\fR(5), +\fBsystemd.socket\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/sd_is_fifo.xml b/man/sd_is_fifo.xml new file mode 100644 index 0000000..4db5120 --- /dev/null +++ b/man/sd_is_fifo.xml @@ -0,0 +1,217 @@ + + + + + + + + + sd_is_fifo + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_is_fifo + 3 + + + + sd_is_fifo + sd_is_socket + sd_is_socket_inet + sd_is_socket_unix + sd_is_mq + Check the type of a file descriptor + + + + + #include <systemd/sd-daemon.h> + + + int sd_is_fifo + int fd + const char *path + + + + int sd_is_socket + int fd + int family + int type + int listening + + + + int sd_is_socket_inet + int fd + int family + int type + int listening + uint16_t port + + + + int sd_is_socket_unix + int fd + int type + int listening + const char* path + size_t length + + + + int sd_is_mq + int fd + const char *path + + + + + + + Description + + sd_is_fifo() may be called + to check whether the specified file descriptor refers + to a FIFO or pipe. If the path + parameter is not NULL, it is checked whether the FIFO + is bound to the specified file system path. + + sd_is_socket() may be + called to check whether the specified file descriptor + refers to a socket. It the + family parameter is not + AF_UNSPEC it is checked whether the socket is of the + specified family (AF_UNIX, AF_INET, ...). If the + type parameter is not 0 it is + checked whether the socket is of the specified type + (SOCK_STREAM, SOCK_DGRAM, ...). If the + listening parameter is positive + it is checked whether the socket is in accepting mode, + i.e. listen() has been called for + it. If listening is 0, it is + checked whether the socket is not in this mode. If the + parameter is negative, no such check is made. The + listening parameter should only + be used for stream sockets and should be set to a + negative value otherwise. + + sd_is_socket_inet() is + similar to sd_is_socket(), but + optionally checks the IPv4 or IPv6 port number the + socket is bound to, unless port + is zero. For this call family + must be passed as either AF_UNSPEC, AF_INET or + AF_INET6. + + sd_is_socket_unix() is + similar to sd_is_socket(), but + optionally checks the AF_UNIX path the socket is bound + to, unless the path parameter + is NULL. For normal file system AF_UNIX sockets set + the length parameter to 0. For + Linux abstract namespace sockets set the + length to the size of the + address, including the initial 0 byte and set + path to the initial 0 byte of + the socket address. + + sd_is_mq() may be called to + check whether the specified file descriptor refers to + a POSIX message queue. If the + path parameter is not NULL, it + is checked whether the message queue is bound to the + specified name. + + + + Return Value + + On failure, these calls return a negative + errno-style error code. If the file descriptor is of + the specified type and bound to the specified address + a positive return value is returned, otherwise + zero. + + + + Notes + + These functions are provided by the reference + implementation of APIs for new-style daemons and + distributed with the systemd package. The algorithms + they implement are simple, and can easily be + reimplemented in daemons if it is important to support + this interface without using the reference + implementation. + + Internally, these function use a combination of + fstat() and + getsockname() to check the file + descriptor type and where it is bound to. + + For details about the algorithms check the + liberally licensed reference implementation sources: + + resp. + + sd_is_fifo() and the + related functions are implemented in the reference + implementation's sd-daemon.c and + sd-daemon.h files. These + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-daemon + pkg-config1 + file. Alternatively, applications consuming these APIs + may copy the implementation into their source + tree. For more details about the reference + implementation see + sd_daemon7. + + These functions continue to work as described, + even if -DDISABLE_SYSTEMD is set during + compilation. + + + + See Also + + systemd1, + sd-daemon7, + sd_listen_fds3, + systemd.service5, + systemd.socket5 + + + + diff --git a/man/sd_is_mq.3 b/man/sd_is_mq.3 new file mode 100644 index 0000000..daadb93 --- /dev/null +++ b/man/sd_is_mq.3 @@ -0,0 +1 @@ +.so man3/sd_is_fifo.3 diff --git a/man/sd_is_socket.3 b/man/sd_is_socket.3 new file mode 100644 index 0000000..daadb93 --- /dev/null +++ b/man/sd_is_socket.3 @@ -0,0 +1 @@ +.so man3/sd_is_fifo.3 diff --git a/man/sd_is_socket_inet.3 b/man/sd_is_socket_inet.3 new file mode 100644 index 0000000..daadb93 --- /dev/null +++ b/man/sd_is_socket_inet.3 @@ -0,0 +1 @@ +.so man3/sd_is_fifo.3 diff --git a/man/sd_is_socket_unix.3 b/man/sd_is_socket_unix.3 new file mode 100644 index 0000000..daadb93 --- /dev/null +++ b/man/sd_is_socket_unix.3 @@ -0,0 +1 @@ +.so man3/sd_is_fifo.3 diff --git a/man/sd_listen_fds.3 b/man/sd_listen_fds.3 new file mode 100644 index 0000000..425ee6c --- /dev/null +++ b/man/sd_listen_fds.3 @@ -0,0 +1,127 @@ +'\" t +.\" Title: sd_listen_fds +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sd_listen_fds +.\" Source: systemd +.\" Language: English +.\" +.TH "SD_LISTEN_FDS" "3" "02/15/2012" "systemd" "sd_listen_fds" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sd_listen_fds \- Check for file descriptors passed by the init system\&. +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include +.fi +.ft +.sp +.ft B +.nf +#define SD_LISTEN_FDS_START 3 +.fi +.ft +.HP \w'int\ sd_listen_fds('u +.BI "int sd_listen_fds(int\ " "unset_environment" ");" +.SH "DESCRIPTION" +.PP +\fBsd_listen_fds()\fR +shall be called by a daemon to check for file descriptors passed by the init system as part of the socket\-based activation logic\&. +.PP +If the +\fIunset_environment\fR +parameter is non\-zero +\fBsd_listen_fds()\fR +will unset the +\fI$LISTEN_FDS\fR/\fI$LISTEN_PID\fR +environment variables before returning (regardless whether the function call itself succeeded or not)\&. Further calls to +\fBsd_listen_fds()\fR +will then fail, but the variables are no longer inherited by child processes\&. +.PP +If a daemon receives more than one file descriptor, they will be passed in the same order as configured in the systemd socket definition file\&. Nonetheless it is recommended to verify the correct socket types before using them\&. To simplify this checking the functions +\fBsd_is_fifo\fR(3), +\fBsd_is_socket\fR(3), +\fBsd_is_socket_inet\fR(3), +\fBsd_is_socket_unix\fR(3) +are provided\&. In order to maximize flexibility it is recommended to make these checks as loose as possible without allowing incorrect setups\&. i\&.e\&. often the actual port number a socket is bound to matters little for the service to work, hence it should not be verified\&. On the other hand, whether a socket is a datagram or stream socket matters a lot for the most common program logics and should be checked\&. +.PP +This function call will set the FD_CLOEXEC flag for all passed file descriptors to avoid further inheritance to children of the calling process\&. +.SH "RETURN VALUE" +.PP +On failure, this call returns a negative errno\-style error code\&. If +\fI$LISTEN_FDS\fR/\fI$LISTEN_PID\fR +was not set or was not correctly set for this daemon and hence no file descriptors were received, 0 is returned\&. Otherwise the number of file descriptors passed is returned\&. The application may find them starting with file descriptor SD_LISTEN_FDS_START, i\&.e\&. file descriptor 3\&. +.SH "NOTES" +.PP +This function is provided by the reference implementation of APIs for new\-style daemons and distributed with the systemd package\&. The algorithm it implements is simple, and can easily be reimplemented in daemons if it is important to support this interface without using the reference implementation\&. +.PP +Internally, this function checks whether the +\fI$LISTEN_PID\fR +environment variable equals the daemon PID\&. If not, it returns immediately\&. Otherwise it parses the number passed in the +\fI$LISTEN_FDS\fR +environment variable, then sets the FD_CLOEXEC flag for the parsed number of file descriptors starting from SD_LISTEN_FDS_START\&. Finally it returns the parsed number\&. +.PP +For details about the algorithm check the liberally licensed reference implementation sources: +\m[blue]\fB\%http://cgit.freedesktop.org/systemd/systemd/plain/src/sd-daemon.c\fR\m[] +resp\&. +\m[blue]\fB\%http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h\fR\m[] +.PP +\fBsd_listen_fds()\fR +is implemented in the reference implementation\*(Aqs +sd\-daemon\&.c +and +sd\-daemon\&.h +files\&. These interfaces are available as shared library, which can be compiled and linked to with the +libsystemd\-daemon +\fBpkg-config\fR(1) +file\&. Alternatively, applications consuming these APIs may copy the implementation into their source tree\&. For more details about the reference implementation see +\fBsd-daemon\fR(7)\&. +.PP +If the reference implementation is used as drop\-in files and \-DDISABLE_SYSTEMD is set during compilation this function will always return 0 and otherwise become a NOP\&. +.SH "ENVIRONMENT" +.PP +\fI$LISTEN_PID\fR, \fI$LISTEN_FDS\fR +.RS 4 +Set by the init system for supervised processes that use socket\-based activation\&. This environment variable specifies the data +\fBsd_listen_fds()\fR +parses\&. See above for details\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd-daemon\fR(7), +\fBsd_is_fifo\fR(3), +\fBsd_is_socket\fR(3), +\fBsd_is_socket_inet\fR(3), +\fBsd_is_socket_unix\fR(3), +\fBdaemon\fR(7), +\fBsystemd.service\fR(5), +\fBsystemd.socket\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/sd_listen_fds.xml b/man/sd_listen_fds.xml new file mode 100644 index 0000000..c3c70a0 --- /dev/null +++ b/man/sd_listen_fds.xml @@ -0,0 +1,203 @@ + + + + + + + + + sd_listen_fds + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_listen_fds + 3 + + + + sd_listen_fds + Check for file descriptors passed by the init system. + + + + + #include <systemd/sd-daemon.h> + + #define SD_LISTEN_FDS_START 3 + + + int sd_listen_fds + int unset_environment + + + + + + Description + + sd_listen_fds() shall be + called by a daemon to check for file descriptors + passed by the init system as part of the socket-based + activation logic. + + If the unset_environment + parameter is non-zero + sd_listen_fds() will unset the + $LISTEN_FDS/$LISTEN_PID + environment variables before returning (regardless + whether the function call itself succeeded or + not). Further calls to + sd_listen_fds() will then fail, + but the variables are no longer inherited by child + processes. + + If a daemon receives more than one file + descriptor, they will be passed in the same order as + configured in the systemd socket definition + file. Nonetheless it is recommended to verify the + correct socket types before using them. To simplify + this checking the functions + sd_is_fifo3, + sd_is_socket3, + sd_is_socket_inet3, + sd_is_socket_unix3 + are provided. In order to maximize flexibility it is + recommended to make these checks as loose as possible + without allowing incorrect setups. i.e. often the + actual port number a socket is bound to matters little + for the service to work, hence it should not be + verified. On the other hand, whether a socket is a + datagram or stream socket matters a lot for the most + common program logics and should be checked. + + This function call will set the FD_CLOEXEC flag + for all passed file descriptors to avoid further + inheritance to children of the calling process. + + + + Return Value + + On failure, this call returns a negative + errno-style error code. If + $LISTEN_FDS/$LISTEN_PID + was not set or was not correctly set for this daemon and + hence no file descriptors were received, 0 is + returned. Otherwise the number of file descriptors + passed is returned. The application may find them + starting with file descriptor SD_LISTEN_FDS_START, + i.e. file descriptor 3. + + + + Notes + + This function is provided by the reference + implementation of APIs for new-style daemons and + distributed with the systemd package. The algorithm it + implements is simple, and can easily be reimplemented + in daemons if it is important to support this + interface without using the reference + implementation. + + Internally, this function checks whether the + $LISTEN_PID environment variable + equals the daemon PID. If not, it returns + immediately. Otherwise it parses the number passed in + the $LISTEN_FDS environment + variable, then sets the FD_CLOEXEC flag for the parsed + number of file descriptors starting from + SD_LISTEN_FDS_START. Finally it returns the parsed + number. + + For details about the algorithm check the + liberally licensed reference implementation sources: + + resp. + + sd_listen_fds() is + implemented in the reference implementation's + sd-daemon.c and + sd-daemon.h files. These + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-daemon + pkg-config1 + file. Alternatively, applications consuming these APIs + may copy the implementation into their source + tree. For more details about the reference + implementation see + sd-daemon7. + + If the reference implementation is used as + drop-in files and -DDISABLE_SYSTEMD is set during + compilation this function will always return 0 and + otherwise become a NOP. + + + + Environment + + + + $LISTEN_PID + $LISTEN_FDS + + Set by the init system + for supervised processes that use + socket-based activation. This + environment variable specifies the + data + sd_listen_fds() + parses. See above for + details. + + + + + + See Also + + + systemd1, + sd-daemon7, + sd_is_fifo3, + sd_is_socket3, + sd_is_socket_inet3, + sd_is_socket_unix3, + daemon7, + systemd.service5, + systemd.socket5 + + + + diff --git a/man/sd_login_monitor_flush.3 b/man/sd_login_monitor_flush.3 new file mode 100644 index 0000000..6229cce --- /dev/null +++ b/man/sd_login_monitor_flush.3 @@ -0,0 +1 @@ +.so man3/sd_login_monitor_new.3 diff --git a/man/sd_login_monitor_get_fd.3 b/man/sd_login_monitor_get_fd.3 new file mode 100644 index 0000000..6229cce --- /dev/null +++ b/man/sd_login_monitor_get_fd.3 @@ -0,0 +1 @@ +.so man3/sd_login_monitor_new.3 diff --git a/man/sd_login_monitor_new.3 b/man/sd_login_monitor_new.3 new file mode 100644 index 0000000..28b8a7d --- /dev/null +++ b/man/sd_login_monitor_new.3 @@ -0,0 +1,109 @@ +'\" t +.\" Title: sd_login_monitor_new +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sd_login_monitor_new +.\" Source: systemd +.\" Language: English +.\" +.TH "SD_LOGIN_MONITOR_NEW" "3" "02/15/2012" "systemd" "sd_login_monitor_new" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sd_login_monitor_new, sd_login_monitor_unref, sd_login_monitor_flush, sd_login_monitor_get_fd \- Monitor login sessions, seats and users +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include +.fi +.ft +.HP \w'int\ sd_login_monitor_new('u +.BI "int sd_login_monitor_new(const\ char*\ " "category" ", sd_login_monitor**\ " "ret" ");" +.HP \w'sd_login_monitor*\ sd_login_monitor_unref('u +.BI "sd_login_monitor* sd_login_monitor_unref(sd_login_monitor*\ " "m" ");" +.HP \w'int\ sd_login_monitor_flush('u +.BI "int sd_login_monitor_flush(sd_login_monitor*\ " "m" ");" +.HP \w'int\ sd_login_monitor_get_fd('u +.BI "int sd_login_monitor_get_fd(sd_login_monitor*\ " "m" ");" +.SH "DESCRIPTION" +.PP +\fBsd_login_monitor_new()\fR +may be used to monitor login session, users and seats\&. Via a monitor object a file descriptor can be integrated into an application defined event loop which is woken up each time a user logs in, logs out or a seat is added or removed, or a session, user, or seat changes state otherwise\&. The first parameter takes a string which can be either +seat +(to get only notifications about seats being added, removed or changed), +session +(to get only notifications about sessions being created or removed or changed) or +uid +(to get only notifications when a user changes state in respect to logins)\&. If notifications shall be generated in all these conditions, NULL may be passed\&. Note that in future additional categories may be defined\&. The second parameter returns a monitor object and needs to be freed with the +\fBsd_login_monitor_unref()\fR +call after use\&. +.PP +\fBsd_login_monitor_unref()\fR +may be used to destroy a monitor object\&. Note that this will invalidate any file descriptor returned by +\fBsd_login_monitor_get_fd()\fR\&. +.PP +\fBsd_login_monitor_flush()\fR +may be used to reset the wakeup state of the monitor object\&. Whenever an event causes the monitor to wake up the event loop via the file descriptor this function needs to be called to reset the wake\-up state\&. If this call is not invoked the file descriptor will immediately wake up the event loop again\&. +.PP +\fBsd_login_monitor_get_fd()\fR +may be used to retrieve the file descriptor of the monitor object that may be integrated in an application defined event loop, based around +\fBpoll\fR(2) +or a similar interface\&. The application should include the returned file descriptor as wake up source for POLLIN events\&. Whenever a wake\-up is triggered the file descriptor needs to be reset via +\fBsd_login_monitor_flush()\fR\&. An application needs to reread the login state with a function like +\fBsd_get_seats\fR(3) +or similar to determine what changed\&. +.SH "RETURN VALUE" +.PP +On success +\fBsd_login_monitor_new()\fR +and +\fBsd_login_monitor_flush()\fR +return 0 or a positive integer\&. On success +\fBsd_login_monitor_get_fd()\fR +returns a Unix file descriptor\&. On failure, these calls return a negative errno\-style error code\&. +.PP +\fBsd_login_monitor_unref()\fR +always returns NULL\&. +.SH "NOTES" +.PP +The +\fBsd_login_monitor_new()\fR, +\fBsd_login_monitor_unref()\fR, +\fBsd_login_monitor_flush()\fR +and +\fBsd_login_monitor_get_fd()\fR +interfaces are available as shared library, which can be compiled and linked to with the +libsystemd\-login +\fBpkg-config\fR(1) +file\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd-login\fR(7), +\fBsd_get_seats\fR(3) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml new file mode 100644 index 0000000..de48432 --- /dev/null +++ b/man/sd_login_monitor_new.xml @@ -0,0 +1,172 @@ + + + + + + + + + sd_login_monitor_new + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_login_monitor_new + 3 + + + + sd_login_monitor_new + sd_login_monitor_unref + sd_login_monitor_flush + sd_login_monitor_get_fd + Monitor login sessions, seats and users + + + + + #include <systemd/sd-login.h> + + + int sd_login_monitor_new + const char* category + sd_login_monitor** ret + + + + sd_login_monitor* sd_login_monitor_unref + sd_login_monitor* m + + + + int sd_login_monitor_flush + sd_login_monitor* m + + + + int sd_login_monitor_get_fd + sd_login_monitor* m + + + + + + + Description + + sd_login_monitor_new() may + be used to monitor login session, users and seats. Via + a monitor object a file descriptor can be integrated + into an application defined event loop which is woken + up each time a user logs in, logs out or a seat is + added or removed, or a session, user, or seat changes + state otherwise. The first parameter takes a string + which can be either seat (to get + only notifications about seats being added, removed or + changed), session (to get only + notifications about sessions being created or removed + or changed) or uid (to get only + notifications when a user changes state in respect to + logins). If notifications shall be generated in all + these conditions, NULL may be passed. Note that in + future additional categories may be defined. The + second parameter returns a monitor object and needs to + be freed with the + sd_login_monitor_unref() call + after use. + + sd_login_monitor_unref() + may be used to destroy a monitor object. Note that + this will invalidate any file descriptor returned by + sd_login_monitor_get_fd(). + + sd_login_monitor_flush() + may be used to reset the wakeup state of the monitor + object. Whenever an event causes the monitor to wake + up the event loop via the file descriptor this + function needs to be called to reset the wake-up + state. If this call is not invoked the file descriptor + will immediately wake up the event loop again. + + sd_login_monitor_get_fd() + may be used to retrieve the file descriptor of the + monitor object that may be integrated in an + application defined event loop, based around + poll2 + or a similar interface. The application should include + the returned file descriptor as wake up source for + POLLIN events. Whenever a wake-up is triggered the + file descriptor needs to be reset via + sd_login_monitor_flush(). An + application needs to reread the login state with a + function like + sd_get_seats3 + or similar to determine what changed. + + + + Return Value + + On success + sd_login_monitor_new() and + sd_login_monitor_flush() return 0 + or a positive integer. On success + sd_login_monitor_get_fd() returns + a Unix file descriptor. On failure, these calls return + a negative errno-style error code. + + sd_login_monitor_unref() + always returns NULL. + + + + Notes + + The sd_login_monitor_new(), + sd_login_monitor_unref(), sd_login_monitor_flush() and + sd_login_monitor_get_fd() interfaces + are available as shared library, which can be compiled + and linked to with the + libsystemd-login + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-login7, + sd_get_seats3 + + + + diff --git a/man/sd_login_monitor_unref.3 b/man/sd_login_monitor_unref.3 new file mode 100644 index 0000000..6229cce --- /dev/null +++ b/man/sd_login_monitor_unref.3 @@ -0,0 +1 @@ +.so man3/sd_login_monitor_new.3 diff --git a/man/sd_notify.3 b/man/sd_notify.3 new file mode 100644 index 0000000..ed159b9 --- /dev/null +++ b/man/sd_notify.3 @@ -0,0 +1,210 @@ +'\" t +.\" Title: sd_notify +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sd_notify +.\" Source: systemd +.\" Language: English +.\" +.TH "SD_NOTIFY" "3" "02/15/2012" "systemd" "sd_notify" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sd_notify, sd_notifyf \- Notify init system about start\-up completion and other daemon status changes +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include +.fi +.ft +.HP \w'int\ sd_notify('u +.BI "int sd_notify(int\ " "unset_environment" ", const\ char\ *" "state" ");" +.HP \w'int\ sd_notifyf('u +.BI "int sd_notifyf(int\ " "unset_environment" ", const\ char\ *" "format" ", \&.\&.\&.);" +.SH "DESCRIPTION" +.PP +\fBsd_notify()\fR +shall be called by a daemon to notify the init system about status changes\&. It can be used to send arbitrary information, encoded in an environment\-block\-like string\&. Most importantly it can be used for start\-up completion notification\&. +.PP +If the +\fIunset_environment\fR +parameter is non\-zero +\fBsd_notify()\fR +will unset the +\fI$NOTIFY_SOCKET\fR +environment variable before returning (regardless whether the function call itself succeeded or not)\&. Further calls to +\fBsd_notify()\fR +will then fail, but the variable is no longer inherited by child processes\&. +.PP +The +\fIstate\fR +parameter should contain an newline\-separated list of variable assignments, similar in style to an environment block\&. A trailing newline is implied if none is specified\&. The string may contain any kind of variable assignments, but the following shall be considered well\-known: +.PP +READY=1 +.RS 4 +Tells the init system that daemon startup is finished\&. This is only used by systemd if the service definition file has Type=notify set\&. The passed argument is a boolean "1" or "0"\&. Since there is little value in signalling non\-readiness, the only value daemons should send is "READY=1"\&. +.RE +.PP +STATUS=\&.\&.\&. +.RS 4 +Passes a single\-line status string back to the init system that describes the daemon state\&. This is free\-form and can be used for various purposes: general state feedback, fsck\-like programs could pass completion percentages and failing programs could pass a human readable error message\&. Example: "STATUS=Completed 66% of file system check\&.\&.\&." +.RE +.PP +ERRNO=\&.\&.\&. +.RS 4 +If a daemon fails, the errno\-style error code, formatted as string\&. Example: "ERRNO=2" for ENOENT\&. +.RE +.PP +BUSERROR=\&.\&.\&. +.RS 4 +If a daemon fails, the D\-Bus error\-style error code\&. Example: "BUSERROR=org\&.freedesktop\&.DBus\&.Error\&.TimedOut" +.RE +.PP +MAINPID=\&.\&.\&. +.RS 4 +The main pid of the daemon, in case the init system did not fork off the process itself\&. Example: "MAINPID=4711" +.RE +.PP +WATCHDOG=1 +.RS 4 +Tells systemd to update the watchdog timestamp\&. Services using this feature should do this in regular intervals\&. A watchdog framework can use the timestamps to detect failed services\&. +.RE +.PP +It is recommended to prefix variable names that are not shown in the list above with +\fIX_\fR +to avoid namespace clashes\&. +.PP +Note that systemd will accept status data sent from a daemon only if the +\fINotifyAccess=\fR +option is correctly set in the service definition file\&. See +\fBsystemd.service\fR(5) +for details\&. +.PP +\fBsd_notifyf()\fR +is similar to +\fBsd_notify()\fR +but takes a +\fBprintf()\fR\-like format string plus arguments\&. +.SH "RETURN VALUE" +.PP +On failure, these calls return a negative errno\-style error code\&. If +\fI$NOTIFY_SOCKET\fR +was not set and hence no status data could be sent, 0 is returned\&. If the status was sent these functions return with a positive return value\&. In order to support both, init systems that implement this scheme and those which don\*(Aqt, it is generally recommended to ignore the return value of this call\&. +.SH "NOTES" +.PP +These functions are provided by the reference implementation of APIs for new\-style daemons and distributed with the systemd package\&. The algorithms they implement are simple, and can easily be reimplemented in daemons if it is important to support this interface without using the reference implementation\&. +.PP +Internally, these functions send a single datagram with the state string as payload to the AF_UNIX socket referenced in the +\fI$NOTIFY_SOCKET\fR +environment variable\&. If the first character of +\fI$NOTIFY_SOCKET\fR +is @ the string is understood as Linux abstract namespace socket\&. The datagram is accompanied by the process credentials of the sending daemon, using SCM_CREDENTIALS\&. +.PP +For details about the algorithms check the liberally licensed reference implementation sources: +\m[blue]\fB\%http://cgit.freedesktop.org/systemd/systemd/plain/src/sd-daemon.c\fR\m[] +resp\&. +\m[blue]\fB\%http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h\fR\m[] +.PP +\fBsd_notify()\fR +and +\fBsd_notifyf()\fR +are implemented in the reference implementation\*(Aqs +sd\-daemon\&.c +and +sd\-daemon\&.h +files\&. These interfaces are available as shared library, which can be compiled and linked to with the +libsystemd\-daemon +\fBpkg-config\fR(1) +file\&. Alternatively, applications consuming these APIs may copy the implementation into their source tree\&. For more details about the reference implementation see +\fBsd_daemon\fR(7)\&. +.PP +If the reference implementation is used as drop\-in files and \-DDISABLE_SYSTEMD is set during compilation these functions will always return 0 and otherwise become a NOP\&. +.SH "ENVIRONMENT" +.PP +\fI$NOTIFY_SOCKET\fR +.RS 4 +Set by the init system for supervised processes for status and start\-up completion notification\&. This environment variable specifies the socket +\fBsd_notify()\fR +talks to\&. See above for details\&. +.RE +.SH "EXAMPLES" +.PP +\fBExample\ \&1.\ \&Start-up Notification\fR +.PP +When a daemon finished starting up, it might issue the following call to notify the init system: +.sp +.if n \{\ +.RS 4 +.\} +.nf +sd_notify(0, "READY=1"); +.fi +.if n \{\ +.RE +.\} +.PP +\fBExample\ \&2.\ \&Extended Start-up Notification\fR +.PP +A daemon could send the following after completing initialization: +.sp +.if n \{\ +.RS 4 +.\} +.nf +sd_notifyf(0, "READY=1\en" + "STATUS=Processing requests\&.\&.\&.\en" + "MAINPID=%lu", + (unsigned long) getpid()); +.fi +.if n \{\ +.RE +.\} +.PP +\fBExample\ \&3.\ \&Error Cause Notification\fR +.PP +A daemon could send the following shortly before exiting, on failure +.sp +.if n \{\ +.RS 4 +.\} +.nf +sd_notifyf(0, "STATUS=Failed to start up: %s\en" + "ERRNO=%i", + strerror(errno), + errno); +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd_daemon\fR(7), +\fBdaemon\fR(7), +\fBsystemd.service\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/sd_notify.xml b/man/sd_notify.xml new file mode 100644 index 0000000..9d9ea41 --- /dev/null +++ b/man/sd_notify.xml @@ -0,0 +1,312 @@ + + + + + + + + + sd_notify + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_notify + 3 + + + + sd_notify + sd_notifyf + Notify init system about start-up completion and other daemon status changes + + + + + #include <systemd/sd-daemon.h> + + + int sd_notify + int unset_environment + const char *state + + + + int sd_notifyf + int unset_environment + const char *format + ... + + + + + + Description + sd_notify() shall be called + by a daemon to notify the init system about status + changes. It can be used to send arbitrary information, + encoded in an environment-block-like string. Most + importantly it can be used for start-up completion + notification. + + If the unset_environment + parameter is non-zero sd_notify() + will unset the $NOTIFY_SOCKET + environment variable before returning (regardless + whether the function call itself succeeded or + not). Further calls to + sd_notify() will then fail, but + the variable is no longer inherited by child + processes. + + The state parameter + should contain an newline-separated list of variable + assignments, similar in style to an environment + block. A trailing newline is implied if none is + specified. The string may contain any kind of variable + assignments, but the following shall be considered + well-known: + + + + READY=1 + + Tells the init system + that daemon startup is finished. This + is only used by systemd if the service + definition file has Type=notify + set. The passed argument is a boolean + "1" or "0". Since there is little + value in signalling non-readiness, the + only value daemons should send is + "READY=1". + + + + STATUS=... + + Passes a single-line + status string back to the init system + that describes the daemon state. This + is free-form and can be used for + various purposes: general state + feedback, fsck-like programs could + pass completion percentages and + failing programs could pass a human + readable error message. Example: + "STATUS=Completed 66% of file system + check..." + + + + ERRNO=... + + If a daemon fails, the + errno-style error code, formatted as + string. Example: "ERRNO=2" for + ENOENT. + + + + BUSERROR=... + + If a daemon fails, the + D-Bus error-style error code. Example: + "BUSERROR=org.freedesktop.DBus.Error.TimedOut" + + + + MAINPID=... + + The main pid of the + daemon, in case the init system did + not fork off the process + itself. Example: + "MAINPID=4711" + + + + WATCHDOG=1 + + Tells systemd to + update the watchdog timestamp. + Services using this feature should do + this in regular intervals. A watchdog + framework can use the timestamps to + detect failed + services. + + + + It is recommended to prefix variable names that + are not shown in the list above with + X_ to avoid namespace + clashes. + + Note that systemd will accept status data sent + from a daemon only if the + NotifyAccess= option is correctly + set in the service definition file. See + systemd.service5 + for details. + + sd_notifyf() is similar to + sd_notify() but takes a + printf()-like format string plus + arguments. + + + + Return Value + + On failure, these calls return a negative + errno-style error code. If + $NOTIFY_SOCKET was not set and + hence no status data could be sent, 0 is returned. If + the status was sent these functions return with a + positive return value. In order to support both, init + systems that implement this scheme and those which + don't, it is generally recommended to ignore the return + value of this call. + + + + Notes + + These functions are provided by the reference + implementation of APIs for new-style daemons and + distributed with the systemd package. The algorithms + they implement are simple, and can easily be + reimplemented in daemons if it is important to support + this interface without using the reference + implementation. + + Internally, these functions send a single + datagram with the state string as payload to the + AF_UNIX socket referenced in the + $NOTIFY_SOCKET environment + variable. If the first character of + $NOTIFY_SOCKET is @ the string is + understood as Linux abstract namespace socket. The + datagram is accompanied by the process credentials of + the sending daemon, using SCM_CREDENTIALS. + + For details about the algorithms check the + liberally licensed reference implementation sources: + + resp. + + sd_notify() and + sd_notifyf() are implemented in + the reference implementation's + sd-daemon.c and + sd-daemon.h files. These + interfaces are available as shared library, which can + be compiled and linked to with the + libsystemd-daemon + pkg-config1 + file. Alternatively, applications consuming these APIs + may copy the implementation into their source tree. For + more details about the reference implementation see + sd_daemon7. + + If the reference implementation is used as + drop-in files and -DDISABLE_SYSTEMD is set during + compilation these functions will always return 0 and + otherwise become a NOP. + + + + Environment + + + + $NOTIFY_SOCKET + + Set by the init system + for supervised processes for status + and start-up completion + notification. This environment variable + specifies the socket + sd_notify() talks + to. See above for details. + + + + + + Examples + + + Start-up Notification + + When a daemon finished starting up, it + might issue the following call to notify + the init system: + + sd_notify(0, "READY=1"); + + + + Extended Start-up Notification + + A daemon could send the following after + completing initialization: + + sd_notifyf(0, "READY=1\n" + "STATUS=Processing requests...\n" + "MAINPID=%lu", + (unsigned long) getpid()); + + + + Error Cause Notification + + A daemon could send the following shortly before exiting, on failure + + sd_notifyf(0, "STATUS=Failed to start up: %s\n" + "ERRNO=%i", + strerror(errno), + errno); + + + + + See Also + + systemd1, + sd_daemon7, + daemon7, + systemd.service5 + + + + diff --git a/man/sd_notifyf.3 b/man/sd_notifyf.3 new file mode 100644 index 0000000..c6bfe96 --- /dev/null +++ b/man/sd_notifyf.3 @@ -0,0 +1 @@ +.so man3/sd_notify.3 diff --git a/man/sd_pid_get_owner_uid.3 b/man/sd_pid_get_owner_uid.3 new file mode 100644 index 0000000..8561fee --- /dev/null +++ b/man/sd_pid_get_owner_uid.3 @@ -0,0 +1 @@ +.so man3/sd_pid_get_session.3 diff --git a/man/sd_pid_get_session.3 b/man/sd_pid_get_session.3 new file mode 100644 index 0000000..e8699fc --- /dev/null +++ b/man/sd_pid_get_session.3 @@ -0,0 +1,95 @@ +'\" t +.\" Title: sd_pid_get_session +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sd_pid_get_session +.\" Source: systemd +.\" Language: English +.\" +.TH "SD_PID_GET_SESSION" "3" "02/15/2012" "systemd" "sd_pid_get_session" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sd_pid_get_session, sd_pid_get_unit, sd_pid_get_owner_uid \- Determine session, service or owner of a session of a specific PID +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include +.fi +.ft +.HP \w'int\ sd_pid_get_session('u +.BI "int sd_pid_get_session(pid_t\ " "pid" ", char**\ " "session" ");" +.HP \w'int\ sd_pid_get_unit('u +.BI "int sd_pid_get_unit(pid_t\ " "pid" ", char**\ " "unit" ");" +.HP \w'int\ sd_pid_get_owner_uid('u +.BI "int sd_pid_get_owner_uid(pid_t\ " "pid" ", uid_t*\ " "uid" ");" +.SH "DESCRIPTION" +.PP +\fBsd_pid_get_session()\fR +may be used to determine the login session identifier of a process identified by the specified process identifier\&. The session identifier is a short string, suitable for usage in file system paths\&. Note that not all processes are part of a login session (e\&.g\&. system service processes, user processes that are shared between multiple sessions of the same user, or kernel threads)\&. For processes not being part of a login session this function will fail\&. The returned string needs to be freed with the libc +\fBfree\fR(3) +call after use\&. +.PP +\fBsd_pid_get_unit()\fR +may be used to determine the systemd unit (i\&.e\&. system service) identifier of a process identified by the specified process identifier\&. The unit name is a short string, suitable for usage in file system paths\&. Note that not all processes are part of a unit/service (e\&.g\&. user processes, or kernel threads)\&. For processes not being part of a systemd unit/system service this function will fail\&. The returned string needs to be freed with the libc +\fBfree\fR(3) +call after use\&. +.PP +\fBsd_pid_get_owner_uid()\fR +may be used to determine the Unix user identifier of the owner of the session of a process identified the specified PID\&. Note that this function will succeed for user processes which are shared between multiple login sessions of the same user, where +\fBsd_pid_get_session()\fR +will fail\&. For processes not being part of a login session and not being a shared process of a user this function will fail\&. +.PP +If the +pid +paramater of any of these functions is passed as 0 the operation is executed for the calling process\&. +.SH "RETURN VALUE" +.PP +On success these calls return 0 or a positive integer\&. On failure, these calls return a negative errno\-style error code\&. +.SH "NOTES" +.PP +The +\fBsd_pid_get_session()\fR, +\fBsd_pid_get_pid()\fR, and +\fBsd_pid_get_owner_uid()\fR +interfaces are available as shared library, which can be compiled and linked to with the +libsystemd\-login +\fBpkg-config\fR(1) +file\&. +.PP +Note that the login session identifier as returned by +\fBsd_pid_get_session()\fR +is completely unrelated to the process session identifier as returned by +\fBgetsid\fR(2)\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd-login\fR(7), +\fBsd_session_is_active\fR(3), +\fBgetsid\fR(2) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/sd_pid_get_session.xml b/man/sd_pid_get_session.xml new file mode 100644 index 0000000..94f5330 --- /dev/null +++ b/man/sd_pid_get_session.xml @@ -0,0 +1,160 @@ + + + + + + + + + sd_pid_get_session + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_pid_get_session + 3 + + + + sd_pid_get_session + sd_pid_get_unit + sd_pid_get_owner_uid + Determine session, service or owner of a session of a specific PID + + + + + #include <systemd/sd-login.h> + + + int sd_pid_get_session + pid_t pid + char** session + + + + int sd_pid_get_unit + pid_t pid + char** unit + + + + int sd_pid_get_owner_uid + pid_t pid + uid_t* uid + + + + + + Description + + sd_pid_get_session() may be + used to determine the login session identifier of a + process identified by the specified process + identifier. The session identifier is a short string, + suitable for usage in file system paths. Note that not + all processes are part of a login session (e.g. system + service processes, user processes that are shared + between multiple sessions of the same user, or kernel + threads). For processes not being part of a login + session this function will fail. The returned string + needs to be freed with the libc + free3 + call after use. + + sd_pid_get_unit() may be + used to determine the systemd unit (i.e. system + service) identifier of a process identified by the + specified process identifier. The unit name is a short + string, suitable for usage in file system paths. Note + that not all processes are part of a unit/service + (e.g. user processes, or kernel threads). For + processes not being part of a systemd unit/system + service this function will fail. The returned string + needs to be freed with the libc + free3 + call after use. + + sd_pid_get_owner_uid() may + be used to determine the Unix user identifier of the + owner of the session of a process identified the + specified PID. Note that this function will succeed + for user processes which are shared between multiple + login sessions of the same user, where + sd_pid_get_session() will + fail. For processes not being part of a login session + and not being a shared process of a user this function + will fail. + + If the pid paramater of any + of these functions is passed as 0 the operation is + executed for the calling process. + + + + Return Value + + On success these calls return 0 or a positive + integer. On failure, these calls return a negative + errno-style error code. + + + + Notes + + The sd_pid_get_session(), + sd_pid_get_pid(), and + sd_pid_get_owner_uid() interfaces + are available as shared library, which can be compiled + and linked to with the + libsystemd-login + pkg-config1 + file. + + Note that the login session identifier as + returned by sd_pid_get_session() + is completely unrelated to the process session + identifier as returned by + getsid2. + + + + See Also + + + systemd1, + sd-login7, + sd_session_is_active3, + getsid2 + + + + diff --git a/man/sd_pid_get_unit.3 b/man/sd_pid_get_unit.3 new file mode 100644 index 0000000..8561fee --- /dev/null +++ b/man/sd_pid_get_unit.3 @@ -0,0 +1 @@ +.so man3/sd_pid_get_session.3 diff --git a/man/sd_readahead.3 b/man/sd_readahead.3 new file mode 100644 index 0000000..c89de1d --- /dev/null +++ b/man/sd_readahead.3 @@ -0,0 +1,116 @@ +'\" t +.\" Title: sd_readahead +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sd_readahead +.\" Source: systemd +.\" Language: English +.\" +.TH "SD_READAHEAD" "3" "02/15/2012" "systemd" "sd_readahead" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sd_readahead \- Control ongoing disk boot\-time read\-ahead operations +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include "sd\-readahead\&.h" +.fi +.ft +.HP \w'int\ sd_readahead('u +.BI "int sd_readahead(const\ char\ *" "action" ");" +.SH "DESCRIPTION" +.PP +\fBsd_readahead()\fR +may be called by programs involved with early boot\-up to control ongoing boot\-time disk read\-ahead operations\&. It may be used to terminate read\-ahead operations in case an uncommon disk access pattern is to be expected and hence read\-ahead replay or collection is unlikely to have the desired speed\-up effect on the current or future boot\-ups\&. +.PP +The +\fIaction\fR +should be one of the following strings: +.PP +cancel +.RS 4 +Terminates read\-ahead data collection, and drops all read\-ahead data collected during this boot\-up\&. +.RE +.PP +done +.RS 4 +Terminates read\-ahead data collection, but keeps all read\-ahead data collected during this boot\-up around for use during subsequent boot\-ups\&. +.RE +.PP +noreplay +.RS 4 +Terminates read\-ahead replay\&. +.RE +.SH "RETURN VALUE" +.PP +On failure, these calls return a negative errno\-style error code\&. It is generally recommended to ignore the return value of this call\&. +.SH "NOTES" +.PP +This function is provided by the reference implementation of APIs for controlling boot\-time read\-ahead and distributed with the systemd package\&. The algorithm it implements is simple, and can easily be reimplemented in daemons if it is important to support this interface without using the reference implementation\&. +.PP +Internally, this function creates a file in +/run/systemd/readahead/ +which is then used as flag file to notify the read\-ahead subsystem\&. +.PP +For details about the algorithm check the liberally licensed reference implementation sources: +\m[blue]\fB\%http://cgit.freedesktop.org/systemd/systemd/plain/src/readahead/sd-readahead.c\fR\m[] +resp\&. +\m[blue]\fB\%http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-readahead.h\fR\m[] +.PP +\fBsd_readahead()\fR +is implemented in the reference implementation\*(Aqs drop\-in +sd\-readahead\&.c +and +sd\-readahead\&.h +files\&. It is recommended that applications consuming this API copy the implementation into their source tree\&. For more details about the reference implementation see +\fBsd-readahead\fR(7) +.PP +If \-DDISABLE_SYSTEMD is set during compilation this function will always return 0 and otherwise become a NOP\&. +.SH "EXAMPLES" +.PP +\fBExample\ \&1.\ \&Cancelling all read-ahead operations\fR +.PP +During boots where SELinux has to relabel the file system hierarchy, it will create a large amount of disk accesses that are not necessary during normal boots\&. Hence it is a good idea to disable both read\-ahead replay and read\-ahead collection\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +sd_readahead("cancel"); +sd_readahead("noreplay"); +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd-readahead\fR(7), +\fBdaemon\fR(7) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/sd_readahead.xml b/man/sd_readahead.xml new file mode 100644 index 0000000..2e7e09c --- /dev/null +++ b/man/sd_readahead.xml @@ -0,0 +1,178 @@ + + + + + + + + + sd_readahead + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_readahead + 3 + + + + sd_readahead + Control ongoing disk boot-time read-ahead operations + + + + + #include "sd-readahead.h" + + + int sd_readahead + const char *action + + + + + + Description + sd_readahead() may be + called by programs involved with early boot-up to + control ongoing boot-time disk read-ahead operations. It may be + used to terminate read-ahead operations in case an + uncommon disk access pattern is to be expected and + hence read-ahead replay or collection is unlikely to + have the desired speed-up effect on the current or + future boot-ups. + + The action should be one + of the following strings: + + + + cancel + + Terminates read-ahead + data collection, and drops all + read-ahead data collected during this + boot-up. + + + + done + + Terminates read-ahead + data collection, but keeps all + read-ahead data collected during this + boot-up around for use during + subsequent boot-ups. + + + + noreplay + + Terminates read-ahead + replay. + + + + + + + + Return Value + + On failure, these calls return a negative + errno-style error code. It is generally recommended to + ignore the return value of this call. + + + + Notes + + This function is provided by the reference + implementation of APIs for controlling boot-time + read-ahead and distributed with the systemd + package. The algorithm it implements is simple, and + can easily be reimplemented in daemons if it is + important to support this interface without using the + reference implementation. + + Internally, this function creates a file in + /run/systemd/readahead/ which is + then used as flag file to notify the read-ahead + subsystem. + + For details about the algorithm check the + liberally licensed reference implementation sources: + + resp. + + sd_readahead() is + implemented in the reference implementation's drop-in + sd-readahead.c and + sd-readahead.h files. It is + recommended that applications consuming this API copy + the implementation into their source tree. For more + details about the reference implementation see + sd-readahead7 + + If -DDISABLE_SYSTEMD is set during compilation + this function will always return 0 and otherwise + become a NOP. + + + + Examples + + + Cancelling all read-ahead operations + + During boots where SELinux has to + relabel the file system hierarchy, it will + create a large amount of disk accesses that + are not necessary during normal boots. Hence + it is a good idea to disable both read-ahead replay and read-ahead collection. + + + sd_readahead("cancel"); +sd_readahead("noreplay"); + + + + + + See Also + + systemd1, + sd-readahead7, + daemon7 + + + + diff --git a/man/sd_seat_can_multi_session.3 b/man/sd_seat_can_multi_session.3 new file mode 100644 index 0000000..8d8b08d --- /dev/null +++ b/man/sd_seat_can_multi_session.3 @@ -0,0 +1 @@ +.so man3/sd_seat_get_active.3 diff --git a/man/sd_seat_get_active.3 b/man/sd_seat_get_active.3 new file mode 100644 index 0000000..4ddde6d --- /dev/null +++ b/man/sd_seat_get_active.3 @@ -0,0 +1,93 @@ +'\" t +.\" Title: sd_seat_get_active +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sd_seat_get_active +.\" Source: systemd +.\" Language: English +.\" +.TH "SD_SEAT_GET_ACTIVE" "3" "02/15/2012" "systemd" "sd_seat_get_active" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sd_seat_get_active, sd_seat_get_sessions, sd_seat_can_multi_session \- Determine state of a specific seat +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include +.fi +.ft +.HP \w'int\ sd_seat_get_active('u +.BI "int sd_seat_get_active(const\ char*\ " "seat" ", char**\ " "session" ", uid_t*\ " "uid" ");" +.HP \w'int\ sd_seat_get_sessions('u +.BI "int sd_seat_get_sessions(const\ char*\ " "seat" ", char***\ " "sessions" ", uid_t**\ " "uid" ", unsigned*\ " "n_uids" ");" +.HP \w'int\ sd_seat_can_multi_session('u +.BI "int sd_seat_can_multi_session(const\ char*\ " "seat" ");" +.SH "DESCRIPTION" +.PP +\fBsd_seat_get_active()\fR +may be used to determine which session is currently active on a seat, if there is any\&. Returns the session identifier and the user identifier of the Unix user the session is belonging to\&. Either the session or the user identifier parameter can be be passed NULL, in case only one of the parameters shall be queried\&. The returned string needs to be freed with the libc +\fBfree\fR(3) +call after use\&. +.PP +\fBsd_seat_get_sessions()\fR +may be used to determine all sessions on the specified seat\&. Returns two arrays, one (NULL terminated) with the session identifiers of the sessions and one with the user identifiers of the Unix users the sessions belong to\&. An additional parameter may be used to return the number of entries in the latter array\&. The two arrays and the latter parameter may be passed as NULL in case these values need not to be determined\&. The arrays and the strings referenced by them need to be freed with the libc +\fBfree\fR(3) +call after use\&. Note that instead of an empty array NULL may be returned and should be considered equivalent to an empty array\&. +.PP +\fBsd_seat_can_multi_session()\fR +may be used to determine whether a specific seat is capable of multi\-session, i\&.e\&. allows multiple login sessions in parallel (whith only one being active at a time)\&. +.PP +If the +seat +parameter of any of these functions is passed as NULL the operation is executed for the seat of the session of the calling process, if there is any\&. +.SH "RETURN VALUE" +.PP +On success +\fBsd_seat_get_active()\fR +return return 0 or a positive integer\&. On success +\fBsd_seat_get_sessions()\fR +returns the number of entries in the session identifier array\&. If the test succeeds +\fBsd_seat_can_multi_session\fR +returns a positive integer, if it fails 0\&. On failure, these calls return a negative errno\-style error code\&. +.SH "NOTES" +.PP +The +\fBsd_seat_get_active()\fR, +\fBsd_seat_get_sessions()\fR, and +\fBsd_seat_can_multi_session()\fR +interfaces are available as shared library, which can be compiled and linked to with the +libsystemd\-login +\fBpkg-config\fR(1) +file\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd-login\fR(7), +\fBsd_session_get_seat\fR(3) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml new file mode 100644 index 0000000..acc6ee4 --- /dev/null +++ b/man/sd_seat_get_active.xml @@ -0,0 +1,157 @@ + + + + + + + + + sd_seat_get_active + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_seat_get_active + 3 + + + + sd_seat_get_active + sd_seat_get_sessions + sd_seat_can_multi_session + Determine state of a specific seat + + + + + #include <systemd/sd-login.h> + + + int sd_seat_get_active + const char* seat + char** session + uid_t* uid + + + + int sd_seat_get_sessions + const char* seat + char*** sessions + uid_t** uid + unsigned* n_uids + + + + int sd_seat_can_multi_session + const char* seat + + + + + + Description + + sd_seat_get_active() may be + used to determine which session is currently active on + a seat, if there is any. Returns the session + identifier and the user identifier of the Unix user + the session is belonging to. Either the session or the + user identifier parameter can be be passed NULL, in + case only one of the parameters shall be queried. The + returned string needs to be freed with the libc + free3 + call after use. + + sd_seat_get_sessions() may + be used to determine all sessions on the specified + seat. Returns two arrays, one (NULL terminated) with + the session identifiers of the sessions and one with + the user identifiers of the Unix users the sessions + belong to. An additional parameter may be used to + return the number of entries in the latter array. The + two arrays and the latter parameter may be passed as + NULL in case these values need not to be + determined. The arrays and the strings referenced by + them need to be freed with the libc + free3 + call after use. Note that instead of an empty array + NULL may be returned and should be considered + equivalent to an empty array. + + sd_seat_can_multi_session() + may be used to determine whether a specific seat is + capable of multi-session, i.e. allows multiple login + sessions in parallel (whith only one being active at a + time). + + If the seat parameter of any + of these functions is passed as NULL the operation is + executed for the seat of the session of the calling + process, if there is any. + + + + Return Value + + On success + sd_seat_get_active() return + return 0 or a positive integer. On success + sd_seat_get_sessions() returns + the number of entries in the session identifier + array. If the test succeeds + sd_seat_can_multi_session returns + a positive integer, if it fails 0. On failure, these + calls return a negative errno-style error code. + + + + Notes + + The sd_seat_get_active(), + sd_seat_get_sessions(), and + sd_seat_can_multi_session() interfaces + are available as shared library, which can be compiled + and linked to with the + libsystemd-login + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-login7, + sd_session_get_seat3 + + + + diff --git a/man/sd_seat_get_sessions.3 b/man/sd_seat_get_sessions.3 new file mode 100644 index 0000000..8d8b08d --- /dev/null +++ b/man/sd_seat_get_sessions.3 @@ -0,0 +1 @@ +.so man3/sd_seat_get_active.3 diff --git a/man/sd_session_get_seat.3 b/man/sd_session_get_seat.3 new file mode 100644 index 0000000..b9ad5cd --- /dev/null +++ b/man/sd_session_get_seat.3 @@ -0,0 +1 @@ +.so man3/sd_session_is_active.3 diff --git a/man/sd_session_get_uid.3 b/man/sd_session_get_uid.3 new file mode 100644 index 0000000..b9ad5cd --- /dev/null +++ b/man/sd_session_get_uid.3 @@ -0,0 +1 @@ +.so man3/sd_session_is_active.3 diff --git a/man/sd_session_is_active.3 b/man/sd_session_is_active.3 new file mode 100644 index 0000000..038cc64 --- /dev/null +++ b/man/sd_session_is_active.3 @@ -0,0 +1,101 @@ +'\" t +.\" Title: sd_session_is_active +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sd_session_is_active +.\" Source: systemd +.\" Language: English +.\" +.TH "SD_SESSION_IS_ACTIVE" "3" "02/15/2012" "systemd" "sd_session_is_active" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sd_session_is_active, sd_session_get_uid, sd_session_get_seat, sd_session_get_service \- Determine state of a specific session +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include +.fi +.ft +.HP \w'int\ sd_session_is_active('u +.BI "int sd_session_is_active(const\ char*\ " "session" ");" +.HP \w'int\ sd_session_get_uid('u +.BI "int sd_session_get_uid(const\ char*\ " "session" ", uid_t*\ " "uid" ");" +.HP \w'int\ sd_session_get_seat('u +.BI "int sd_session_get_seat(const\ char*\ " "session" ", char**\ " "seat" ");" +.HP \w'int\ sd_session_get_service('u +.BI "int sd_session_get_service(const\ char*\ " "session" ", char**\ " "service" ");" +.SH "DESCRIPTION" +.PP +\fBsd_session_is_active()\fR +may be used to determine whether the session identified by the specified session identifier is currently active (i\&.e\&. currently in the foreground and available for user input) or not\&. +.PP +\fBsd_session_get_uid()\fR +may be used to determine the user identifier of the Unix user the session identified by the specified session identifier belongs to\&. +.PP +\fBsd_session_get_seat()\fR +may be used to determine the seat identifier of the seat the session identified by the specified session identifier belongs to\&. Note that not all sessions are attached to a seat, this call will fail for them\&. The returned string needs to be freed with the libc +\fBfree\fR(3) +call after use\&. +.PP +\fBsd_session_get_service()\fR +may be used to determine the name of the service (as passed during PAM session setup) that registered the session identified by the specified session identifier\&. The returned string needs to be freed with the libc +\fBfree\fR(3) +call after use\&. +.PP +If the +session +parameter of any of these functions is passed as NULL the operation is executed for the session the calling process is a member of, if there is any\&. +.SH "RETURN VALUE" +.PP +If the test succeeds +\fBsd_session_is_active()\fR +returns a positive integer, if it fails 0\&. On success +\fBsd_session_get_uid()\fR, +\fBsd_session_get_service()\fR +and +\fBsd_session_get_seat()\fR +return 0 or a positive integer\&. On failure, these calls return a negative errno\-style error code\&. +.SH "NOTES" +.PP +The +\fBsd_session_is_active()\fR, +\fBsd_session_get_uid()\fR, +\fBsd_session_get_service()\fR +and +\fBsd_session_get_seat()\fR +interfaces are available as shared library, which can be compiled and linked to with the +libsystemd\-login +\fBpkg-config\fR(1) +file\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd-login\fR(7), +\fBsd_pid_get_session\fR(3) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml new file mode 100644 index 0000000..5db305d --- /dev/null +++ b/man/sd_session_is_active.xml @@ -0,0 +1,157 @@ + + + + + + + + + sd_session_is_active + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_session_is_active + 3 + + + + sd_session_is_active + sd_session_get_uid + sd_session_get_seat + sd_session_get_service + Determine state of a specific session + + + + + #include <systemd/sd-login.h> + + + int sd_session_is_active + const char* session + + + + int sd_session_get_uid + const char* session + uid_t* uid + + + + int sd_session_get_seat + const char* session + char** seat + + + + int sd_session_get_service + const char* session + char** service + + + + + + Description + + sd_session_is_active() may + be used to determine whether the session identified by + the specified session identifier is currently active + (i.e. currently in the foreground and available for + user input) or not. + + sd_session_get_uid() may be + used to determine the user identifier of the Unix user the session + identified by the specified session identifier belongs + to. + + sd_session_get_seat() may + be used to determine the seat identifier of the seat + the session identified by the specified session + identifier belongs to. Note that not all sessions are + attached to a seat, this call will fail for them. The + returned string needs to be freed with the libc + free3 + call after use. + + sd_session_get_service() + may be used to determine the name of the service (as + passed during PAM session setup) that registered the + session identified by the specified session + identifier. The returned string needs to be freed with + the libc + free3 + call after use. + + If the session parameter of + any of these functions is passed as NULL the operation + is executed for the session the calling process is a + member of, if there is any. + + + + Return Value + + If the test succeeds + sd_session_is_active() returns a + positive integer, if it fails 0. On success + sd_session_get_uid(), + sd_session_get_service() and + sd_session_get_seat() return 0 or + a positive integer. On failure, these calls return a + negative errno-style error code. + + + + Notes + + The sd_session_is_active(), + sd_session_get_uid(), + sd_session_get_service() and + sd_session_get_seat() interfaces + are available as shared library, which can be compiled + and linked to with the + libsystemd-login + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-login7, + sd_pid_get_session3 + + + + diff --git a/man/sd_uid_get_seats.3 b/man/sd_uid_get_seats.3 new file mode 100644 index 0000000..616dee5 --- /dev/null +++ b/man/sd_uid_get_seats.3 @@ -0,0 +1 @@ +.so man3/sd_uid_get_state.3 diff --git a/man/sd_uid_get_sessions.3 b/man/sd_uid_get_sessions.3 new file mode 100644 index 0000000..616dee5 --- /dev/null +++ b/man/sd_uid_get_sessions.3 @@ -0,0 +1 @@ +.so man3/sd_uid_get_state.3 diff --git a/man/sd_uid_get_state.3 b/man/sd_uid_get_state.3 new file mode 100644 index 0000000..467f4cd --- /dev/null +++ b/man/sd_uid_get_state.3 @@ -0,0 +1,113 @@ +'\" t +.\" Title: sd_uid_get_state +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sd_uid_get_state +.\" Source: systemd +.\" Language: English +.\" +.TH "SD_UID_GET_STATE" "3" "02/15/2012" "systemd" "sd_uid_get_state" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sd_uid_get_state, sd_uid_is_on_seat, sd_uid_get_sessions, sd_uid_get_seats \- Determine login state of a specific Unix user ID +.SH "SYNOPSIS" +.sp +.ft B +.nf +#include +.fi +.ft +.HP \w'int\ sd_uid_get_state('u +.BI "int sd_uid_get_state(uid_t\ " "pid" ", char**\ " "state" ");" +.HP \w'int\ sd_uid_is_on_seat('u +.BI "int sd_uid_is_on_seat(uid_t\ " "pid" ", int\ " "require_active" ", const\ char*\ " "seat" ");" +.HP \w'int\ sd_uid_get_sessions('u +.BI "int sd_uid_get_sessions(uid_t\ " "pid" ", int\ " "require_active" ", char***\ " "sessions" ");" +.HP \w'int\ sd_uid_get_seats('u +.BI "int sd_uid_get_seats(uid_t\ " "pid" ", int\ " "require_active" ", char***\ " "seats" ");" +.SH "DESCRIPTION" +.PP +\fBsd_uid_get_state()\fR +may be used to determine the login state of a specific Unix user identifier\&. The following states are currently known: +offline +(user not logged in at all), +lingering +(user not logged in, but some user services running), +online +(user logged in, but not active), +active +(user logged in on an active seat)\&. In the future additional states might be defined, client code should be written to be robust in regards to additional state strings being returned\&. The returned string needs to be freed with the libc +\fBfree\fR(3) +call after use\&. +.PP +\fBsd_uid_is_on_seat()\fR +may be used to determine whether a specific user is logged in or active on a specific seat\&. Accepts a Unix user identifier and a seat identifier string as parameters\&. The +\fIrequire_active\fR +parameter is a boolean\&. If non\-zero (true) this function will test if the user is active (i\&.e\&. has a session that is in the foreground and accepting user input) on the specified seat, otherwise (false) only if the user is logged in (and possibly inactive) on the specified seat\&. +.PP +\fBsd_uid_get_sessions()\fR +may be used to determine the current sessions of the specified user\&. Acceptes a Unix user identifier as parameter\&. The +\fIrequire_active\fR +boolean parameter controls whether the returned list shall consist of only those sessions where the user is currently active (true) or where the user is currently logged in at all, possibly inactive (false)\&. The call returns a NULL terminated string array of session identifiers in +\fIsessions\fR +which needs to be freed by the caller with the libc +\fBfree\fR(3) +call after use, including all the strings referenced\&. If the string array parameter is passed as NULL the array will not be filled in, but the return code still indicates the number of current sessions\&. Note that instead of an empty array NULL may be returned and should be considered equivalent to an empty array\&. +.PP +Similar, +\fBsd_uid_get_seats()\fR +may be used to determine the list of seats on which the user currently has sessions\&. Similar semantics apply, however note that the user may have multiple sessions on the same seat as well as sessions with no attached seat and hence the number of entries in the returned array may differ from the one returned by +\fBsd_uid_get_sessions()\fR\&. +.SH "RETURN VALUE" +.PP +On success +\fBsd_uid_get_state()\fR +returns 0 or a positive integer\&. If the test succeeds +\fBsd_uid_is_on_seat()\fR +returns a positive integer, if it fails 0\&. +\fBsd_uid_get_sessions()\fR +and +\fBsd_uid_get_seats()\fR +return the number of entries in the returned arrays\&. On failure, these calls return a negative errno\-style error code\&. +.SH "NOTES" +.PP +The +\fBsd_uid_get_state()\fR, +\fBsd_uid_is_on_seat()\fR, +\fBsd_uid_get_sessions()\fR, and +\fBsd_uid_get_seats()\fR +interfaces are available as shared library, which can be compiled and linked to with the +libsystemd\-login +\fBpkg-config\fR(1) +file\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsd-login\fR(7), +\fBsd_pid_get_owner_uid\fR(3) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/sd_uid_get_state.xml b/man/sd_uid_get_state.xml new file mode 100644 index 0000000..6777625 --- /dev/null +++ b/man/sd_uid_get_state.xml @@ -0,0 +1,185 @@ + + + + + + + + + sd_uid_get_state + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sd_uid_get_state + 3 + + + + sd_uid_get_state + sd_uid_is_on_seat + sd_uid_get_sessions + sd_uid_get_seats + Determine login state of a specific Unix user ID + + + + + #include <systemd/sd-login.h> + + + int sd_uid_get_state + uid_t pid + char** state + + + + int sd_uid_is_on_seat + uid_t pid + int require_active + const char* seat + + + + int sd_uid_get_sessions + uid_t pid + int require_active + char*** sessions + + + + int sd_uid_get_seats + uid_t pid + int require_active + char*** seats + + + + + + Description + + sd_uid_get_state() may be + used to determine the login state of a specific Unix + user identifier. The following states are currently + known: offline (user not logged in + at all), lingering (user not logged + in, but some user services running), + online (user logged in, but not + active), active (user logged in on + an active seat). In the future additional states might + be defined, client code should be written to be robust + in regards to additional state strings being + returned. The returned string needs to be freed with + the libc + free3 + call after use. + + sd_uid_is_on_seat() may be + used to determine whether a specific user is logged in + or active on a specific seat. Accepts a Unix user + identifier and a seat identifier string as + parameters. The require_active + parameter is a boolean. If non-zero (true) this + function will test if the user is active (i.e. has a + session that is in the foreground and accepting user + input) on the specified seat, otherwise (false) only + if the user is logged in (and possibly inactive) on + the specified seat. + + sd_uid_get_sessions() may + be used to determine the current sessions of the + specified user. Acceptes a Unix user identifier as + parameter. The require_active + boolean parameter controls whether the returned list + shall consist of only those sessions where the user is + currently active (true) or where the user is currently + logged in at all, possibly inactive (false). The call + returns a NULL terminated string array of session + identifiers in sessions which + needs to be freed by the caller with the libc + free3 + call after use, including all the strings + referenced. If the string array parameter is passed as + NULL the array will not be filled in, but the return + code still indicates the number of current + sessions. Note that instead of an empty array NULL may + be returned and should be considered equivalent to an + empty array. + + Similar, sd_uid_get_seats() + may be used to determine the list of seats on which + the user currently has sessions. Similar semantics + apply, however note that the user may have + multiple sessions on the same seat as well as sessions + with no attached seat and hence the number of entries + in the returned array may differ from the one returned + by sd_uid_get_sessions(). + + + + Return Value + + On success + sd_uid_get_state() returns 0 or a + positive integer. If the test succeeds + sd_uid_is_on_seat() returns a + positive integer, if it fails + 0. sd_uid_get_sessions() and + sd_uid_get_seats() return the + number of entries in the returned arrays. On failure, + these calls return a negative errno-style error + code. + + + + Notes + + The sd_uid_get_state(), + sd_uid_is_on_seat(), + sd_uid_get_sessions(), and + sd_uid_get_seats() interfaces are + available as shared library, which can be compiled and + linked to with the libsystemd-login + pkg-config1 + file. + + + + See Also + + + systemd1, + sd-login7, + sd_pid_get_owner_uid3 + + + + diff --git a/man/sd_uid_is_on_seat.3 b/man/sd_uid_is_on_seat.3 new file mode 100644 index 0000000..616dee5 --- /dev/null +++ b/man/sd_uid_is_on_seat.3 @@ -0,0 +1 @@ +.so man3/sd_uid_get_state.3 diff --git a/man/shutdown.8 b/man/shutdown.8 new file mode 100644 index 0000000..8b84f08 --- /dev/null +++ b/man/shutdown.8 @@ -0,0 +1,128 @@ +'\" t +.\" Title: shutdown +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: shutdown +.\" Source: systemd +.\" Language: English +.\" +.TH "SHUTDOWN" "8" "02/15/2012" "systemd" "shutdown" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +shutdown \- Halt, power\-off or reboot the machine +.SH "SYNOPSIS" +.HP \w'\fBshutdown\ \fR\fB[OPTIONS...]\fR\fB\ \fR\fB[TIME]\fR\fB\ \fR\fB[WALL...]\fR\ 'u +\fBshutdown \fR\fB[OPTIONS...]\fR\fB \fR\fB[TIME]\fR\fB \fR\fB[WALL...]\fR +.SH "DESCRIPTION" +.PP +\fBshutdown\fR +may be used to halt, power\-off or reboot the machine\&. +.PP +The first argument may be a time string (which is usually +now)\&. Optionally, this may be followed by a wall message to be sent to all logged\-in users before going down\&. +.PP +The time string may either be in the format +hh:mm +for hour/minutes specifying the time to execute the shutdown at, specified in 24h clock format\&. Alternatively it may be in the syntax ++m +referring to the specified number of minutes m from now\&. +now +is an alias for ++0, i\&.e\&. for triggering an immediate shutdown\&. If no time argument is specified, ++1 +is implied\&. +.PP +Note that to specify a wall message you must specify a time argument, too\&. +.PP +If the time argument is used, 5 minutes before the system goes down the +/etc/nologin +file is created to ensure that further logins shall not be allowed\&. +.SH "OPTIONS" +.PP +The following options are understood: +.PP +\fB\-\-help\fR +.RS 4 +Prints a short help text and exits\&. +.RE +.PP +\fB\-H\fR, \fB\-\-halt\fR +.RS 4 +Halt the machine\&. +.RE +.PP +\fB\-P\fR, \fB\-\-poweroff\fR +.RS 4 +Power\-off the machine (the default)\&. +.RE +.PP +\fB\-r\fR, \fB\-\-reboot\fR +.RS 4 +Reboot the machine\&. +.RE +.PP +\fB\-h\fR +.RS 4 +Equivalent to +\fB\-\-poweroff\fR, unless +\fB\-\-halt\fR +is specified\&. +.RE +.PP +\fB\-k\fR +.RS 4 +Don\*(Aqt halt, power\-off, reboot, just write wall message\&. +.RE +.PP +\fB\-\-no\-wall\fR +.RS 4 +Don\*(Aqt send wall message before halt, power\-off, reboot\&. +.RE +.PP +\fB\-c\fR +.RS 4 +Cancel a pending shutdown\&. This may be used cancel the effect of an invocation of +\fBshutdown\fR +with a time argument that is not ++0 +or +now\&. +.RE +.SH "EXIT STATUS" +.PP +On success 0 is returned, a non\-zero failure code otherwise\&. +.SH "NOTES" +.PP +This is a legacy command available for compatibility only\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(1), +\fBhalt\fR(8), +\fBwall\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/shutdown.xml b/man/shutdown.xml new file mode 100644 index 0000000..c8c4b54 --- /dev/null +++ b/man/shutdown.xml @@ -0,0 +1,188 @@ + + + + + + + + + shutdown + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + shutdown + 8 + + + + shutdown + Halt, power-off or reboot the machine + + + + + shutdown OPTIONS TIME WALL + + + + + Description + + shutdown may be used to halt, + power-off or reboot the machine. + + The first argument may be a time string (which + is usually now). Optionally, this + may be followed by a wall message to be sent to all + logged-in users before going down. + + The time string may either be in the format + hh:mm for hour/minutes specifying + the time to execute the shutdown at, specified in 24h + clock format. Alternatively it may be in the syntax + +m referring to the specified + number of minutes m from now. now + is an alias for +0, i.e. for + triggering an immediate shutdown. If no time argument + is specified, +1 is + implied. + + Note that to specify a wall message you must + specify a time argument, too. + + If the time argument is used, 5 minutes + before the system goes down the + /etc/nologin file is created to + ensure that further logins shall not be + allowed. + + + + Options + + The following options are understood: + + + + + + Prints a short help + text and exits. + + + + + + + Halt the machine. + + + + + + + Power-off the + machine (the default). + + + + + + + Reboot the + machine. + + + + + + Equivalent to + , unless + is + specified. + + + + + + Don't halt, power-off, + reboot, just write wall + message. + + + + + + Don't send wall + message before + halt, power-off, reboot. + + + + + + Cancel a pending + shutdown. This may be used cancel the + effect of an invocation of + shutdown with a + time argument that is not + +0 or + now. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Notes + + This is a legacy command available for + compatibility only. + + + + See Also + + systemd1, + systemctl1, + halt8, + wall1 + + + + diff --git a/man/sysctl.d.5 b/man/sysctl.d.5 new file mode 100644 index 0000000..b8a28ce --- /dev/null +++ b/man/sysctl.d.5 @@ -0,0 +1,89 @@ +'\" t +.\" Title: sysctl.d +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: sysctl.d +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSCTL\&.D" "5" "02/15/2012" "systemd" "sysctl.d" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +sysctl.d \- Configure kernel parameters at boot +.SH "SYNOPSIS" +.PP +/usr/lib/sysctl\&.d/*\&.conf +.PP +/etc/sysctl\&.d/*\&.conf +.PP +/run/sysctl\&.d/*\&.conf +.SH "DESCRIPTION" +.PP +\fBsystemd\fR +uses configuration files from the above directories to configure +\fBsysctl\fR(8) +kernel parameters to load during boot\&. +.SH "CONFIGURATION FORMAT" +.PP +The configuration files should simply contain a list of variable assignments, separated by newlines\&. Empty lines and lines whose first non\-whitespace character is # or ; are ignored\&. +.PP +Note that both / and \&. are accepted as separators in sysctl variable names\&. +.PP +Each configuration file is named in the style of +\&.conf\&. Files in +/etc/ +overwrite files with the same name in +/usr/lib/\&. Files in +/run +overwrite files with the same name in +/etc/ +and +/usr/lib/\&. Packages should install their configuration files in +/usr/lib/, files in +/etc/ +are reserved for the local administration, which possibly decides to overwrite the configurations installed from packages\&. All files are sorted by filename in alphabetical order, regardless in which of the directories they reside, to ensure that a specific configuration file takes precedence over another file with an alphabetically later name\&. +.SH "EXAMPLE" +.PP +\fBExample\ \&1.\ \&/etc/sysctl.d/domain-name.conf example:\fR +.sp +.if n \{\ +.RS 4 +.\} +.nf +# Set kernel YP domain name +kernel\&.domainname=example\&.com +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsysctl\fR(8), +\fBsysctl.conf\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/sysctl.d.xml b/man/sysctl.d.xml new file mode 100644 index 0000000..240aa81 --- /dev/null +++ b/man/sysctl.d.xml @@ -0,0 +1,110 @@ + + + + + + + + sysctl.d + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + sysctl.d + 5 + + + + sysctl.d + Configure kernel parameters at boot + + + + /usr/lib/sysctl.d/*.conf + /etc/sysctl.d/*.conf + /run/sysctl.d/*.conf + + + + Description + + systemd uses configuration files + from the above directories to configure + sysctl8 + kernel parameters to load during boot. + + + + Configuration Format + + The configuration files should simply contain a + list of variable assignments, separated by + newlines. Empty lines and lines whose first + non-whitespace character is # or ; are ignored. + + Note that both / and . are accepted as + separators in sysctl variable names. + + Each configuration file is named in the style of + <program>.conf. + Files in /etc/ overwrite + files with the same name in /usr/lib/. + Files in /run overwrite files with + the same name in /etc/ and + /usr/lib/. Packages should install their + configuration files in /usr/lib/, files + in /etc/ are reserved for the local + administration, which possibly decides to overwrite the + configurations installed from packages. All files are sorted + by filename in alphabetical order, regardless in which of the + directories they reside, to ensure that a specific + configuration file takes precedence over another file with + an alphabetically later name. + + + + Example + + /etc/sysctl.d/domain-name.conf example: + + # Set kernel YP domain name +kernel.domainname=example.com + + + + + See Also + + systemd1, + sysctl8, + sysctl.conf5 + + + + diff --git a/man/systemadm.1 b/man/systemadm.1 new file mode 100644 index 0000000..4787677 --- /dev/null +++ b/man/systemadm.1 @@ -0,0 +1,69 @@ +'\" t +.\" Title: systemadm +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemadm +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMADM" "1" "02/15/2012" "systemd" "systemadm" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemadm \- Graphical frontend for the systemd system and service manager +.SH "SYNOPSIS" +.HP \w'\fBsystemadm\ \fR\fB[OPTIONS...]\fR\ 'u +\fBsystemadm \fR\fB[OPTIONS...]\fR +.SH "DESCRIPTION" +.PP +\fBsystemadm\fR +is a graphical frontend for the systemd system and service manager and allows introspection and control of systemd\&. +.SH "OPTIONS" +.PP +The following options are understood: +.PP +\fB\-\-h\fR, \fB\-\-help\fR +.RS 4 +Prints a short help text and exits\&. +.RE +.PP +\fB\-\-system\fR +.RS 4 +Connect to the systemd system manager\&. (Default) +.RE +.PP +\fB\-\-user\fR +.RS 4 +Connect to the systemd manager of the calling user\&. +.RE +.PP +In addition to this a number of parameters common to all Gtk+ programs are supported\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemadm.xml b/man/systemadm.xml new file mode 100644 index 0000000..cefc300 --- /dev/null +++ b/man/systemadm.xml @@ -0,0 +1,111 @@ + + + + + + + + + systemadm + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemadm + 1 + + + + systemadm + Graphical frontend for the systemd system + and service manager + + + + + systemadm OPTIONS + + + + + Description + + systemadm is a graphical + frontend for the systemd system and service manager + and allows introspection and control of + systemd. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + + Connect to the systemd + system + manager. (Default) + + + + + + Connect to the systemd + manager of the calling + user. + + + + + In addition to this a number of parameters + common to all Gtk+ programs are supported. + + + + See Also + + systemd1, + systemctl1 + + + + diff --git a/man/systemctl.1 b/man/systemctl.1 new file mode 100644 index 0000000..cc29490 --- /dev/null +++ b/man/systemctl.1 @@ -0,0 +1,644 @@ +'\" t +.\" Title: systemctl +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemctl +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMCTL" "1" "02/15/2012" "systemd" "systemctl" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemctl \- Control the systemd system and service manager +.SH "SYNOPSIS" +.HP \w'\fBsystemctl\ \fR\fB[OPTIONS...]\fR\fB\ \fR\fB{COMMAND}\fR\fB\ \fR\fB[NAME...]\fR\ 'u +\fBsystemctl \fR\fB[OPTIONS...]\fR\fB \fR\fB{COMMAND}\fR\fB \fR\fB[NAME...]\fR +.SH "DESCRIPTION" +.PP +\fBsystemctl\fR +may be used to introspect and control the state of the +\fBsystemd\fR(1) +system and service manager\&. +.SH "OPTIONS" +.PP +The following options are understood: +.PP +\fB\-\-help\fR, \fB\-h\fR +.RS 4 +Prints a short help text and exits\&. +.RE +.PP +\fB\-\-version\fR +.RS 4 +Prints a short version string and exits\&. +.RE +.PP +\fB\-\-type=\fR, \fB\-t\fR +.RS 4 +When listing units, limit display to certain unit types\&. If not specified units of all types will be shown\&. The argument should be a unit type name such as +\fBservice\fR, +\fBsocket\fR +and similar\&. +.RE +.PP +\fB\-\-property=\fR, \fB\-p\fR +.RS 4 +When showing unit/job/manager properties, limit display to certain properties as specified as argument\&. If not specified all set properties are shown\&. The argument should be a property name, such as +MainPID\&. If specified more than once all properties with the specified names are shown\&. +.RE +.PP +\fB\-\-all\fR, \fB\-a\fR +.RS 4 +When listing units, show all units, regardless of their state, including inactive units\&. When showing unit/job/manager properties, show all properties regardless whether they are set or not\&. +.RE +.PP +\fB\-\-failed\fR +.RS 4 +When listing units, show only failed units\&. Do not confuse with +\fB\-\-fail\fR\&. +.RE +.PP +\fB\-\-full\fR +.RS 4 +Do not ellipsize unit names and truncate unit descriptions in the output of +\fBlist\-units\fR +and +\fBlist\-jobs\fR\&. +.RE +.PP +\fB\-\-fail\fR +.RS 4 +If the requested operation conflicts with a pending unfinished job, fail the command\&. If this is not specified the requested operation will replace the pending job, if necessary\&. Do not confuse with +\fB\-\-failed\fR\&. +.RE +.PP +\fB\-\-ignore\-dependencies\fR +.RS 4 +When enqueuing a new job ignore all its dependencies and execute it immediately\&. If passed no required units of the unit passed will be pulled in, and no ordering dependencies will be honoured\&. This is mostly a debugging and rescue tool for the administrator and should not be used by applications\&. +.RE +.PP +\fB\-\-quiet\fR, \fB\-q\fR +.RS 4 +Suppress output to STDOUT in +\fBsnapshot\fR, +\fBis\-active\fR, +\fBenable\fR +and +\fBdisable\fR\&. +.RE +.PP +\fB\-\-no\-block\fR +.RS 4 +Do not synchronously wait for the requested operation to finish\&. If this is not specified the job will be verified, enqueued and +\fBsystemctl\fR +will wait until it is completed\&. By passing this argument it is only verified and enqueued\&. +.RE +.PP +\fB\-\-no\-legend\fR +.RS 4 +Do not print a legend, i\&.e\&. the column headers and the footer with hints\&. +.RE +.PP +\fB\-\-no\-pager\fR +.RS 4 +Do not pipe output into a pager\&. +.RE +.PP +\fB\-\-system\fR +.RS 4 +Talk to the systemd system manager\&. (Default) +.RE +.PP +\fB\-\-user\fR +.RS 4 +Talk to the systemd manager of the calling user\&. +.RE +.PP +\fB\-\-order\fR, \fB\-\-require\fR +.RS 4 +When used in conjunction with the +\fBdot\fR +command (see below), selects which dependencies are shown in the dependency graph\&. If +\fB\-\-order\fR +is passed only dependencies of type +\fIAfter=\fR +or +\fIBefore=\fR +are shown\&. If +\fB\-\-require\fR +is passed only dependencies of type +\fIRequires=\fR, +\fIRequiresOverridable=\fR, +\fIRequisite=\fR, +\fIRequisiteOverridable=\fR, +\fIWants=\fR +and +\fIConflicts=\fR +are shown\&. If neither is passed, shows dependencies of all these types\&. +.RE +.PP +\fB\-\-no\-wall\fR +.RS 4 +Don\*(Aqt send wall message before halt, power\-off, reboot\&. +.RE +.PP +\fB\-\-global\fR +.RS 4 +When used with +\fBenable\fR +and +\fBdisable\fR, operate on the global user configuration directory, thus enabling or disabling a unit file globally for all future logins of all users\&. +.RE +.PP +\fB\-\-no\-reload\fR +.RS 4 +When used with +\fBenable\fR +and +\fBdisable\fR, do not implicitly reload daemon configuration after executing the changes\&. +.RE +.PP +\fB\-\-no\-ask\-password\fR +.RS 4 +When used with +\fBstart\fR +and related commands, disables asking for passwords\&. Background services may require input of a password or passphrase string, for example to unlock system hard disks or cryptographic certificates\&. Unless this option is specified and the command is invoked from a terminal +\fBsystemctl\fR +will query the user on the terminal for the necessary secrets\&. Use this option to switch this behavior off\&. In this case the password must be supplied by some other means (for example graphical password agents) or the service might fail\&. +.RE +.PP +\fB\-\-kill\-who=\fR +.RS 4 +When used with +\fBkill\fR, choose which processes to kill\&. Must be one of +\fBmain\fR, +\fBcontrol\fR +or +\fBall\fR +to select whether to kill only the main process of the unit, the control process or all processes of the unit\&. If omitted defaults to +\fBall\fR\&. +.RE +.PP +\fB\-\-signal=\fR, \fB\-s\fR +.RS 4 +When used with +\fBkill\fR, choose which signal to send to selected processes\&. Must be one of the well known signal specifiers such as SIGTERM, SIGINT or SIGSTOP\&. If omitted defaults to +\fBSIGTERM\fR\&. +.RE +.PP +\fB\-\-force\fR, \fB\-f\fR +.RS 4 +When used with +\fBenable\fR, override any existing conflicting symlinks\&. +When used with +\fBhalt\fR, +\fBpoweroff\fR, +\fBreboot\fR +or +\fBkexec\fR +execute selected operation without shutting down all units\&. However, all processes will be killed forcibly and all file systems are unmounted or remounted read\-only\&. This is hence a drastic but relatively safe option to request an immediate reboot\&. +.RE +.PP +\fB\-\-root=\fR +.RS 4 +When used with +\fBenable\fR/\fBdisable\fR/\fBis\-enabled\fR +(and related commands), use alternative root path when looking for unit files\&. +.RE +.PP +\fB\-\-runtime\fR +.RS 4 +When used with +\fBenable\fR/\fBdisable\fR/\fBis\-enabled\fR +(and related commands), make changes only temporarily, so that they are dropped on the next reboot\&. This will have the effect that changes are not made in subdirectories of +/etc +but in +/run, with identical immediate effects, however, since the latter is lost on reboot, the changes are lost too\&. +.RE +.PP +\fB\-H\fR, \fB\-\-host\fR +.RS 4 +Execute operation remotely\&. Specify a hostname, or username and hostname separated by @, to connect to\&. This will use SSH to talk to the remote systemd instance\&. +.RE +.PP +\fB\-P\fR, \fB\-\-privileged\fR +.RS 4 +Acquire privileges via PolicyKit before executing the operation\&. +.RE +.PP +The following commands are understood: +.PP +\fBlist\-units\fR +.RS 4 +List known units\&. +.RE +.PP +\fBstart [NAME\&.\&.\&.]\fR +.RS 4 +Start (activate) one or more units specified on the command line\&. +.RE +.PP +\fBstop [NAME\&.\&.\&.]\fR +.RS 4 +Stop (deactivate) one or more units specified on the command line\&. +.RE +.PP +\fBreload [NAME\&.\&.\&.]\fR +.RS 4 +Asks all units listed on the command line to reload their configuration\&. Note that this will reload the service\-specific configuration, not the unit configuration file of systemd\&. If you want systemd to reload the configuration file of a unit use the +\fBdaemon\-reload\fR +command\&. In other words: for the example case of Apache, this will reload Apache\*(Aqs +httpd\&.conf +in the web server, not the +apache\&.service +systemd unit file\&. +.sp +This command should not be confused with the +\fBdaemon\-reload\fR +or +\fBload\fR +commands\&. +.RE +.PP +\fBrestart [NAME\&.\&.\&.]\fR +.RS 4 +Restart one or more units specified on the command line\&. If the units are not running yet they will be started\&. +.RE +.PP +\fBtry\-restart [NAME\&.\&.\&.]\fR +.RS 4 +Restart one or more units specified on the command line if the units are running\&. Do nothing if units are not running\&. Note that for compatibility with Red Hat init scripts +\fBcondrestart\fR +is equivalent to this command\&. +.RE +.PP +\fBreload\-or\-restart [NAME\&.\&.\&.]\fR +.RS 4 +Reload one or more units if they support it\&. If not, restart them instead\&. If the units are not running yet they will be started\&. +.RE +.PP +\fBreload\-or\-try\-restart [NAME\&.\&.\&.]\fR +.RS 4 +Reload one or more units if they support it\&. If not, restart them instead\&. Do nothing if the units are not running\&. Note that for compatibility with SysV init scripts +\fBforce\-reload\fR +is equivalent to this command\&. +.RE +.PP +\fBisolate [NAME]\fR +.RS 4 +Start the unit specified on the command line and its dependencies and stop all others\&. +.sp +This is similar to changing the runlevel in a traditional init system\&. The +\fBisolate\fR +command will immediately stop processes that are not enabled in the new unit, possibly including the graphical environment or terminal you are currently using\&. +.sp +Note that this works only on units where +\fBAllowIsolate=\fR +is enabled\&. See +\fBsystemd.unit\fR(5) +for details\&. +.RE +.PP +\fBkill [NAME\&.\&.\&.]\fR +.RS 4 +Send a signal to one or more processes of the unit\&. Use +\fB\-\-kill\-who=\fR +to select which process to kill\&. Use +\fB\-\-kill\-mode=\fR +to select the kill mode and +\fB\-\-signal=\fR +to select the signal to send\&. +.RE +.PP +\fBis\-active [NAME\&.\&.\&.]\fR +.RS 4 +Check whether any of the specified units are active (i\&.e\&. running)\&. Returns an exit code 0 if at least one is active, non\-zero otherwise\&. Unless +\fB\-\-quiet\fR +is specified this will also print the current unit state to STDOUT\&. +.RE +.PP +\fBstatus [NAME\&.\&.\&.|PID\&.\&.\&.]\fR +.RS 4 +Show terse runtime status information about one or more units\&. This function is intended to generate human\-readable output\&. If you are looking for computer\-parsable output, use +\fBshow\fR +instead\&. If a PID is passed information about the unit the process of the PID belongs to is shown\&. +.RE +.PP +\fBshow [NAME\&.\&.\&.|JOB\&.\&.\&.]\fR +.RS 4 +Show properties of one or more units, jobs or the manager itself\&. If no argument is specified properties of the manager will be shown\&. If a unit name is specified properties of the unit is shown, and if a job id is specified properties of the job is shown\&. By default, empty properties are suppressed\&. Use +\fB\-\-all\fR +to show those too\&. To select specific properties to show use +\fB\-\-property=\fR\&. This command is intended to be used whenever computer\-parsable output is required\&. Use +\fBstatus\fR +if you are looking for formatted human\-readable output\&. +.RE +.PP +\fBreset\-failed [NAME\&.\&.\&.]\fR +.RS 4 +Reset the \*(Aqfailed\*(Aq state of the specified units, or if no unit name is passed of all units\&. When a unit fails in some way (i\&.e\&. process exiting with non\-zero error code, terminating abnormally or timing out) it will automatically enter the \*(Aqfailed\*(Aq state and its exit code and status is recorded for introspection by the administrator until the service is restarted or reset with this command\&. +.RE +.PP +\fBlist\-unit\-files\fR +.RS 4 +List installed unit files\&. +.RE +.PP +\fBenable [NAME\&.\&.\&.]\fR +.RS 4 +Enable one or more unit files, as specified on the command line\&. This will create a number of symlinks as encoded in the +[Install] +sections of the unit files\&. After the symlinks have been created the systemd configuration is reloaded (in a way that is equivalent to +\fBdaemon\-reload\fR) to ensure the changes are taken into account immediately\&. Note that this does not have the effect that any of the units enabled are also started at the same time\&. If this is desired a separate +\fBstart\fR +command must be invoked for the unit\&. +.sp +This command will print the actions executed\&. This output may be suppressed by passing +\fB\-\-quiet\fR\&. +.sp +Note that this operation creates only the suggested symlinks for the units\&. While this command is the recommended way to manipulate the unit configuration directory, the administrator is free to make additional changes manually, by placing or removing symlinks in the directory\&. This is particularly useful to create configurations that deviate from the suggested default installation\&. In this case the administrator must make sure to invoke +\fBdaemon\-reload\fR +manually as necessary, to ensure his changes are taken into account\&. +.sp +Enabling units should not be confused with starting (activating) units, as done by the +\fBstart\fR +command\&. Enabling and starting units is orthogonal: units may be enabled without being started and started without being enabled\&. Enabling simply hooks the unit into various suggested places (for example, so that the unit is automatically started on boot or when a particular kind of hardware is plugged in)\&. Starting actually spawns the daemon process (in case of service units), or binds the socket (in case of socket units), and so on\&. +.sp +Depending on whether +\fB\-\-system\fR, +\fB\-\-user\fR +or +\fB\-\-global\fR +is specified this enables the unit for the system, for the calling user only or for all future logins of all users\&. Note that in the latter case no systemd daemon configuration is reloaded\&. +.RE +.PP +\fBdisable [NAME\&.\&.\&.]\fR +.RS 4 +Disables one or more units\&. This removes all symlinks to the specified unit files from the unit configuration directory, and hence undoes the changes made by +\fBenable\fR\&. Note however that this removes all symlinks to the unit files (i\&.e\&. including manual additions), not just those actually created by +\fBenable\fR\&. This call implicitly reloads the systemd daemon configuration after completing the disabling of the units\&. Note that this command does not implicitly stop the units that is being disabled\&. If this is desired an additional +\fBstop\fRcommand should be executed afterwards\&. +.sp +This command will print the actions executed\&. This output may be suppressed by passing +\fB\-\-quiet\fR\&. +.PP +This command honors +\fB\-\-system\fR, +\fB\-\-user\fR, +\fB\-\-global\fR +in a similar way as +\fBenable\fR\&. +.RE +.PP +\fBis\-enabled [NAME\&.\&.\&.]\fR +.RS 4 +Checks whether any of the specified unit files is enabled (as with +\fBenable\fR)\&. Returns an exit code of 0 if at least one is enabled, non\-zero otherwise\&. Prints the current enable status\&. To suppress this output use +\fB\-\-quiet\fR\&. +.RE +.PP +\fBreenable [NAME\&.\&.\&.]\fR +.RS 4 +Reenable one or more unit files, as specified on the command line\&. This is a combination of +\fBdisable\fR +and +\fBenable\fR +and is useful to reset the symlinks a unit is enabled with to the defaults configured in the +[Install] +section of the unit file\&. +.RE +.PP +\fBpreset [NAME\&.\&.\&.]\fR +.RS 4 +Reset one or more unit files, as specified on the command line, to the defaults configured in a preset file\&. This has the same effect as +\fBdisable\fR +or +\fBenable\fR, depending how the unit is listed in the preset files\&. +.RE +.PP +\fBmask [NAME\&.\&.\&.]\fR +.RS 4 +Mask one or more unit files, as specified on the command line\&. This will link these units to +/dev/null, making it impossible to start them\&. This is a stronger version of +\fBdisable\fR, since it prohibits all kinds of activation of the unit, including manual activation\&. Use this option with care\&. +.RE +.PP +\fBunmask [NAME\&.\&.\&.]\fR +.RS 4 +Unmask one or more unit files, as specified on the command line\&. This will undo the effect of +\fBmask\fR\&. +.RE +.PP +\fBlink [NAME\&.\&.\&.]\fR +.RS 4 +Link a unit file that is not in the unit file search paths into the unit file search path\&. This requires an absolute path to a unit file\&. The effect of this can be undone with +\fBdisable\fR\&. The effect of this command is that a unit file is available for +\fBstart\fR +and other commands although it isn\*(Aqt installed directly in the unit search path\&. +.RE +.PP +\fBload [NAME\&.\&.\&.]\fR +.RS 4 +Load one or more units specified on the command line\&. This will simply load their configuration from disk, but not start them\&. To start them you need to use the +\fBstart\fR +command which will implicitly load a unit that has not been loaded yet\&. Note that systemd garbage collects loaded units that are not active or referenced by an active unit\&. This means that units loaded this way will usually not stay loaded for long\&. Also note that this command cannot be used to reload unit configuration\&. Use the +\fBdaemon\-reload\fR +command for that\&. All in all, this command is of little use except for debugging\&. +.sp +This command should not be confused with the +\fBdaemon\-reload\fR +or +\fBreload\fR +commands\&. +.RE +.PP +\fBlist\-jobs\fR +.RS 4 +List jobs that are in progress\&. +.RE +.PP +\fBcancel [JOB\&.\&.\&.]\fR +.RS 4 +Cancel one or more jobs specified on the command line by their numeric job IDs\&. If no job id is specified, cancel all pending jobs\&. +.RE +.PP +\fBdump\fR +.RS 4 +Dump server status\&. This will output a (usually very long) human readable manager status dump\&. Its format is subject to change without notice and should not be parsed by applications\&. +.RE +.PP +\fBdot\fR +.RS 4 +Generate textual dependency graph description in dot format for further processing with the GraphViz +\fBdot\fR(1) +tool\&. Use a command line like +\fBsystemctl dot | dot \-Tsvg > systemd\&.svg\fR +to generate a graphical dependency tree\&. Unless +\fB\-\-order\fR +or +\fB\-\-require\fR +is passed the generated graph will show both ordering and requirement dependencies\&. +.RE +.PP +\fBsnapshot [NAME]\fR +.RS 4 +Create a snapshot\&. If a snapshot name is specified, the new snapshot will be named after it\&. If none is specified an automatic snapshot name is generated\&. In either case, the snapshot name used is printed to STDOUT, unless +\fB\-\-quiet\fR +is specified\&. +.sp +A snapshot refers to a saved state of the systemd manager\&. It is implemented itself as a unit that is generated dynamically with this command and has dependencies on all units active at the time\&. At a later time the user may return to this state by using the +\fBisolate\fR +command on the snapshot unit\&. +.PP +Snapshots are only useful for saving and restoring which units are running or are stopped, they do not save/restore any other state\&. Snapshots are dynamic and lost on reboot\&. +.RE +.PP +\fBdelete [NAME\&.\&.\&.]\fR +.RS 4 +Remove a snapshot previously created with +\fBsnapshot\fR\&. +.RE +.PP +\fBdaemon\-reload\fR +.RS 4 +Reload systemd manager configuration\&. This will reload all unit files and recreate the entire dependency tree\&. While the daemon is reloaded, all sockets systemd listens on on behalf of user configuration will stay accessible\&. +.sp +This command should not be confused with the +\fBload\fR +or +\fBreload\fR +commands\&. +.RE +.PP +\fBdaemon\-reexec\fR +.RS 4 +Reexecute the systemd manager\&. This will serialize the manager state, reexecute the process and deserialize the state again\&. This command is of little use except for debugging and package upgrades\&. Sometimes it might be helpful as a heavy\-weight +\fBdaemon\-reload\fR\&. While the daemon is reexecuted all sockets systemd listens on on behalf of user configuration will stay accessible\&. +.RE +.PP +\fBshow\-environment\fR +.RS 4 +Dump the systemd manager environment block\&. The environment block will be dumped in straight\-forward form suitable for sourcing into a shell script\&. This environment block will be passed to all processes the manager spawns\&. +.RE +.PP +\fBset\-environment [NAME=VALUE\&.\&.\&.]\fR +.RS 4 +Set one or more systemd manager environment variables, as specified on the command line\&. +.RE +.PP +\fBunset\-environment [NAME\&.\&.\&.]\fR +.RS 4 +Unset one or more systemd manager environment variables\&. If only a variable name is specified it will be removed regardless of its value\&. If a variable and a value are specified the variable is only removed if it has the specified value\&. +.RE +.PP +\fBdefault\fR +.RS 4 +Enter default mode\&. This is mostly equivalent to +\fBstart default\&.target\fR\&. +.RE +.PP +\fBrescue\fR +.RS 4 +Enter rescue mode\&. This is mostly equivalent to +\fBisolate rescue\&.target\fR +but also prints a wall message to all users\&. +.RE +.PP +\fBemergency\fR +.RS 4 +Enter emergency mode\&. This is mostly equivalent to +\fBisolate emergency\&.target\fR +but also prints a wall message to all users\&. +.RE +.PP +\fBhalt\fR +.RS 4 +Shut down and halt the system\&. This is mostly equivalent to +\fBstart halt\&.target\fR +but also prints a wall message to all users\&. If combined with +\fB\-\-force\fR +shutdown of all running services is skipped, however all processes are killed and all file systems are unmounted or mounted read\-only, immediately followed by the system halt\&. +.RE +.PP +\fBpoweroff\fR +.RS 4 +Shut down and power\-off the system\&. This is mostly equivalent to +\fBstart poweroff\&.target\fR +but also prints a wall message to all users\&. If combined with +\fB\-\-force\fR +shutdown of all running services is skipped, however all processes are killed and all file systems are unmounted or mounted read\-only, immediately followed by the powering off\&. +.RE +.PP +\fBreboot\fR +.RS 4 +Shut down and reboot the system\&. This is mostly equivalent to +\fBstart reboot\&.target\fR +but also prints a wall message to all users\&. If combined with +\fB\-\-force\fR +shutdown of all running services is skipped, however all processes are killed and all file systems are unmounted or mounted read\-only, immediately followed by the reboot\&. +.RE +.PP +\fBkexec\fR +.RS 4 +Shut down and reboot the system via kexec\&. This is mostly equivalent to +\fBstart kexec\&.target\fR +but also prints a wall message to all users\&. If combined with +\fB\-\-force\fR +shutdown of all running services is skipped, however all processes are killed and all file systems are unmounted or mounted read\-only, immediately followed by the reboot\&. +.RE +.PP +\fBexit\fR +.RS 4 +Ask the systemd manager to quit\&. This is only supported for user service managers (i\&.e\&. in conjunction with the +\fB\-\-user\fR +option) and will fail otherwise\&. +.RE +.SH "EXIT STATUS" +.PP +On success 0 is returned, a non\-zero failure code otherwise\&. +.SH "ENVIRONMENT" +.PP +\fI$SYSTEMD_PAGER\fR +.RS 4 +Pager to use when +\fB\-\-no\-pager\fR +is not given; overrides +\fI$PAGER\fR\&. Setting this to an empty string or the value +cat +is equivalent to passing +\fB\-\-no\-pager\fR\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemadm\fR(1), +\fBsystemd-loginctl\fR(1), +\fBsystemd.unit\fR(5), +\fBsystemd.special\fR(7), +\fBwall\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemctl.xml b/man/systemctl.xml new file mode 100644 index 0000000..5adee45 --- /dev/null +++ b/man/systemctl.xml @@ -0,0 +1,1128 @@ + + + + + + + + + systemctl + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemctl + 1 + + + + systemctl + Control the systemd system and service manager + + + + + systemctl OPTIONS COMMAND NAME + + + + + Description + + systemctl may be used to + introspect and control the state of the + systemd1 + system and service manager. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + + When listing units, + limit display to certain unit + types. If not specified units of all + types will be shown. The argument + should be a unit type name such as + , + and + similar. + + + + + + + When showing + unit/job/manager properties, limit + display to certain properties as + specified as argument. If not + specified all set properties are + shown. The argument should be a + property name, such as + MainPID. If + specified more than once all + properties with the specified names + are shown. + + + + + + + When listing units, + show all units, regardless of their + state, including inactive units. When + showing unit/job/manager properties, + show all properties regardless whether + they are set or not. + + + + + + When listing units, + show only failed units. Do not confuse + with + . + + + + + + Do not ellipsize unit + names and truncate unit descriptions + in the output of + list-units and + list-jobs. + + + + + + If the requested + operation conflicts with a pending + unfinished job, fail the command. If + this is not specified the requested + operation will replace the pending job, + if necessary. Do not confuse + with + . + + + + + + When enqueuing a new + job ignore all its dependencies and + execute it immediately. If passed no + required units of the unit passed will + be pulled in, and no ordering + dependencies will be honoured. This is + mostly a debugging and rescue tool for + the administrator and should not be + used by + applications. + + + + + + + Suppress output to + STDOUT in + snapshot, + is-active, + enable and + disable. + + + + + + Do not synchronously wait for + the requested operation to finish. If this is + not specified the job will be verified, + enqueued and systemctl will + wait until it is completed. By passing this + argument it is only verified and + enqueued. + + + + + + Do not print a legend, i.e. + the column headers and the footer with hints. + + + + + + + Do not pipe output into a + pager. + + + + + + Talk to the systemd + system manager. (Default) + + + + + + Talk to the systemd + manager of the calling user. + + + + + + + When used in + conjunction with the + dot command (see + below), selects which dependencies are + shown in the dependency graph. If + is passed + only dependencies of type + After= or + Before= are + shown. If + is passed only dependencies of type + Requires=, + RequiresOverridable=, + Requisite=, + RequisiteOverridable=, + Wants= and + Conflicts= are + shown. If neither is passed, shows + dependencies of all these + types. + + + + + + Don't send wall + message before + halt, power-off, reboot. + + + + + + When used with + enable and + disable, operate on the + global user configuration + directory, thus enabling or disabling + a unit file globally for all future + logins of all users. + + + + + + When used with + enable and + disable, do not + implicitly reload daemon configuration + after executing the + changes. + + + + + + When used with + start and related + commands, disables asking for + passwords. Background services may + require input of a password or + passphrase string, for example to + unlock system hard disks or + cryptographic certificates. Unless + this option is specified and the + command is invoked from a terminal + systemctl will + query the user on the terminal for the + necessary secrets. Use this option to + switch this behavior off. In this + case the password must be supplied by + some other means (for example + graphical password agents) or the + service might fail. + + + + + + When used with + kill, choose which + processes to kill. Must be one of + , + or + to select whether + to kill only the main process of the + unit, the control process or all + processes of the unit. If omitted + defaults to + . + + + + + + + When used with + kill, choose which + signal to send to selected + processes. Must be one of the well + known signal specifiers such as + SIGTERM, SIGINT or SIGSTOP. If + omitted defaults to + . + + + + + + + When used with + enable, override any + existing conflicting + symlinks. + + When used with + halt, + poweroff, + reboot or + kexec execute + selected operation without shutting + down all units. However, all processes + will be killed forcibly and all file + systems are unmounted or remounted + read-only. This is hence a drastic but + relatively safe option to request an + immediate reboot. + + + + + + When used with + enable/disable/is-enabled (and + related commands), use alternative + root path when looking for unit + files. + + + + + + When used with + enable/disable/is-enabled (and related commands), make + changes only temporarily, so that they + are dropped on the next reboot. This + will have the effect that changes are + not made in subdirectories of + /etc but in + /run, with + identical immediate effects, however, + since the latter is lost on reboot, + the changes are lost + too. + + + + + + + Execute operation + remotely. Specify a hostname, or + username and hostname separated by @, + to connect to. This will use SSH to + talk to the remote systemd + instance. + + + + + + + Acquire privileges via + PolicyKit before executing the + operation. + + + + The following commands are understood: + + + + list-units + + List known units. + + + start [NAME...] + + Start (activate) one + or more units specified on the command + line. + + + stop [NAME...] + + Stop (deactivate) one + or more units specified on the command + line. + + + reload [NAME...] + + Asks all units listed + on the command line to reload their + configuration. Note that this will + reload the service-specific + configuration, not the unit + configuration file of systemd. If you + want systemd to reload the + configuration file of a unit use the + daemon-reload + command. In other words: for the + example case of Apache, this will + reload Apache's + httpd.conf in the + web server, not the + apache.service + systemd unit file. + + This command should not be + confused with the + daemon-reload or + load + commands. + + + + restart [NAME...] + + Restart one or more + units specified on the command + line. If the units are not running yet + they will be + started. + + + try-restart [NAME...] + + Restart one or more + units specified on the command + line if the units are running. Do + nothing if units are not running. + Note that for compatibility + with Red Hat init scripts + condrestart is + equivalent to this command. + + + reload-or-restart [NAME...] + + Reload one or more + units if they support it. If not, + restart them instead. If the units + are not running yet they will be + started. + + + reload-or-try-restart [NAME...] + + Reload one or more + units if they support it. If not, + restart them instead. Do nothing if + the units are not running. Note that + for compatibility with SysV init + scripts + force-reload is + equivalent to this + command. + + + isolate [NAME] + + Start the unit + specified on the command line and its + dependencies and stop all others. + + This is similar to changing the + runlevel in a traditional init system. The + isolate command will + immediately stop processes that are not + enabled in the new unit, possibly including + the graphical environment or terminal you + are currently using. + + Note that this works only on units + where is + enabled. See + systemd.unit5 + for details. + + + kill [NAME...] + + Send a signal to one + or more processes of the unit. Use + to select + which process to kill. Use + to + select the kill mode and + to select + the signal to send. + + + is-active [NAME...] + + Check whether any of + the specified units are active + (i.e. running). Returns an exit code + 0 if at least one is active, non-zero + otherwise. Unless + is specified + this will also print the current unit + state to STDOUT. + + + status [NAME...|PID...] + + Show terse runtime + status information about one or more + units. This function is intended to + generate human-readable output. If you + are looking for computer-parsable + output, use show + instead. If a PID is passed + information about the unit the process + of the PID belongs to is + shown. + + + show [NAME...|JOB...] + + Show properties of one + or more units, jobs or the manager + itself. If no argument is specified + properties of the manager will be + shown. If a unit name is specified + properties of the unit is shown, and + if a job id is specified properties of + the job is shown. By default, empty + properties are suppressed. Use + to show those + too. To select specific properties to + show use + . This + command is intended to be used + whenever computer-parsable output is + required. Use + status if you are + looking for formatted human-readable + output. + + + + reset-failed [NAME...] + + Reset the + 'failed' state of the + specified units, or if no unit name is + passed of all units. When a unit fails + in some way (i.e. process exiting with + non-zero error code, terminating + abnormally or timing out) it will + automatically enter the + 'failed' state and + its exit code and status is recorded + for introspection by the administrator + until the service is restarted or + reset with this + command. + + + + list-unit-files + + List installed unit files. + + + + + enable [NAME...] + + Enable one or more + unit files, as specified on the + command line. This will create a + number of symlinks as encoded in the + [Install] sections + of the unit files. After the symlinks + have been created the systemd + configuration is reloaded (in a way + that is equivalent to + daemon-reload) to + ensure the changes are taken into + account immediately. Note that this + does not have the effect that any of + the units enabled are also started at + the same time. If this is desired a + separate start + command must be invoked for the + unit. + + This command will + print the actions executed. This + output may be suppressed by passing + . + + Note that this operation creates + only the suggested symlinks for the + units. While this command is the + recommended way to manipulate the unit + configuration directory, the + administrator is free to make + additional changes manually, by + placing or removing symlinks in the + directory. This is particularly useful + to create configurations that deviate + from the suggested default + installation. In this case the + administrator must make sure to invoke + daemon-reload + manually as necessary, to ensure his + changes are taken into account. + + Enabling units should not be + confused with starting (activating) + units, as done by the + start + command. Enabling and starting units + is orthogonal: units may be enabled + without being started and started + without being enabled. Enabling simply + hooks the unit into various suggested + places (for example, so that the unit + is automatically started on boot or + when a particular kind of hardware is + plugged in). Starting actually spawns + the daemon process (in case of service + units), or binds the socket (in case + of socket units), and so + on. + + Depending on whether + , + or + is specified + this enables the unit for the system, + for the calling user only + or for all future logins of all + users. Note that in the latter case no + systemd daemon configuration is + reloaded. + + + + + disable [NAME...] + + Disables one or more + units. This removes all symlinks to + the specified unit files from the unit + configuration directory, and hence + undoes the changes made by + enable. Note + however that this removes + all symlinks to the unit files + (i.e. including manual additions), not + just those actually created by + enable. This call + implicitly reloads the systemd daemon + configuration after completing the + disabling of the units. Note that this + command does not implicitly stop the + units that is being disabled. If this + is desired an additional + stopcommand should + be executed afterwards. + + This command will print the + actions executed. This output may be + suppressed by passing + . + + + This command honors + , + , + in a similar + way as + enable. + + + + is-enabled [NAME...] + + Checks whether any of + the specified unit files is enabled + (as with + enable). Returns an + exit code of 0 if at least one is + enabled, non-zero otherwise. Prints + the current enable status. To suppress + this output use + . + + + + reenable [NAME...] + + Reenable one or more + unit files, as specified on the + command line. This is a combination of + disable and + enable and is + useful to reset the symlinks a unit is + enabled with to the defaults + configured in the + [Install] section + of the unit file. + + + + + preset [NAME...] + + Reset one or more unit + files, as specified on the command + line, to the defaults configured in a + preset file. This has the same effect + as disable or + enable, depending + how the unit is listed in the preset + files. + + + + + mask [NAME...] + + Mask one or more unit + files, as specified on the command + line. This will link these units to + /dev/null, making + it impossible to start them. This is a stronger version + of disable, since + it prohibits all kinds of activation + of the unit, including manual + activation. Use this option with + care. + + + + + unmask [NAME...] + + Unmask one or more + unit files, as specified on the + command line. This will undo the + effect of + mask. + + + + + link [NAME...] + + Link a unit file that + is not in the unit file search paths + into the unit file search path. This + requires an absolute path to a unit + file. The effect of this can be undone + with disable. The + effect of this command is that a unit + file is available for + start and other + commands although it isn't installed + directly in the unit search + path. + + + + + load [NAME...] + + Load one or more units + specified on the command line. This + will simply load their configuration + from disk, but not start them. To + start them you need to use the + start command which + will implicitly load a unit that has + not been loaded yet. Note that systemd + garbage collects loaded units that are + not active or referenced by an active + unit. This means that units loaded + this way will usually not stay loaded + for long. Also note that this command + cannot be used to reload unit + configuration. Use the + daemon-reload + command for that. All in all, this + command is of little use except for + debugging. + This command should not be + confused with the + daemon-reload or + reload + commands. + + + list-jobs + + List jobs that are in progress. + + + cancel [JOB...] + + Cancel one or more + jobs specified on the command line by + their numeric job + IDs. If no job id is specified, cancel all pending jobs. + + + dump + + Dump server + status. This will output a (usually + very long) human readable manager + status dump. Its format is subject to + change without notice and should not + be parsed by + applications. + + + dot + + Generate textual + dependency graph description in dot + format for further processing with the + GraphViz + dot1 + tool. Use a command line like + systemctl dot | dot -Tsvg > + systemd.svg to generate a + graphical dependency tree. Unless + or + is passed + the generated graph will show both + ordering and requirement + dependencies. + + + snapshot [NAME] + + Create a snapshot. If + a snapshot name is specified, the new + snapshot will be named after it. If + none is specified an automatic + snapshot name is generated. In either + case, the snapshot name used is + printed to STDOUT, unless + is + specified. + + A snapshot refers to a saved + state of the systemd manager. It is + implemented itself as a unit that is + generated dynamically with this + command and has dependencies on all + units active at the time. At a later + time the user may return to this state + by using the + isolate command on + the snapshot unit. + + Snapshots are only useful for + saving and restoring which units are + running or are stopped, they do not + save/restore any other + state. Snapshots are dynamic and lost + on reboot. + + + delete [NAME...] + + Remove a snapshot + previously created with + snapshot. + + + daemon-reload + + Reload systemd manager + configuration. This will reload all + unit files and recreate the entire + dependency tree. While the daemon is + reloaded, all sockets systemd listens + on on behalf of user configuration will + stay accessible. This + command should not be confused with + the load or + reload + commands. + + + daemon-reexec + + Reexecute the systemd + manager. This will serialize the + manager state, reexecute the process + and deserialize the state again. This + command is of little use except for + debugging and package + upgrades. Sometimes it might be + helpful as a heavy-weight + daemon-reload. While + the daemon is reexecuted all sockets + systemd listens on on behalf of user + configuration will stay + accessible. + + + show-environment + + Dump the systemd + manager environment block. The + environment block will be dumped in + straight-forward form suitable for + sourcing into a shell script. This + environment block will be passed to + all processes the manager + spawns. + + + set-environment [NAME=VALUE...] + + Set one or more + systemd manager environment variables, + as specified on the command + line. + + + unset-environment [NAME...] + + Unset one or more + systemd manager environment + variables. If only a variable name is + specified it will be removed + regardless of its value. If a variable + and a value are specified the variable + is only removed if it has the + specified value. + + + default + + Enter default + mode. This is mostly equivalent to + start + default.target. + + + rescue + + Enter rescue + mode. This is mostly equivalent to + isolate + rescue.target but also + prints a wall message to all + users. + + + emergency + + Enter emergency + mode. This is mostly equivalent to + isolate + emergency.target but also + prints a wall message to all + users. + + + halt + + Shut down and halt the + system. This is mostly equivalent to + start halt.target + but also prints a wall message to all + users. If + combined with + shutdown of all running services is + skipped, however all processes are killed + and all file systems are unmounted or + mounted read-only, immediately + followed by the + system halt. + + + poweroff + + Shut down and + power-off the system. This is mostly + equivalent to start + poweroff.target but also + prints a wall message to all + users. If + combined with + shutdown of all running services is + skipped, however all processes are killed + and all file systems are unmounted or + mounted read-only, immediately + followed by the + powering off. + + + reboot + + Shut down and + reboot the system. This is mostly + equivalent to start + reboot.target but also + prints a wall message to all + users. If + combined with + shutdown of all running services is + skipped, however all processes are killed + and all file systems are unmounted or + mounted read-only, immediately + followed by the + reboot. + + + kexec + + Shut down and reboot + the system via kexec. This is mostly + equivalent to start + kexec.target but also prints + a wall message to all users. If + combined with + shutdown of all running services is + skipped, however all processes are killed + and all file systems are unmounted or + mounted read-only, immediately + followed by the + reboot. + + + exit + + Ask the systemd + manager to quit. This is only + supported for user service managers + (i.e. in conjunction with the + option) and + will fail otherwise. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Environment + + + + $SYSTEMD_PAGER + Pager to use when + is not given; + overrides $PAGER. Setting + this to an empty string or the value + cat is equivalent to passing + . + + + + + + See Also + + systemd1, + systemadm1, + systemd-loginctl1, + systemd.unit5, + systemd.special7, + wall1 + + + + diff --git a/man/systemd-ask-password.1 b/man/systemd-ask-password.1 new file mode 100644 index 0000000..69d936e --- /dev/null +++ b/man/systemd-ask-password.1 @@ -0,0 +1,116 @@ +'\" t +.\" Title: systemd-ask-password +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd-ask-password +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\-ASK\-PASSWO" "1" "02/15/2012" "systemd" "systemd-ask-password" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd-ask-password \- Query the user for a system password +.SH "SYNOPSIS" +.HP \w'\fBsystemd\-ask\-password\ \fR\fB[OPTIONS...]\fR\fB\ \fR\fB[MESSAGE]\fR\ 'u +\fBsystemd\-ask\-password \fR\fB[OPTIONS...]\fR\fB \fR\fB[MESSAGE]\fR +.SH "DESCRIPTION" +.PP +\fBsystemd\-ask\-password\fR +may be used to query a system password or passphrase from the user, using a question message specified on the command line\&. When run from a TTY it will query a password on the TTY and print it to STDOUT\&. When run with no TTY or with +\fB\-\-no\-tty\fR +it will query the password system\-wide and allow active users to respond via several agents\&. The latter is only available to privileged processes\&. +.PP +The purpose of this tool is to query system\-wide passwords \-\- that is passwords not attached to a specific user account\&. Examples include: unlocking encrypted hard disks when they are plugged in or at boot, entering an SSL certificate passphrase for web and VPN servers\&. +.PP +Existing agents are: a boot\-time password agent asking the user for passwords using Plymouth; a boot\-time password agent querying the user directly on the console; an agent requesting password input via a +\fBwall\fR(1) +message; an agent suitable for running in a GNOME session; a command line agent which can be started temporarily to process queued password requests; a TTY agent that is temporarily spawned during +\fBsystemctl\fR(1) +invocations\&. +.PP +Additional password agents may be implemented according to the +\m[blue]\fBsystemd Password Agent Specification\fR\m[]\&\s-2\u[1]\d\s+2\&. +.PP +If a password is queried on a tty the user may press TAB to hide the asterisks normally shown for each character typed\&. Pressing Backspace as first key achieves the same effect\&. +.SH "OPTIONS" +.PP +The following options are understood: +.PP +\fB\-\-h\fR, \fB\-\-help\fR +.RS 4 +Prints a short help text and exits\&. +.RE +.PP +\fB\-\-icon=\fR +.RS 4 +Specify an icon name alongside the password query, which may be used in all agents supporting graphical display\&. The icon name should follow the +\m[blue]\fBXDG Icon Naming Specification\fR\m[]\&\s-2\u[2]\d\s+2\&. +.RE +.PP +\fB\-\-timeout=\fR +.RS 4 +Specify the query timeout in seconds\&. Defaults to 90s\&. +.RE +.PP +\fB\-\-no\-tty\fR +.RS 4 +Never ask for password on current TTY even if one is available\&. Always use agent system\&. +.RE +.PP +\fB\-\-accept\-cached\fR +.RS 4 +If passed accept cached passwords, i\&.e\&. passwords previously typed in\&. +.RE +.PP +\fB\-\-multiple\fR +.RS 4 +When used in conjunction with +\fB\-\-accept\-cached\fR +accept multiple passwords\&. This will output one password per line\&. +.RE +.SH "EXIT STATUS" +.PP +On success 0 is returned, a non\-zero failure code otherwise\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(1), +\fBplymouth\fR(8), +\fBwall\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE +.SH "NOTES" +.IP " 1." 4 +systemd Password Agent Specification +.RS 4 +\%http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents +.RE +.IP " 2." 4 +XDG Icon Naming Specification +.RS 4 +\%http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html +.RE diff --git a/man/systemd-ask-password.xml b/man/systemd-ask-password.xml new file mode 100644 index 0000000..c607b1a --- /dev/null +++ b/man/systemd-ask-password.xml @@ -0,0 +1,183 @@ + + + + + + + + + systemd-ask-password + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-ask-password + 1 + + + + systemd-ask-password + Query the user for a system password + + + + + systemd-ask-password OPTIONS MESSAGE + + + + + Description + + systemd-ask-password may be + used to query a system password or passphrase from the + user, using a question message specified on the + command line. When run from a TTY it will query a + password on the TTY and print it to STDOUT. When run + with no TTY or with it will + query the password system-wide and allow active users + to respond via several agents. The latter is + only available to privileged processes. + + The purpose of this tool is to query system-wide + passwords -- that is passwords not attached to a + specific user account. Examples include: unlocking + encrypted hard disks when they are plugged in or at + boot, entering an SSL certificate passphrase for web + and VPN servers. + + Existing agents are: a boot-time password agent + asking the user for passwords using Plymouth; a + boot-time password agent querying the user directly on + the console; an agent requesting password input via a + wall1 + message; an agent suitable for running in a GNOME + session; a command line agent which can be started + temporarily to process queued password requests; a TTY + agent that is temporarily spawned during + systemctl1 + invocations. + + Additional password agents may be implemented + according to the systemd + Password Agent Specification. + + If a password is queried on a tty the user may + press TAB to hide the asterisks normally shown for + each character typed. Pressing Backspace as first key + achieves the same effect. + + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Specify an icon name + alongside the password query, which may + be used in all agents supporting + graphical display. The icon name + should follow the XDG + Icon Naming + Specification. + + + + + + Specify the query + timeout in seconds. Defaults to + 90s. + + + + + + Never ask for password + on current TTY even if one is + available. Always use agent + system. + + + + + + If passed accept + cached passwords, i.e. passwords + previously typed in. + + + + + + When used in + conjunction with + + accept multiple passwords. This will + output one password per + line. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + See Also + + systemd1, + systemctl1, + plymouth8, + wall1 + + + + diff --git a/man/systemd-cgls.1 b/man/systemd-cgls.1 new file mode 100644 index 0000000..45a071c --- /dev/null +++ b/man/systemd-cgls.1 @@ -0,0 +1,74 @@ +'\" t +.\" Title: systemd-cgls +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd-cgls +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\-CGLS" "1" "02/15/2012" "systemd" "systemd-cgls" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd-cgls \- Recursively show control group contents +.SH "SYNOPSIS" +.HP \w'\fBsystemd\-cgls\ \fR\fB[OPTIONS...]\fR\fB\ \fR\fB[CGROUP...]\fR\ 'u +\fBsystemd\-cgls \fR\fB[OPTIONS...]\fR\fB \fR\fB[CGROUP...]\fR +.SH "DESCRIPTION" +.PP +\fBsystemd\-cgls\fR +recursively shows the contents of the selected Linux control group hierarchy in a tree\&. If arguments are specified shows all member processes of the specified control groups plus all their subgroups and their members\&. The control groups may either be specified by their full file paths or are assumed in the systemd control group hierarchy\&. If no argument is specified and the current working directory is beneath the control group mount point +/sys/fs/cgroup +shows the contents of the control group the working directory refers to\&. Otherwise the full systemd control group hierarchy is shown\&. +.SH "OPTIONS" +.PP +The following options are understood: +.PP +\fB\-h\fR, \fB\-\-help\fR +.RS 4 +Prints a short help text and exits\&. +.RE +.PP +\fB\-\-no\-pager\fR +.RS 4 +Do not pipe output into a pager\&. +.RE +.PP +\fB\-k\fR +.RS 4 +Include kernel threads in output\&. +.RE +.SH "EXIT STATUS" +.PP +On success 0 is returned, a non\-zero failure code otherwise\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(1), +\fBsystemd-cgtop\fR(1), +\fBps\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd-cgls.xml b/man/systemd-cgls.xml new file mode 100644 index 0000000..1e53147 --- /dev/null +++ b/man/systemd-cgls.xml @@ -0,0 +1,123 @@ + + + + + + + + + systemd-cgls + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-cgls + 1 + + + + systemd-cgls + Recursively show control group contents + + + + + systemd-cgls OPTIONS CGROUP + + + + + Description + + systemd-cgls recursively + shows the contents of the selected Linux control group + hierarchy in a tree. If arguments are specified shows + all member processes of the specified control groups + plus all their subgroups and their members. The + control groups may either be specified by their full + file paths or are assumed in the systemd control group + hierarchy. If no argument is specified and the current + working directory is beneath the control group mount + point /sys/fs/cgroup shows the contents + of the control group the working directory refers + to. Otherwise the full systemd control group hierarchy + is shown. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Do not pipe output into a + pager. + + + + + + Include kernel + threads in output. + + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + See Also + + systemd1, + systemctl1, + systemd-cgtop1, + ps1 + + + + diff --git a/man/systemd-cgtop.1 b/man/systemd-cgtop.1 new file mode 100644 index 0000000..91ef1a2 --- /dev/null +++ b/man/systemd-cgtop.1 @@ -0,0 +1,169 @@ +'\" t +.\" Title: systemd-cgtop +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd-cgtop +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\-CGTOP" "1" "02/15/2012" "systemd" "systemd-cgtop" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd-cgtop \- Show top control groups by their resource usage +.SH "SYNOPSIS" +.HP \w'\fBsystemd\-cgtop\ \fR\fB[OPTIONS...]\fR\ 'u +\fBsystemd\-cgtop \fR\fB[OPTIONS...]\fR +.SH "DESCRIPTION" +.PP +\fBsystemd\-cgtop\fR +shows the top control groups of the local Linux control group hierarchy, ordered by their CPU, memory and disk I/O load\&. The display is refreshed in regular intervals (by default every 1s), similar in style to +\fBtop\fR(1)\&. +.PP +Resource usage is only accounted for control groups in the relevant hierarchy, i\&.e\&. CPU usage is only accounted for control groups in the +cpuacct +hierarchy, memory usage only for those in +memory +and disk I/O usage for those in +blkio\&. +\fBsystemd\fR(1) +by default places all services in their own control group in the +cpuacct +hierarchy, but not in +memory +nor +blkio\&. If resource monitoring for these resources is required it is recommended to add +blkio +and +memory +to the +\fIDefaultControllers=\fR +setting in +/etc/systemd/system\&.conf +(see +\fBsystemd.conf\fR(5) +for details)\&. Alternatively, it is possible to enable resource accounting individually for services, by making use of the +\fIControlGroup=\fR +option in the unit files (See +\fBsystemd.exec\fR(5) +for details)\&. +.PP +To emphasize this: unless +blkio +and +memory +are enabled for the services in question with either of the options suggested above no resource accounting will be available for system services and the data shown by +\fBsystemd\-cgtop\fR +will be incomplete\&. +.SH "OPTIONS" +.PP +The following options are understood: +.PP +\fB\-h\fR, \fB\-\-help\fR +.RS 4 +Prints a short help text and exits\&. +.RE +.PP +\fB\-p\fR +.RS 4 +Order by control group path name\&. +.RE +.PP +\fB\-t\fR +.RS 4 +Order by number of tasks in control group (i\&.e\&. threads and processes)\&. +.RE +.PP +\fB\-c\fR +.RS 4 +Order by CPU load\&. +.RE +.PP +\fB\-m\fR +.RS 4 +Order by memory usage\&. +.RE +.PP +\fB\-i\fR +.RS 4 +Order by disk I/O load\&. +.RE +.PP +\fB\-d\fR, \fB\-\-delay=\fR +.RS 4 +Specify refresh delay in seconds (or if one of +ms, +us, +min +is specified as unit in this time unit)\&. +.RE +.PP +\fB\-\-depth=\fR +.RS 4 +Maximum control group tree traversal depth\&. Specifies how deep +\fBsystemd\-cgtop\fR +shall traverse the control group hierarchies\&. If 0 is specified only the root group is monitored, for 1 only the first level of control groups is monitored, and so on\&. Defaults to 2\&. +.RE +.SH "KEYS" +.PP +\fBsystemd\-cgtop\fR +is an interactive tool and may be controlled via user input using the following keys: +.PP +h +.RS 4 +Shows a short help text\&. +.RE +.PP +SPACE +.RS 4 +Immediately refresh output\&. +.RE +.PP +q +.RS 4 +Terminate the program\&. +.RE +.PP +p, t, c, m, i +.RS 4 +Change ordering of control groups by path, number of tasks, CPU load, memory usage resp\&. IO load\&. +.RE +.PP ++, \- +.RS 4 +Increase, resp\&. decrease refresh delay\&. +.RE +.SH "EXIT STATUS" +.PP +On success 0 is returned, a non\-zero failure code otherwise\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(1), +\fBsystemd-cgls\fR(1), +\fBtop\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd-cgtop.xml b/man/systemd-cgtop.xml new file mode 100644 index 0000000..2d67ae5 --- /dev/null +++ b/man/systemd-cgtop.xml @@ -0,0 +1,246 @@ + + + + + + + + + systemd-cgtop + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-cgtop + 1 + + + + systemd-cgtop + Show top control groups by their resource usage + + + + + systemd-cgtop OPTIONS + + + + + Description + + systemd-cgtop shows the top + control groups of the local Linux control group + hierarchy, ordered by their CPU, memory and disk I/O load. The + display is refreshed in regular intervals (by default + every 1s), similar in style to + top1. + + Resource usage is only accounted for control + groups in the relevant hierarchy, i.e. CPU usage is + only accounted for control groups in the + cpuacct hierarchy, memory usage + only for those in memory and disk + I/O usage for those in + blkio. systemd1 + by default places all services in their own control + group in the cpuacct hierarchy, but + not in memory nor + blkio. If resource monitoring for + these resources is required it is recommended to add + blkio and memory + to the DefaultControllers= setting + in /etc/systemd/system.conf (see + systemd.conf5 + for details). Alternatively, it is possible to enable + resource accounting individually for services, by + making use of the ControlGroup= + option in the unit files (See + systemd.exec5 + for details). + + To emphasize this: unless + blkio and memory + are enabled for the services in question with either + of the options suggested above no resource accounting + will be available for system services and the data shown + by systemd-cgtop will be + incomplete. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Order by control group + path name. + + + + + + Order by number of + tasks in control + group (i.e. threads and processes). + + + + + + Order by CPU load. + + + + + + Order by memory usage. + + + + + + Order by disk I/O load. + + + + + + + Specify refresh delay + in seconds (or if one of + ms, + us, + min is specified as + unit in this time + unit). + + + + + + Maximum control group + tree traversal depth. Specifies how + deep systemd-cgtop + shall traverse the control group + hierarchies. If 0 is specified only + the root group is monitored, for 1 + only the first level of control groups + is monitored, and so on. Defaults to + 2. + + + + + + + + + Keys + + systemd-cgtop is an + interactive tool and may be controlled via user input + using the following keys: + + + + h + + Shows a short help text. + + + + SPACE + + Immediately refresh output. + + + + q + + Terminate the program. + + + + + p + t + c + m + i + + Change ordering of control groups + by path, number of tasks, CPU load, + memory usage resp. IO + load. + + + + + + - + + Increase, + resp. decrease refresh + delay. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + See Also + + systemd1, + systemctl1, + systemd-cgls1, + top1 + + + + diff --git a/man/systemd-loginctl.1 b/man/systemd-loginctl.1 new file mode 100644 index 0000000..4ca65ba --- /dev/null +++ b/man/systemd-loginctl.1 @@ -0,0 +1,253 @@ +'\" t +.\" Title: systemd-loginctl +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd-loginctl +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\-LOGINCTL" "1" "02/15/2012" "systemd" "systemd-loginctl" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd-loginctl \- Control the systemd login manager +.SH "SYNOPSIS" +.HP \w'\fBsystemd\-loginctl\ \fR\fB[OPTIONS...]\fR\fB\ \fR\fB{COMMAND}\fR\fB\ \fR\fB[NAME...]\fR\ 'u +\fBsystemd\-loginctl \fR\fB[OPTIONS...]\fR\fB \fR\fB{COMMAND}\fR\fB \fR\fB[NAME...]\fR +.SH "DESCRIPTION" +.PP +\fBsystemd\-loginctl\fR +may be used to introspect and control the state of the +\fBsystemd\fR(1) +login manager\&. +.SH "OPTIONS" +.PP +The following options are understood: +.PP +\fB\-\-help\fR, \fB\-h\fR +.RS 4 +Prints a short help text and exits\&. +.RE +.PP +\fB\-\-version\fR +.RS 4 +Prints a short version string and exits\&. +.RE +.PP +\fB\-\-property=\fR, \fB\-p\fR +.RS 4 +When showing session/user/ properties, limit display to certain properties as specified as argument\&. If not specified all set properties are shown\&. The argument should be a property name, such as +Sessions\&. If specified more than once all properties with the specified names are shown\&. +.RE +.PP +\fB\-\-all\fR, \fB\-a\fR +.RS 4 +When showing unit/job/manager properties, show all properties regardless whether they are set or not\&. +.RE +.PP +\fB\-\-no\-pager\fR +.RS 4 +Do not pipe output into a pager\&. +.RE +.PP +\fB\-\-kill\-who=\fR +.RS 4 +When used with +\fBkill\-session\fR, choose which processes to kill\&. Must be one of +\fBleader\fR, or +\fBall\fR +to select whether to kill only the leader process of the session or all processes of the session\&. If omitted defaults to +\fBall\fR\&. +.RE +.PP +\fB\-\-signal=\fR, \fB\-s\fR +.RS 4 +When used with +\fBkill\-session\fR +or +\fBkill\-user\fR, choose which signal to send to selected processes\&. Must be one of the well known signal specifiers such as SIGTERM, SIGINT or SIGSTOP\&. If omitted defaults to +\fBSIGTERM\fR\&. +.RE +.PP +\fB\-H\fR, \fB\-\-host\fR +.RS 4 +Execute operation remotely\&. Specify a hostname, or username and hostname separated by @, to connect to\&. This will use SSH to talk to the remote login manager instance\&. +.RE +.PP +\fB\-P\fR, \fB\-\-privileged\fR +.RS 4 +Acquire privileges via PolicyKit before executing the operation\&. +.RE +.PP +The following commands are understood: +.PP +\fBlist\-sessions\fR +.RS 4 +List current sessions\&. +.RE +.PP +\fBsession\-status [ID\&.\&.\&.]\fR +.RS 4 +Show terse runtime status information about one or more sessions\&. This function is intended to generate human\-readable output\&. If you are looking for computer\-parsable output, use +\fBshow\-session\fR +instead\&. +.RE +.PP +\fBshow\-session [ID\&.\&.\&.]\fR +.RS 4 +Show properties of one or more sessions or the manager itself\&. If no argument is specified properties of the manager will be shown\&. If a session ID is specified properties of the session is shown\&. By default, empty properties are suppressed\&. Use +\fB\-\-all\fR +to show those too\&. To select specific properties to show use +\fB\-\-property=\fR\&. This command is intended to be used whenever computer\-parsable output is required\&. Use +\fBsession\-status\fR +if you are looking for formatted human\-readable output\&. +.RE +.PP +\fBactivate [ID\&.\&.\&.]\fR +.RS 4 +Activate one or more sessions\&. This brings one or more sessions into the foreground, if another session is currently in the foreground on the respective seat\&. +.RE +.PP +\fBlock\-session [ID\&.\&.\&.]\fR, \fBunlock\-session [ID\&.\&.\&.]\fR +.RS 4 +Activates/deactivates the screen lock on one or more sessions, if the session supports it\&. +.RE +.PP +\fBterminate\-session [ID\&.\&.\&.]\fR +.RS 4 +Terminates a session\&. This kills all processes of the session and deallocates all resources attached to the session\&. +.RE +.PP +\fBkill\-session [ID\&.\&.\&.]\fR +.RS 4 +Send a signal to one or more processes of the session\&. Use +\fB\-\-kill\-who=\fR +to select which process to kill\&. Use +\fB\-\-signal=\fR +to select the signal to send\&. +.RE +.PP +\fBlist\-users\fR +.RS 4 +List currently logged in users\&. +.RE +.PP +\fBuser\-status [USER\&.\&.\&.]\fR +.RS 4 +Show terse runtime status information about one or more logged in users\&. This function is intended to generate human\-readable output\&. If you are looking for computer\-parsable output, use +\fBshow\-user\fR +instead\&. Users may be specified by their usernames or numeric user IDs\&. +.RE +.PP +\fBshow\-user [USER\&.\&.\&.]\fR +.RS 4 +Show properties of one or more users or the manager itself\&. If no argument is specified properties of the manager will be shown\&. If a user is specified properties of the user is shown\&. By default, empty properties are suppressed\&. Use +\fB\-\-all\fR +to show those too\&. To select specific properties to show use +\fB\-\-property=\fR\&. This command is intended to be used whenever computer\-parsable output is required\&. Use +\fBuser\-status\fR +if you are looking for formatted human\-readable output\&. +.RE +.PP +\fBenable\-linger [USER\&.\&.\&.]\fR, \fBdisable\-linger [USER\&.\&.\&.]\fR +.RS 4 +Enable/disable user lingering for one or more users\&. If enabled for a specific user a user manager is spawned for him/her at boot, and kept around after logouts\&. This allows users who aren\*(Aqt logged in to run long\-running services\&. +.RE +.PP +\fBterminate\-user [USER\&.\&.\&.]\fR +.RS 4 +Terminates all sessions of a user\&. This kills all processes of all sessions of the user and deallocates all runtime resources attached to the user\&. +.RE +.PP +\fBkill\-user [USER\&.\&.\&.]\fR +.RS 4 +Send a signal to all processes of a user\&. Use +\fB\-\-signal=\fR +to select the signal to send\&. +.RE +.PP +\fBlist\-seats\fR +.RS 4 +List currently available seats on the local system\&. +.RE +.PP +\fBseat\-status [NAME\&.\&.\&.]\fR +.RS 4 +Show terse runtime status information about one or more seats\&. This function is intended to generate human\-readable output\&. If you are looking for computer\-parsable output, use +\fBshow\-seat\fR +instead\&. +.RE +.PP +\fBshow\-seat [NAME\&.\&.\&.]\fR +.RS 4 +Show properties of one or more seats or the manager itself\&. If no argument is specified properties of the manager will be shown\&. If a seat is specified properties of the seat are shown\&. By default, empty properties are suppressed\&. Use +\fB\-\-all\fR +to show those too\&. To select specific properties to show use +\fB\-\-property=\fR\&. This command is intended to be used whenever computer\-parsable output is required\&. Use +\fBseat\-status\fR +if you are looking for formatted human\-readable output\&. +.RE +.PP +\fBattach [NAME] [DEVICE\&.\&.\&.]\fR +.RS 4 +Attach one or more devices to a seat\&. The devices should be specified via device paths in the +/sys +file system\&. To create a new seat attach at least one graphics card to a previously unused seat names\&. seat names may consist only of a\-z, A\-Z, 0\-9, "\-" and "_" and must be prefixed with "seat"\&. To drop assignment of a device to a specific seat just reassign it to a different seat, or use +\fBflush\-devices\fR\&. +.RE +.PP +\fBflush\-devices\fR +.RS 4 +Removes all device assignments previously created with +\fBattach\fR\&. After this call only automatically generated seats will remain and all seat hardware is assigned to them\&. +.RE +.PP +\fBterminate\-seat [NAME\&.\&.\&.]\fR +.RS 4 +Terminates all sessions on a seat\&. This kills all processes of all sessions on a seat and deallocates all runtime resources attached to them\&. +.RE +.SH "EXIT STATUS" +.PP +On success 0 is returned, a non\-zero failure code otherwise\&. +.SH "ENVIRONMENT" +.PP +\fI$SYSTEMD_PAGER\fR +.RS 4 +Pager to use when +\fB\-\-no\-pager\fR +is not given; overrides +\fI$PAGER\fR\&. Setting this to an empty string or the value +cat +is equivalent to passing +\fB\-\-no\-pager\fR\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(1), +\fBsystemd-logind.conf\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd-loginctl.xml b/man/systemd-loginctl.xml new file mode 100644 index 0000000..6a28276 --- /dev/null +++ b/man/systemd-loginctl.xml @@ -0,0 +1,457 @@ + + + + + + + + + systemd-loginctl + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-loginctl + 1 + + + + systemd-loginctl + Control the systemd login manager + + + + + systemd-loginctl OPTIONS COMMAND NAME + + + + + Description + + systemd-loginctl may be used to + introspect and control the state of the + systemd1 + login manager. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Prints a short version + string and exits. + + + + + + + When showing + session/user/ properties, limit + display to certain properties as + specified as argument. If not + specified all set properties are + shown. The argument should be a + property name, such as + Sessions. If + specified more than once all + properties with the specified names + are shown. + + + + + + + When showing + unit/job/manager properties, show all + properties regardless whether they are + set or not. + + + + + + + Do not pipe output into a + pager. + + + + + + When used with + kill-session, + choose which processes to kill. Must + be one of , or + to select whether + to kill only the leader process of the + session or all processes of the + session. If omitted defaults to + . + + + + + + + When used with + kill-session or + kill-user, choose + which signal to send to selected + processes. Must be one of the well + known signal specifiers such as + SIGTERM, SIGINT or SIGSTOP. If omitted + defaults to + . + + + + + + + Execute operation + remotely. Specify a hostname, or + username and hostname separated by @, + to connect to. This will use SSH to + talk to the remote login manager + instance. + + + + + + + Acquire privileges via + PolicyKit before executing the + operation. + + + + The following commands are understood: + + + + list-sessions + + List current sessions. + + + + session-status [ID...] + + Show terse runtime + status information about one or more + sessions. This function is intended to + generate human-readable output. If you + are looking for computer-parsable + output, use + show-session + instead. + + + + show-session [ID...] + + Show properties of one + or more sessions or the manager + itself. If no argument is specified + properties of the manager will be + shown. If a session ID is specified + properties of the session is shown. By + default, empty properties are + suppressed. Use + to show those too. To select specific + properties to show use + . This + command is intended to be used + whenever computer-parsable output is + required. Use + session-status if + you are looking for formatted + human-readable + output. + + + + activate [ID...] + + Activate one or more + sessions. This brings one or more + sessions into the foreground, if + another session is currently in the + foreground on the respective + seat. + + + + lock-session [ID...] + unlock-session [ID...] + + Activates/deactivates + the screen lock on one or more + sessions, if the session supports it. + + + + terminate-session [ID...] + + Terminates a + session. This kills all processes of + the session and deallocates all + resources attached to the + session. + + + + kill-session [ID...] + + Send a signal to one + or more processes of the session. Use + to select + which process to kill. Use + to select + the signal to send. + + + + list-users + + List currently logged + in users. + + + + user-status [USER...] + + Show terse runtime + status information about one or more + logged in users. This function is + intended to generate human-readable + output. If you are looking for + computer-parsable output, use + show-user + instead. Users may be specified by + their usernames or numeric user + IDs. + + + + show-user [USER...] + + Show properties of one + or more users or the manager + itself. If no argument is specified + properties of the manager will be + shown. If a user is specified + properties of the user is shown. By + default, empty properties are + suppressed. Use + to show those too. To select specific + properties to show use + . This + command is intended to be used + whenever computer-parsable output is + required. Use + user-status if + you are looking for formatted + human-readable + output. + + + + enable-linger [USER...] + disable-linger [USER...] + + Enable/disable user + lingering for one or more users. If + enabled for a specific user a user + manager is spawned for him/her at + boot, and kept around after + logouts. This allows users who aren't + logged in to run long-running + services. + + + + terminate-user [USER...] + + Terminates all + sessions of a user. This kills all + processes of all sessions of the user + and deallocates all runtime resources + attached to the + user. + + + + kill-user [USER...] + + Send a signal to all + processes of a user. Use + to select + the signal to send. + + + + list-seats + + List currently + available seats on the local + system. + + + + seat-status [NAME...] + + Show terse runtime + status information about one or more + seats. This function is + intended to generate human-readable + output. If you are looking for + computer-parsable output, use + show-seat + instead. + + + + show-seat [NAME...] + + Show properties of one + or more seats or the manager + itself. If no argument is specified + properties of the manager will be + shown. If a seat is specified + properties of the seat are shown. By + default, empty properties are + suppressed. Use + to show those too. To select specific + properties to show use + . This + command is intended to be used + whenever computer-parsable output is + required. Use + seat-status if you + are looking for formatted + human-readable + output. + + + + attach [NAME] [DEVICE...] + + Attach one or more + devices to a seat. The devices should + be specified via device paths in the + /sys file + system. To create a new seat attach at + least one graphics card to a + previously unused seat names. seat + names may consist only of a-z, A-Z, + 0-9, "-" and "_" and must be prefixed + with "seat". To drop assignment of a + device to a specific seat just + reassign it to a different seat, or + use + flush-devices. + + + + flush-devices + + Removes all device + assignments previously created with + attach. After this + call only automatically generated + seats will remain and all seat + hardware is assigned to + them. + + + + terminate-seat [NAME...] + + Terminates all + sessions on a seat. This kills all + processes of all sessions on a seat and + deallocates all runtime resources + attached to them. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Environment + + + + $SYSTEMD_PAGER + Pager to use when + is not given; + overrides $PAGER. Setting + this to an empty string or the value + cat is equivalent to passing + . + + + + + + See Also + + systemd1, + systemctl1, + systemd-logind.conf5 + + + + diff --git a/man/systemd-logind.conf.5 b/man/systemd-logind.conf.5 new file mode 100644 index 0000000..4b4e2f2 --- /dev/null +++ b/man/systemd-logind.conf.5 @@ -0,0 +1,116 @@ +'\" t +.\" Title: systemd-logind.conf +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd-logind.conf +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\-LOGIND\&.CO" "5" "02/15/2012" "systemd" "systemd-logind.conf" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd-logind.conf \- login manager configuration file +.SH "SYNOPSIS" +.PP +systemd\-login\&.conf +.SH "DESCRIPTION" +.PP +This files configures various parameters of the systemd login manager\&. +.SH "OPTIONS" +.PP +All options are configured in the +[Login] +section: +.PP +\fINAutoVTs=\fR +.RS 4 +Takes a positive integer\&. How many virtual terminals to allocate by default and when switched to autospawn +autovt +services on (if they are otherwise unused)\&. These services are instantiated from a template of +autovt@\&.service +with the virtual terminal TTY name, e\&.g\&. +autovt@tty4\&.service\&. By default +autovt@\&.service +is linked to +getty@\&.service, i\&.e\&. login prompts are started dynamically as the user switches to unused virtual terminals, and this parameter hence controls how many gettys are available on the virtual terminals\&. Defaults to 6\&. When set to 0, automatic spawning of +autovt +services is disabled\&. +.RE +.PP +\fIKillUserProcesses=\fR +.RS 4 +Takes a boolean argument\&. Configures whether the processes of a user should be killed when she or he completely logs out (i\&.e\&. after her/his last session ended)\&. Defaults to +no\&. +.RE +.PP +\fIKillOnlyUsers=\fR, \fIKillExcludeUsers=\fR +.RS 4 +These settings take space separated lists of user names that influence the effect of +\fIKillUserProcesses=\fR\&. If not empty only processes of users listed in +\fIKillOnlyUsers\fR +will be killed when they log out entirely\&. Processes of users listed in +\fIKillExcludeUsers=\fR +are excluded from being killed\&. +\fIKillExcludeUsers=\fR +defaults to +root +and takes precedence over +\fIKillOnlyUsers=\fR +which defaults to the empty list\&. +.RE +.PP +\fIControllers=\fR, \fIResetControllers=\fR +.RS 4 +These settings control the default control group hierarchies users logging are added to\&. When logging in users will get private control groups in all hierarchies listed in +\fIControllers=\fR +and be reset to the root control group in all hierarchies listed in +\fIResetControllers=\fR\&. +\fIControllers=\fR +defaults to the empty list, +\fIResetControllers=\fR +defaults to +cpu\&. +.RE +.PP +Note that setting +\fIKillUserProcesses=1\fR +will break tools like +\fBscreen\fR(1)\&. +.PP +Note that +\fIKillUserProcesses=1\fR +is a weaker version of +\fIkill\-session\-processes=1\fR +which may be configured per\-service for +\fBpam_systemd\fR(8)\&. The latter kills processes of a session as soon as it ends, the former kills processes as soon as the last session of the user ends\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemd-loginctl\fR(1), +\fBsystemd.conf\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd-logind.conf.xml b/man/systemd-logind.conf.xml new file mode 100644 index 0000000..c7e277f --- /dev/null +++ b/man/systemd-logind.conf.xml @@ -0,0 +1,175 @@ + + + + + + + + + systemd-logind.conf + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-logind.conf + 5 + + + + systemd-logind.conf + login manager configuration file + + + + systemd-login.conf + + + + Description + + This files configures various parameters of the systemd login manager. + + + + + Options + + All options are configured in the + [Login] section: + + + + + NAutoVTs= + + Takes a positive + integer. How many virtual terminals to + allocate by default and when switched + to autospawn autovt + services on (if they are otherwise + unused). These services are + instantiated from a template of + autovt@.service + with the virtual terminal TTY name, + e.g. autovt@tty4.service. By + default + autovt@.service + is linked to + getty@.service, + i.e. login prompts are started + dynamically as the user switches to + unused virtual terminals, and this + parameter hence controls how many + gettys are available on the virtual + terminals. Defaults to 6. When set to + 0, automatic spawning of + autovt services is + disabled. + + + + KillUserProcesses= + + Takes a boolean + argument. Configures whether the + processes of a user should be killed + when she or he completely logs out (i.e. after + her/his last session ended). Defaults to + no. + + + + KillOnlyUsers= + KillExcludeUsers= + + These settings take + space separated lists of user names + that influence the effect of + KillUserProcesses=. If + not empty only processes of users + listed in + KillOnlyUsers will + be killed when they log out + entirely. Processes of users listed in + KillExcludeUsers= + are excluded from being + killed. KillExcludeUsers= + defaults to root + and takes precedence over + KillOnlyUsers= + which defaults to the empty list. + + + + Controllers= + ResetControllers= + + These settings control + the default control group hierarchies + users logging are added to. When + logging in users will get private + control groups in all hierarchies + listed in + Controllers= and be + reset to the root control group in all + hierarchies listed in + ResetControllers=. Controllers= + defaults to the empty list, + ResetControllers= + defaults to + cpu. + + + + Note that setting + KillUserProcesses=1 will break tools + like + screen1. + + Note that KillUserProcesses=1 + is a weaker version of + kill-session-processes=1 which may + be configured per-service for + pam_systemd8. The + latter kills processes of a session as soon as it + ends, the former kills processes as soon as the last + session of the user ends. + + + + See Also + + systemd1, + systemd-loginctl1, + systemd.conf5 + + + + diff --git a/man/systemd-notify.1 b/man/systemd-notify.1 new file mode 100644 index 0000000..5329a1e --- /dev/null +++ b/man/systemd-notify.1 @@ -0,0 +1,136 @@ +'\" t +.\" Title: systemd-notify +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd-notify +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\-NOTIFY" "1" "02/15/2012" "systemd" "systemd-notify" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd-notify \- Notify init system about start\-up completion and other daemon status changes +.SH "SYNOPSIS" +.HP \w'\fBsystemd\-notify\ \fR\fB[OPTIONS...]\fR\fB\ \fR\fB[VARIABLE=VALUE...]\fR\ 'u +\fBsystemd\-notify \fR\fB[OPTIONS...]\fR\fB \fR\fB[VARIABLE=VALUE...]\fR +.SH "DESCRIPTION" +.PP +\fBsystemd\-notify\fR +may be called by daemon scripts to notify the init system about status changes\&. It can be used to send arbitrary information, encoded in an environment\-block\-like list of strings\&. Most importantly it can be used for start\-up completion notification\&. +.PP +This is mostly just a wrapper around +\fBsd_notify()\fR +and makes this functionality available to shell scripts\&. For details see +\fBsd_notify\fR(3)\&. +.PP +The command line may carry a list of environment variables to send as part of the status update\&. +.PP +Note that systemd will refuse reception of status updates from this command unless +\fINotifyAccess=all\fR +is set for the service unit this command is called from\&. +.SH "OPTIONS" +.PP +The following options are understood: +.PP +\fB\-\-h\fR, \fB\-\-help\fR +.RS 4 +Prints a short help text and exits\&. +.RE +.PP +\fB\-\-ready\fR +.RS 4 +Inform the init system about service start\-up completion\&. This is equivalent to +\fBsystemd\-notify READY=1\fR\&. For details about the semantics of this option see +\fBsd_notify\fR(3)\&. +.RE +.PP +\fB\-\-pid=\fR +.RS 4 +Inform the init system about the main PID of the daemon\&. Takes a PID as argument\&. If the argument is omitted the PID of the process that invoked +\fBsystemd\-notify\fR +is used\&. This is equivalent to +\fBsystemd\-notify MAINPID=$PID\fR\&. For details about the semantics of this option see +\fBsd_notify\fR(3)\&. +.RE +.PP +\fB\-\-status=\fR +.RS 4 +Send a free\-form status string for the daemon to the init systemd\&. This option takes the status string as argument\&. This is equivalent to +\fBsystemd\-notify STATUS=\&.\&.\&.\fR\&. For details about the semantics of this option see +\fBsd_notify\fR(3)\&. +.RE +.PP +\fB\-\-booted\fR +.RS 4 +Returns 0 if the system was booted up with systemd, non\-zero otherwise\&. If this option is passed no message is sent\&. This option is hence unrelated to the other options\&. For details about the semantics of this option see +\fBsd_booted\fR(3)\&. +.RE +.PP +\fB\-\-readahead=\fR +.RS 4 +Controls disk read\-ahead operations\&. The argument must be a string, and either "cancel", "done" or "noreplay"\&. For details about the semantics of this option see +\fBsd_readahead\fR(3)\&. +.RE +.SH "EXIT STATUS" +.PP +On success 0 is returned, a non\-zero failure code otherwise\&. +.SH "EXAMPLE" +.PP +\fBExample\ \&1.\ \&Start-up Notification and Status Updates\fR +.PP +A simple shell daemon that sends start\-up notifications after having set up its communication channel\&. During runtime it sends further status updates to the init system: +.sp +.if n \{\ +.RS 4 +.\} +.nf +#!/bin/bash + +mkfifo /tmp/waldo +systemd\-notify \-\-ready \-\-status="Waiting for data\&.\&.\&." + +while : ; do + read a < /tmp/waldo + systemd\-notify \-\-status="Processing $a" + + # Do something with $a \&.\&.\&. + + systemd\-notify \-\-status="Waiting for data\&.\&.\&." +done +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(1), +\fBsystemd.unit\fR(5), +\fBsd_notify\fR(3), +\fBsd_booted\fR(3) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd-notify.xml b/man/systemd-notify.xml new file mode 100644 index 0000000..59d6b2f --- /dev/null +++ b/man/systemd-notify.xml @@ -0,0 +1,211 @@ + + + + + + + + + systemd-notify + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-notify + 1 + + + + systemd-notify + Notify init system about start-up completion and other daemon status changes + + + + + systemd-notify OPTIONS VARIABLE=VALUE + + + + + Description + + systemd-notify may be + called by daemon scripts to notify the init system + about status changes. It can be used to send arbitrary + information, encoded in an environment-block-like list + of strings. Most importantly it can be used for + start-up completion notification. + + This is mostly just a wrapper around + sd_notify() and makes this + functionality available to shell scripts. For details + see + sd_notify3. + + The command line may carry a list of + environment variables to send as part of the status + update. + + Note that systemd will refuse reception of + status updates from this command unless + NotifyAccess=all is set for the + service unit this command is called from. + + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + Inform the init system + about service start-up + completion. This is equivalent to + systemd-notify + READY=1. For details about + the semantics of this option see + sd_notify3. + + + + + + Inform the init system + about the main PID of the + daemon. Takes a PID as argument. If + the argument is omitted the PID of the + process that invoked + systemd-notify is + used. This is equivalent to + systemd-notify + MAINPID=$PID. For details + about the semantics of this option see + sd_notify3. + + + + + + Send a free-form + status string for the daemon to the + init systemd. This option takes the + status string as argument. This is + equivalent to systemd-notify + STATUS=.... For details + about the semantics of this option see + sd_notify3. + + + + + + Returns 0 if the + system was booted up with systemd, + non-zero otherwise. If this option is + passed no message is sent. This option + is hence unrelated to the other + options. For details about the + semantics of this option see + sd_booted3. + + + + + + Controls disk + read-ahead operations. The argument + must be a string, and either "cancel", + "done" or "noreplay". For details + about the semantics of this option see + sd_readahead3. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Example + + + Start-up Notification and Status Updates + + A simple shell daemon that sends + start-up notifications after having set up its + communication channel. During runtime it sends + further status updates to the init + system: + + #!/bin/bash + +mkfifo /tmp/waldo +systemd-notify --ready --status="Waiting for data..." + +while : ; do + read a < /tmp/waldo + systemd-notify --status="Processing $a" + + # Do something with $a ... + + systemd-notify --status="Waiting for data..." +done + + + + + See Also + + systemd1, + systemctl1, + systemd.unit5, + sd_notify3, + sd_booted3 + + + + diff --git a/man/systemd-nspawn.1 b/man/systemd-nspawn.1 new file mode 100644 index 0000000..dc72a7a --- /dev/null +++ b/man/systemd-nspawn.1 @@ -0,0 +1,145 @@ +'\" t +.\" Title: systemd-nspawn +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd-nspawn +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\-NSPAWN" "1" "02/15/2012" "systemd" "systemd-nspawn" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd-nspawn \- Spawn a namespace container for debugging, testing and building +.SH "SYNOPSIS" +.HP \w'\fBsystemd\-nspawn\ \fR\fB[OPTIONS...]\fR\fB\ \fR\fB[COMMAND]\fR\fB\ \fR\fB[ARGS...]\fR\ 'u +\fBsystemd\-nspawn \fR\fB[OPTIONS...]\fR\fB \fR\fB[COMMAND]\fR\fB \fR\fB[ARGS...]\fR +.SH "DESCRIPTION" +.PP +\fBsystemd\-nspawn\fR +may be used to run a command or OS in a light\-weight namespace container\&. In many ways it is similar to +\fBchroot\fR(1), but more powerful since it fully virtualizes the file system hierarchy, as well as the process tree, the various IPC subsystems and the host and domain name\&. +.PP +\fBsystemd\-nspawn\fR +limits access to various kernel interfaces in the container to read\-only, such as +/sys, +/proc/sys +or +/sys/fs/selinux\&. Network interfaces and the system clock may not be changed from within the container\&. Device nodes may not be created\&. The host system cannot be rebooted and kernel modules may not be loaded from within the container\&. +.PP +Note that even though these security precautions are taken +\fBsystemd\-nspawn\fR +is not suitable for secure container setups\&. Many of the security features may be circumvented and are hence primarily useful to avoid accidental changes to the host system from the container\&. The intended use of this program is debugging and testing as well as building of packages, distributions and software involved with boot and systems management\&. +.PP +In contrast to +\fBchroot\fR(1) +\fBsystemd\-nspawn\fR +may be used to boot full Linux\-based operating systems in a container\&. +.PP +Use a tool like +\fBdebootstrap\fR(8) +or +\fBmock\fR(1) +to set up an OS directory tree suitable as file system hierarchy for +\fBsystemd\-nspawn\fR +containers\&. +.PP +Note that +\fBsystemd\-nspawn\fR +will mount file systems private to the container to +/dev, +/run +and similar\&. These will not be visible outside of the container, and their contents will be lost when the container exits\&. +.PP +Note that running two +\fBsystemd\-nspawn\fR +containers from the same directory tree will not make processes in them see each other\&. The PID namespace separation of the two containers is complete and the containers will share very few runtime objects except for the underlying file system\&. +.SH "OPTIONS" +.PP +If no arguments are passed the container is set up and a shell started in it, otherwise the passed command and arguments are executed in it\&. The following options are understood: +.PP +\fB\-\-help\fR, \fB\-h\fR +.RS 4 +Prints a short help text and exits\&. +.RE +.PP +\fB\-\-directory=\fR, \fB\-D\fR +.RS 4 +Directory to use as file system root for the namespace container\&. If omitted the current directory will be used\&. +.RE +.PP +\fB\-\-user=\fR, \fB\-u\fR +.RS 4 +Run the command under specified user, create home directory and cd into it\&. As rest of systemd\-nspawn, this is not the security feature and limits against accidental changes only\&. +.RE +.PP +\fB\-\-private\-network\fR +.RS 4 +Turn off networking in the container\&. This makes all network interfaces unavailable in the container, with the exception of the loopback device\&. +.RE +.SH "EXAMPLE 1" +.sp +.if n \{\ +.RS 4 +.\} +.nf +# debootstrap \-\-arch=amd64 unstable debian\-tree/ +# systemd\-nspawn \-D debian\-tree/ +.fi +.if n \{\ +.RE +.\} +.PP +This installs a minimal Debian unstable distribution into the directory +debian\-tree/ +and then spawns a shell in a namespace container in it\&. +.SH "EXAMPLE 2" +.sp +.if n \{\ +.RS 4 +.\} +.nf +# mock \-\-init +# systemd\-nspawn \-D /var/lib/mock/fedora\-rawhide\-x86_64/root/ /sbin/init systemd\&.log_level=debug +.fi +.if n \{\ +.RE +.\} +.PP +This installs a minimal Fedora distribution into a subdirectory of +/var/lib/mock/ +and then boots an OS in a namespace container in it, with systemd as init system, configured for debug logging\&. +.SH "EXIT STATUS" +.PP +The exit code of the program executed in the container is returned\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBchroot\fR(1), +\fBdebootstrap\fR(8), +\fBmock\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml new file mode 100644 index 0000000..dbd2ff5 --- /dev/null +++ b/man/systemd-nspawn.xml @@ -0,0 +1,215 @@ + + + + + + + + + systemd-nspawn + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-nspawn + 1 + + + + systemd-nspawn + Spawn a namespace container for debugging, testing and building + + + + + systemd-nspawn OPTIONS COMMAND ARGS + + + + + Description + + systemd-nspawn may be used to + run a command or OS in a light-weight namespace + container. In many ways it is similar to + chroot1, + but more powerful since it fully virtualizes the file + system hierarchy, as well as the process tree, the + various IPC subsystems and the host and domain + name. + + systemd-nspawn limits access + to various kernel interfaces in the container to + read-only, such as /sys, + /proc/sys or + /sys/fs/selinux. Network + interfaces and the system clock may not be changed + from within the container. Device nodes may not be + created. The host system cannot be rebooted and kernel + modules may not be loaded from within the + container. + + Note that even though these security precautions + are taken systemd-nspawn is not + suitable for secure container setups. Many of the + security features may be circumvented and are hence + primarily useful to avoid accidental changes to the + host system from the container. The intended use of + this program is debugging and testing as well as + building of packages, distributions and software + involved with boot and systems management. + + In contrast to + chroot1 + systemd-nspawn may be used to boot + full Linux-based operating systems in a + container. + + Use a tool like + debootstrap8 or mock1 + to set up an OS directory tree suitable as file system + hierarchy for systemd-nspawn containers. + + Note that systemd-nspawn will + mount file systems private to the container to + /dev, + /run and similar. These will + not be visible outside of the container, and their + contents will be lost when the container exits. + + Note that running two + systemd-nspawn containers from the + same directory tree will not make processes in them + see each other. The PID namespace separation of the + two containers is complete and the containers will + share very few runtime objects except for the + underlying file system. + + + + Options + + If no arguments are passed the container is set + up and a shell started in it, otherwise the passed + command and arguments are executed in it. The + following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + + + Directory to use as + file system root for the namespace + container. If omitted the current + directory will be + used. + + + + + + + Run the command + under specified user, create home + directory and cd into it. As rest + of systemd-nspawn, this is not + the security feature and limits + against accidental changes only. + + + + + + + Turn off networking in + the container. This makes all network + interfaces unavailable in the + container, with the exception of the + loopback device. + + + + + + + + Example 1 + + # debootstrap --arch=amd64 unstable debian-tree/ +# systemd-nspawn -D debian-tree/ + + This installs a minimal Debian unstable + distribution into the directory + debian-tree/ and then spawns a + shell in a namespace container in it. + + + + + Example 2 + + # mock --init +# systemd-nspawn -D /var/lib/mock/fedora-rawhide-x86_64/root/ /sbin/init systemd.log_level=debug + + This installs a minimal Fedora distribution into + a subdirectory of /var/lib/mock/ + and then boots an OS in a namespace container in it, + with systemd as init system, configured for debug + logging. + + + + + Exit status + + The exit code of the program executed in the + container is returned. + + + + See Also + + systemd1, + chroot1, + debootstrap8, + mock1 + + + + diff --git a/man/systemd-tmpfiles.8 b/man/systemd-tmpfiles.8 new file mode 100644 index 0000000..4f8eb6a --- /dev/null +++ b/man/systemd-tmpfiles.8 @@ -0,0 +1,103 @@ +'\" t +.\" Title: systemd-tmpfiles +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd-tmpfiles +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\-TMPFILES" "8" "02/15/2012" "systemd" "systemd-tmpfiles" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd-tmpfiles \- Creates, deletes and cleans up volatile and temporary files and directories\&. +.SH "SYNOPSIS" +.HP \w'\fBsystemd\-tmpfiles\ \fR\fB[OPTIONS...]\fR\fB\ \fR\fB[CONFIGURATION\ FILE...]\fR\ 'u +\fBsystemd\-tmpfiles \fR\fB[OPTIONS...]\fR\fB \fR\fB[CONFIGURATION\ FILE...]\fR +.SH "DESCRIPTION" +.PP +\fBsystemd\-tmpfiles\fR +creates, deletes and cleans up volatile and temporary files and directories, based on the configuration from +/etc/tmpfiles\&.d/\&. See +\fBtmpfiles.d\fR(5) +for more details on these files\&. +.PP +If invoked with no arguments applies all directives from all configuration files in +/etc/tmpfiles\&.d/*\&.conf\&. If one or more absolute file names are passed on the command line only the directives in these files are applied\&. +.SH "OPTIONS" +.PP +The following options are understood: +.PP +\fB\-\-create\fR +.RS 4 +If this option is passed all files and directories marked with f, F, d, D in the configuration files are created\&. Files and directories marked with z, Z have their ownership, access mode and security labels set\&. +.RE +.PP +\fB\-\-clean\fR +.RS 4 +If this option is passed all files and directories with an age parameter configured will be cleaned up\&. +.RE +.PP +\fB\-\-remove\fR +.RS 4 +If this option is passed all files and directories marked with r, R in the configuration files are removed\&. +.RE +.PP +\fB\-\-prefix=PATH\fR +.RS 4 +Only apply rules that apply to paths with the specified prefix\&. +.RE +.PP +\fB\-\-help\fR +.RS 4 +Prints a short help text and exits\&. +.RE +.PP +It is possible to combine +\fB\-\-create\fR, +\fB\-\-clean\fR, and +\fB\-\-remove\fR +in one invocation\&. For example, during boot the following command line is executed to ensure that all temporary and volatile directories are removed and created according to the configuration file: +.sp +.if n \{\ +.RS 4 +.\} +.nf +systemd\-tmpfiles \-\-remove \-\-create +.fi +.if n \{\ +.RE +.\} +.SH "EXIT STATUS" +.PP +On success 0 is returned, a non\-zero failure code otherwise\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBtmpfiles.d\fR(5), +\fBtmpwatch\fR(8) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml new file mode 100644 index 0000000..bbb80b2 --- /dev/null +++ b/man/systemd-tmpfiles.xml @@ -0,0 +1,152 @@ + + + + + + + + + systemd-tmpfiles + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd-tmpfiles + 8 + + + + systemd-tmpfiles + Creates, deletes and cleans up volatile + and temporary files and directories. + + + + + systemd-tmpfiles OPTIONS CONFIGURATION FILE + + + + + Description + + systemd-tmpfiles creates, + deletes and cleans up volatile and temporary files and + directories, based on the configuration from + /etc/tmpfiles.d/. See + tmpfiles.d5 + for more details on these files. + + If invoked with no arguments applies all + directives from all configuration files in + /etc/tmpfiles.d/*.conf. If one or + more absolute file names are passed on the command + line only the directives in these files are + applied. + + + + Options + + The following options are understood: + + + + + + If this option is passed all + files and directories marked with f, + F, d, D in the configuration files are + created. Files and directories marked with z, + Z have their ownership, access mode and security + labels set. + + + + + If this option is + passed all files and directories with + an age parameter configured will be + cleaned up. + + + + + If this option is + passed all files and directories marked + with r, R in the configuration files + are removed. + + + + Only apply rules that + apply to paths with the specified + prefix. + + + + + + + Prints a short help + text and exits. + + + + + It is possible to combine + , , + and in one invocation. For + example, during boot the following command line is + executed to ensure that all temporary and volatile + directories are removed and created according to the + configuration file: + + systemd-tmpfiles --remove --create + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + See Also + + systemd1, + tmpfiles.d5, + tmpwatch8 + + + + diff --git a/man/systemd.1 b/man/systemd.1 new file mode 100644 index 0000000..49e6544 --- /dev/null +++ b/man/systemd.1 @@ -0,0 +1,821 @@ +'\" t +.\" Title: systemd +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD" "1" "02/15/2012" "systemd" "systemd" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd, init \- systemd System and Service Manager +.SH "SYNOPSIS" +.HP \w'\fBsystemd\ \fR\fB[OPTIONS...]\fR\ 'u +\fBsystemd \fR\fB[OPTIONS...]\fR +.HP \w'\fBinit\ \fR\fB[OPTIONS...]\fR\fB\ \fR\fB{COMMAND}\fR\ 'u +\fBinit \fR\fB[OPTIONS...]\fR\fB \fR\fB{COMMAND}\fR +.SH "DESCRIPTION" +.PP +systemd is a system and service manager for Linux operating systems\&. When run as first process on boot (as PID 1), it acts as init system that brings up and maintains userspace services\&. +.PP +For compatibility with SysV, if systemd is called as +\fBinit\fR +and a PID that is not 1, it will execute +\fBtelinit\fR +and pass all command line arguments unmodified\&. That means +\fBinit\fR +and +\fBtelinit\fR +are mostly equivalent when invoked from normal login sessions\&. See +\fBtelinit\fR(8) +for more information\&. +.PP +When run as system instance, systemd interprets the configuration file +system\&.conf, otherwise +user\&.conf\&. See +\fBsystemd.conf\fR(5) +for more information\&. +.SH "OPTIONS" +.PP +The following options are understood: +.PP +\fB\-h\fR, \fB\-\-help\fR +.RS 4 +Prints a short help text and exits\&. +.RE +.PP +\fB\-\-test\fR +.RS 4 +Determine startup sequence, dump it and exit\&. This is an option useful for debugging only\&. +.RE +.PP +\fB\-\-dump\-configuration\-items\fR +.RS 4 +Dump understood unit configuration items\&. This outputs a terse but complete list of configuration items understood in unit definition files\&. +.RE +.PP +\fB\-\-introspect=\fR +.RS 4 +Extract D\-Bus interface introspection data\&. This is mostly useful at install time to generate data suitable for the D\-Bus interfaces repository\&. Optionally the interface name for the introspection data may be specified\&. If omitted, the introspection data for all interfaces is dumped\&. +.RE +.PP +\fB\-\-unit=\fR +.RS 4 +Set default unit to activate on startup\&. If not specified defaults to +default\&.target\&. +.RE +.PP +\fB\-\-system\fR, \fB\-\-user\fR +.RS 4 +Tell systemd to run a system instance (resp\&. user instance), even if the process ID is not 1 (resp\&. is 1), i\&.e\&. systemd is not (resp\&. is) run as init process\&. Normally it should not be necessary to pass these options, as systemd automatically detects the mode it is started in\&. These options are hence of little use except for debugging\&. Note that it is not supported booting and maintaining a full system with systemd running in +\fB\-\-system\fR +mode, but PID not 1\&. In practice, passing +\fB\-\-system\fR +explicitly is only useful in conjunction with +\fB\-\-test\fR\&. +.RE +.PP +\fB\-\-dump\-core\fR +.RS 4 +Dump core on crash\&. This switch has no effect when run as user instance\&. +.RE +.PP +\fB\-\-crash\-shell\fR +.RS 4 +Run shell on crash\&. This switch has no effect when run as user instance\&. +.RE +.PP +\fB\-\-confirm\-spawn\fR +.RS 4 +Ask for confirmation when spawning processes\&. This switch has no effect when run as user instance\&. +.RE +.PP +\fB\-\-show\-status=\fR +.RS 4 +Show terse service status information while booting\&. This switch has no effect when run as user instance\&. Takes a boolean argument which may be omitted which is interpreted as +\fBtrue\fR\&. +.RE +.PP +\fB\-\-sysv\-console=\fR +.RS 4 +Controls whether output of SysV init scripts will be directed to the console\&. This switch has no effect when run as user instance\&. Takes a boolean argument which may be omitted which is interpreted as +\fBtrue\fR\&. +.RE +.PP +\fB\-\-log\-target=\fR +.RS 4 +Set log target\&. Argument must be one of +\fBconsole\fR, +\fBjournal\fR, +\fBsyslog\fR, +\fBkmsg\fR, +\fBjournal\-or\-kmsg\fR, +\fBsyslog\-or\-kmsg\fR, +\fBnull\fR\&. +.RE +.PP +\fB\-\-log\-level=\fR +.RS 4 +Set log level\&. As argument this accepts a numerical log level or the well\-known +\fBsyslog\fR(3) +symbolic names (lowercase): +\fBemerg\fR, +\fBalert\fR, +\fBcrit\fR, +\fBerr\fR, +\fBwarning\fR, +\fBnotice\fR, +\fBinfo\fR, +\fBdebug\fR\&. +.RE +.PP +\fB\-\-log\-color=\fR +.RS 4 +Highlight important log messages\&. Argument is a boolean value\&. If the argument is omitted it defaults to +\fBtrue\fR\&. +.RE +.PP +\fB\-\-log\-location=\fR +.RS 4 +Include code location in log messages\&. This is mostly relevant for debugging purposes\&. Argument is a boolean value\&. If the argument is omitted it defaults to +\fBtrue\fR\&. +.RE +.PP +\fB\-\-default\-standard\-output=\fR, \fB\-\-default\-standard\-error=\fR +.RS 4 +Sets the default output resp\&. error output for all services and sockets, i\&.e\&. controls the default for +\fBStandardOutput=\fR +resp\&. +\fBStandardError=\fR +(see +\fBsystemd.exec\fR(5) +for details)\&. Takes one of +\fBinherit\fR, +\fBnull\fR, +\fBtty\fR, +\fBjournal\fR, +\fBjournal+console\fR, +\fBsyslog\fR, +\fBsyslog+console\fR, +\fBkmsg\fR, +\fBkmsg+console\fR\&. If the argument is omitted +\fB\-\-default\-standard\-output=\fR +defaults to +\fBjournal\fR +and +\fB\-\-default\-standard\-error=\fR +to +\fBinherit\fR\&. +.RE +.SH "CONCEPTS" +.PP +systemd provides a dependency system between various entities called "units"\&. Units encapsulate various objects that are relevant for system boot\-up and maintenance\&. The majority of units are configured in unit configuration files, whose syntax and basic set of options is described in +\fBsystemd.unit\fR(5), however some are created automatically from other configuration or dynamically from system state\&. Units may be \*(Aqactive\*(Aq (meaning started, bound, plugged in, \&.\&.\&. depending on the unit type, see below), or \*(Aqinactive\*(Aq (meaning stopped, unbound, unplugged, \&.\&.\&.), as well as in the process of being activated or deactivated, i\&.e\&. between the two states (these states are called \*(Aqactivating\*(Aq, \*(Aqdeactivating\*(Aq)\&. A special \*(Aqfailed\*(Aq state is available as well which is very similar to \*(Aqinactive\*(Aq and is entered when the service failed in some way (process returned error code on exit, or crashed, or an operation timed out)\&. If this state is entered the cause will be logged, for later reference\&. Note that the various unit types may have a number of additional substates, which are mapped to the five generalized unit states described here\&. +.PP +The following unit types are available: +.sp +.RS 4 +.ie n \{\ +\h'-04' 1.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 1." 4.2 +.\} +Service units, which control daemons and the processes they consist of\&. For details see +\fBsystemd.service\fR(5)\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 2.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 2." 4.2 +.\} +Socket units, which encapsulate local IPC or network sockets in the system, useful for socket\-based activation\&. For details about socket units see +\fBsystemd.socket\fR(5), for details on socket\-based activation and other forms of activation, see +\fBdaemon\fR(7)\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 3." 4.2 +.\} +Target units are useful to group units, or provide well\-known synchronization points during boot\-up, see +\fBsystemd.target\fR(5)\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 4.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 4." 4.2 +.\} +Device units expose kernel devices in systemd and may be used to implement device\-based activation\&. For details see +\fBsystemd.device\fR(5)\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 5.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 5." 4.2 +.\} +Mount units control mount points in the file system, for details see +\fBsystemd.mount\fR(5)\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 6.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 6." 4.2 +.\} +Automount units provide automount capabilities, for on\-demand mounting of file systems as well as parallelized boot\-up\&. See +\fBsystemd.automount\fR(5)\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 7.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 7." 4.2 +.\} +Snapshot units can be used to temporarily save the state of the set of systemd units, which later may be restored by activating the saved snapshot unit\&. For more information see +\fBsystemd.snapshot\fR(5)\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 8.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 8." 4.2 +.\} +Timer units are useful for triggering activation of other units based on timers\&. You may find details in +\fBsystemd.timer\fR(5)\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 9.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP " 9." 4.2 +.\} +Swap units are very similar to mount units and encapsulate memory swap partitions or files of the operating system\&. They are described in +\fBsystemd.swap\fR(5)\&. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'10.\h'+01'\c +.\} +.el \{\ +.sp -1 +.IP "10." 4.2 +.\} +Path units may be used to activate other services when file system objects change or are modified\&. See +\fBsystemd.path\fR(5)\&. +.RE +.PP +Units are named as their configuration files\&. Some units have special semantics\&. A detailed list is available in +\fBsystemd.special\fR(7)\&. +.PP +systemd knows various kinds of dependencies, including positive and negative requirement dependencies (i\&.e\&. +\fIRequires=\fR +and +\fIConflicts=\fR) as well as ordering dependencies (\fIAfter=\fR +and +\fIBefore=\fR)\&. NB: ordering and requirement dependencies are orthogonal\&. If only a requirement dependency exists between two units (e\&.g\&. +foo\&.service +requires +bar\&.service), but no ordering dependency (e\&.g\&. +foo\&.service +after +bar\&.service) and both are requested to start, they will be started in parallel\&. It is a common pattern that both requirement and ordering dependencies are placed between two units\&. Also note that the majority of dependencies are implicitly created and maintained by systemd\&. In most cases it should be unnecessary to declare additional dependencies manually, however it is possible to do this\&. +.PP +Application programs and units (via dependencies) may request state changes of units\&. In systemd, these requests are encapsulated as \*(Aqjobs\*(Aq and maintained in a job queue\&. Jobs may succeed or can fail, their execution is ordered based on the ordering dependencies of the units they have been scheduled for\&. +.PP +On boot systemd activates the target unit +default\&.target +whose job is to activate on\-boot services and other on\-boot units by pulling them in via dependencies\&. Usually the unit name is just an alias (symlink) for either +graphical\&.target +(for fully\-featured boots into the UI) or +multi\-user\&.target +(for limited console\-only boots for use in embedded or server environments, or similar; a subset of graphical\&.target)\&. However it is at the discretion of the administrator to configure it as an alias to any other target unit\&. See +\fBsystemd.special\fR(7) +for details about these target units\&. +.PP +Processes systemd spawns are placed in individual Linux control groups named after the unit which they belong to in the private systemd hierarchy\&. (see +\m[blue]\fBcgroups\&.txt\fR\m[]\&\s-2\u[1]\d\s+2 +for more information about control groups, or short "cgroups")\&. systemd uses this to effectively keep track of processes\&. Control group information is maintained in the kernel, and is accessible via the file system hierarchy (beneath +/sys/fs/cgroup/systemd/), or in tools such as +\fBps\fR(1) +(\fBps xawf \-eo pid,user,cgroup,args\fR +is particularly useful to list all processes and the systemd units they belong to\&.)\&. +.PP +systemd is compatible with the SysV init system to a large degree: SysV init scripts are supported and simply read as an alternative (though limited) configuration file format\&. The SysV +/dev/initctl +interface is provided, and compatibility implementations of the various SysV client tools are available\&. In addition to that, various established Unix functionality such as +/etc/fstab +or the +utmp +database are supported\&. +.PP +systemd has a minimal transaction system: if a unit is requested to start up or shut down it will add it and all its dependencies to a temporary transaction\&. Then, it will verify if the transaction is consistent (i\&.e\&. whether the ordering of all units is cycle\-free)\&. If it is not, systemd will try to fix it up, and removes non\-essential jobs from the transaction that might remove the loop\&. Also, systemd tries to suppress non\-essential jobs in the transaction that would stop a running service\&. Finally it is checked whether the jobs of the transaction contradict jobs that have already been queued, and optionally the transaction is aborted then\&. If all worked out and the transaction is consistent and minimized in its impact it is merged with all already outstanding jobs and added to the run queue\&. Effectively this means that before executing a requested operation, systemd will verify that it makes sense, fixing it if possible, and only failing if it really cannot work\&. +.PP +Systemd contains native implementations of various tasks that need to be executed as part of the boot process\&. For example, it sets the host name or configures the loopback network device\&. It also sets up and mounts various API file systems, such as +/sys +or +/proc\&. +.PP +For more information about the concepts and ideas behind systemd please refer to the +\m[blue]\fBOriginal Design Document\fR\m[]\&\s-2\u[2]\d\s+2\&. +.PP +Note that some but not all interfaces provided by systemd are covered by the +\m[blue]\fBInterface Stability Promise\fR\m[]\&\s-2\u[3]\d\s+2\&. +.SH "DIRECTORIES" +.PP +System unit directories +.RS 4 +The systemd system manager reads unit configuration from various directories\&. Packages that want to install unit files shall place them in the directory returned by +\fBpkg\-config systemd \-\-variable=systemdsystemunitdir\fR\&. Other directories checked are +/usr/local/lib/systemd/system +and +/usr/lib/systemd/system\&. User configuration always takes precedence\&. +\fBpkg\-config systemd \-\-variable=systemdsystemconfdir\fR +returns the path of the system configuration directory\&. Packages should alter the content of these directories only with the +\fBenable\fR +and +\fBdisable\fR +commands of the +\fBsystemctl\fR(1) +tool\&. +.RE +.PP +User unit directories +.RS 4 +Similar rules apply for the user unit directories\&. However, here the +\m[blue]\fBXDG Base Directory specification\fR\m[]\&\s-2\u[4]\d\s+2 +is followed to find units\&. Applications should place their unit files in the directory returned by +\fBpkg\-config systemd \-\-variable=systemduserunitdir\fR\&. Global configuration is done in the directory reported by +\fBpkg\-config systemd \-\-variable=systemduserconfdir\fR\&. The +\fBenable\fR +and +\fBdisable\fR +commands of the +\fBsystemctl\fR(1) +tool can handle both global (i\&.e\&. for all users) and private (for one user) enabling/disabling of units\&. +.RE +.PP +SysV init scripts directory +.RS 4 +The location of the SysV init script directory varies between distributions\&. If systemd cannot find a native unit file for a requested service, it will look for a SysV init script of the same name (with the +\&.service +suffix removed)\&. +.RE +.PP +SysV runlevel link farm directory +.RS 4 +The location of the SysV runlevel link farm directory varies between distributions\&. systemd will take the link farm into account when figuring out whether a service shall be enabled\&. Note that a service unit with a native unit configuration file cannot be started by activating it in the SysV runlevel link farm\&. +.RE +.SH "SIGNALS" +.PP +SIGTERM +.RS 4 +Upon receiving this signal the systemd system manager serializes its state, reexecutes itself and deserializes the saved state again\&. This is mostly equivalent to +\fBsystemctl daemon\-reexec\fR\&. +.sp +systemd user managers will start the +exit\&.target +unit when this signal is received\&. This is mostly equivalent to +\fBsystemctl \-\-user start exit\&.target\fR\&. +.RE +.PP +SIGINT +.RS 4 +Upon receiving this signal the systemd system manager will start the +ctrl\-alt\-del\&.target +unit\&. This is mostly equivalent to +\fBsystemctl start ctl\-alt\-del\&.target\fR\&. +.sp +systemd user managers treat this signal the same way as SIGTERM\&. +.RE +.PP +SIGWINCH +.RS 4 +When this signal is received the systemd system manager will start the +kbrequest\&.target +unit\&. This is mostly equivalent to +\fBsystemctl start kbrequest\&.target\fR\&. +.sp +This signal is ignored by systemd user managers\&. +.RE +.PP +SIGPWR +.RS 4 +When this signal is received the systemd manager will start the +sigpwr\&.target +unit\&. This is mostly equivalent to +\fBsystemctl start sigpwr\&.target\fR\&. +.RE +.PP +SIGUSR1 +.RS 4 +When this signal is received the systemd manager will try to reconnect to the D\-Bus bus\&. +.RE +.PP +SIGUSR2 +.RS 4 +When this signal is received the systemd manager will log its complete state in human readable form\&. The data logged is the same as printed by +\fBsystemctl dump\fR\&. +.RE +.PP +SIGHUP +.RS 4 +Reloads the complete daemon configuration\&. This is mostly equivalent to +\fBsystemctl daemon\-reload\fR\&. +.RE +.PP +SIGRTMIN+0 +.RS 4 +Enters default mode, starts the +default\&.target +unit\&. This is mostly equivalent to +\fBsystemctl start default\&.target\fR\&. +.RE +.PP +SIGRTMIN+1 +.RS 4 +Enters rescue mode, starts the +rescue\&.target +unit\&. This is mostly equivalent to +\fBsystemctl isolate rescue\&.target\fR\&. +.RE +.PP +SIGRTMIN+2 +.RS 4 +Enters emergency mode, starts the +emergency\&.service +unit\&. This is mostly equivalent to +\fBsystemctl isolate emergency\&.service\fR\&. +.RE +.PP +SIGRTMIN+3 +.RS 4 +Halts the machine, starts the +halt\&.target +unit\&. This is mostly equivalent to +\fBsystemctl start halt\&.target\fR\&. +.RE +.PP +SIGRTMIN+4 +.RS 4 +Powers off the machine, starts the +poweroff\&.target +unit\&. This is mostly equivalent to +\fBsystemctl start poweroff\&.target\fR\&. +.RE +.PP +SIGRTMIN+5 +.RS 4 +Reboots the machine, starts the +reboot\&.target +unit\&. This is mostly equivalent to +\fBsystemctl start reboot\&.target\fR\&. +.RE +.PP +SIGRTMIN+6 +.RS 4 +Reboots the machine via kexec, starts the +kexec\&.target +unit\&. This is mostly equivalent to +\fBsystemctl start kexec\&.target\fR\&. +.RE +.PP +SIGRTMIN+13 +.RS 4 +Immediately halts the machine\&. +.RE +.PP +SIGRTMIN+14 +.RS 4 +Immediately powers off the machine\&. +.RE +.PP +SIGRTMIN+15 +.RS 4 +Immediately reboots the machine\&. +.RE +.PP +SIGRTMIN+16 +.RS 4 +Immediately reboots the machine with kexec\&. +.RE +.PP +SIGRTMIN+20 +.RS 4 +Enables display of status messages on the console, as controlled via +\fIsystemd\&.show_status=1\fR +on the kernel command line\&. +.RE +.PP +SIGRTMIN+21 +.RS 4 +Disables display of status messages on the console, as controlled via +\fIsystemd\&.show_status=0\fR +on the kernel command line\&. +.RE +.PP +SIGRTMIN+22, SIGRTMIN+23 +.RS 4 +Sets the log level to +debug +(resp\&. +info +on +SIGRTMIN+23), as controlled via +\fIsystemd\&.log_level=debug\fR +(resp\&. +\fIsystemd\&.log_level=info\fR +on +SIGRTMIN+23) on the kernel command line\&. +.RE +.PP +SIGRTMIN+26, SIGRTMIN+27, SIGRTMIN+28, SIGRTMIN+29 +.RS 4 +Sets the log level to +journal\-or\-kmsg +(resp\&. +console +on +SIGRTMIN+27; resp\&. +kmsg +on +SIGRTMIN+28; resp\&. +syslog\-or\-kmsg +on +SIGRTMIN+29), as controlled via +\fIsystemd\&.log_target=journal\-or\-kmsg\fR +(resp\&. +\fIsystemd\&.log_target=console\fR +on +SIGRTMIN+27; resp\&. +\fIsystemd\&.log_target=kmsg\fR +on +SIGRTMIN+28; resp +\fIsystemd\&.log_target=syslog\-or\-kmsg\fR +on +SIGRTMIN+29) on the kernel command line\&. +.RE +.SH "ENVIRONMENT" +.PP +\fI$SYSTEMD_LOG_LEVEL\fR +.RS 4 +systemd reads the log level from this environment variable\&. This can be overridden with +\fB\-\-log\-level=\fR\&. +.RE +.PP +\fI$SYSTEMD_LOG_TARGET\fR +.RS 4 +systemd reads the log target from this environment variable\&. This can be overridden with +\fB\-\-log\-target=\fR\&. +.RE +.PP +\fI$SYSTEMD_LOG_COLOR\fR +.RS 4 +Controls whether systemd highlights important log messages\&. This can be overridden with +\fB\-\-log\-color=\fR\&. +.RE +.PP +\fI$SYSTEMD_LOG_LOCATION\fR +.RS 4 +Controls whether systemd prints the code location along with log messages\&. This can be overridden with +\fB\-\-log\-location=\fR\&. +.RE +.PP +\fI$XDG_CONFIG_HOME\fR, \fI$XDG_CONFIG_DIRS\fR, \fI$XDG_DATA_HOME\fR, \fI$XDG_DATA_DIRS\fR +.RS 4 +The systemd user manager uses these variables in accordance to the +\m[blue]\fBXDG Base Directory specification\fR\m[]\&\s-2\u[4]\d\s+2 +to find its configuration\&. +.RE +.PP +\fI$SYSTEMD_UNIT_PATH\fR +.RS 4 +Controls where systemd looks for unit files\&. +.RE +.PP +\fI$SYSTEMD_SYSVINIT_PATH\fR +.RS 4 +Controls where systemd looks for SysV init scripts\&. +.RE +.PP +\fI$SYSTEMD_SYSVRCND_PATH\fR +.RS 4 +Controls where systemd looks for SysV init script runlevel link farms\&. +.RE +.PP +\fI$LISTEN_PID\fR, \fI$LISTEN_FDS\fR +.RS 4 +Set by systemd for supervised processes during socket\-based activation\&. See +\fBsd_listen_fds\fR(3) +for more information\&. +.RE +.PP +\fI$NOTIFY_SOCKET\fR +.RS 4 +Set by systemd for supervised processes for status and start\-up completion notification\&. See +\fBsd_notify\fR(3) +for more information\&. +.RE +.SH "KERNEL COMMAND LINE" +.PP +When run as system instance systemd parses a few kernel command line arguments: +.PP +\fIsystemd\&.unit=\fR +.RS 4 +Overrides the unit to activate on boot\&. Defaults to +default\&.target\&. This may be used to temporarily boot into a different boot unit, for example +rescue\&.target +or +emergency\&.service\&. See +\fBsystemd.special\fR(7) +for details about these units\&. +.RE +.PP +\fIsystemd\&.dump_core=\fR +.RS 4 +Takes a boolean argument\&. If +\fBtrue\fR +systemd dumps core when it crashes\&. Otherwise no core dump is created\&. Defaults to +\fBtrue\fR\&. +.RE +.PP +\fIsystemd\&.crash_shell=\fR +.RS 4 +Takes a boolean argument\&. If +\fBtrue\fR +systemd spawns a shell when it crashes\&. Otherwise no shell is spawned\&. Defaults to +\fBfalse\fR, for security reasons, as the shell is not protected by any password authentication\&. +.RE +.PP +\fIsystemd\&.crash_chvt=\fR +.RS 4 +Takes an integer argument\&. If positive systemd activates the specified virtual terminal when it crashes\&. Defaults to +\-1\&. +.RE +.PP +\fIsystemd\&.confirm_spawn=\fR +.RS 4 +Takes a boolean argument\&. If +\fBtrue\fR +asks for confirmation when spawning processes\&. Defaults to +\fBfalse\fR\&. +.RE +.PP +\fIsystemd\&.show_status=\fR +.RS 4 +Takes a boolean argument\&. If +\fBtrue\fR +shows terse service status updates on the console during bootup\&. Defaults to +\fBtrue\fR\&. +.RE +.PP +\fIsystemd\&.sysv_console=\fR +.RS 4 +Takes a boolean argument\&. If +\fBtrue\fR +output of SysV init scripts will be directed to the console\&. Defaults to +\fBtrue\fR, unless +\fBquiet\fR +is passed as kernel command line option in which case it defaults to +\fBfalse\fR\&. +.RE +.PP +\fIsystemd\&.log_target=\fR, \fIsystemd\&.log_level=\fR, \fIsystemd\&.log_color=\fR, \fIsystemd\&.log_location=\fR +.RS 4 +Controls log output, with the same effect as the +\fI$SYSTEMD_LOG_TARGET\fR, +\fI$SYSTEMD_LOG_LEVEL\fR, +\fI$SYSTEMD_LOG_COLOR\fR, +\fI$SYSTEMD_LOG_LOCATION\fR +environment variables described above\&. +.RE +.PP +\fIsystemd\&.default_standard_output=\fR, \fIsystemd\&.default_standard_error=\fR +.RS 4 +Controls default standard output/error output for services, with the same effect as the +\fB\-\-default\-standard\-output=\fR +resp\&. +\fB\-\-default\-standard\-error=\fR +command line arguments described above\&. +.RE +.PP +\fIsystemd\&.setenv=\fR +.RS 4 +Takes a string argument in the form VARIABLE=VALUE\&. May be used to set environment variables for the init process and all its children at boot time\&. May be used more than once to set multiple variables\&. If the equal sign and variable are missing unsets an environment variable which might be passed in from the initial ram disk\&. +.RE +.SH "SOCKETS AND FIFOS" +.PP +/run/systemd/notify +.RS 4 +Daemon status notification socket\&. This is an AF_UNIX datagram socket and is used to implement the daemon notification logic as implemented by +\fBsd_notify\fR(3)\&. +.RE +.PP +/run/systemd/shutdownd +.RS 4 +Used internally by the +\fBshutdown\fR(8) +tool to implement delayed shutdowns\&. This is an AF_UNIX datagram socket\&. +.RE +.PP +/run/systemd/private +.RS 4 +Used internally as communication channel between +\fBsystemctl\fR(1) +and the systemd process\&. This is an AF_UNIX stream socket\&. This interface is private to systemd and should not be used in external projects\&. +.RE +.PP +/dev/initctl +.RS 4 +Limited compatibility support for the SysV client interface, as implemented by the +systemd\-initctl\&.service +unit\&. This is a named pipe in the file system\&. This interface is obsolete and should not be used in new applications\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemctl\fR(1), +\fBsystemadm\fR(1), +\fBsystemd-notify\fR(1), +\fBdaemon\fR(7), +\fBsd-daemon\fR(7), +\fBsystemd.unit\fR(5), +\fBsystemd.special\fR(5), +\fBpkg-config\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE +.SH "NOTES" +.IP " 1." 4 +cgroups.txt +.RS 4 +\%http://www.kernel.org/doc/Documentation/cgroups/cgroups.txt +.RE +.IP " 2." 4 +Original Design Document +.RS 4 +\%http://0pointer.de/blog/projects/systemd.html +.RE +.IP " 3." 4 +Interface Stability Promise +.RS 4 +\%http://www.freedesktop.org/wiki/Software/systemd/InterfaceStabilityPromise +.RE +.IP " 4." 4 +XDG Base Directory specification +.RS 4 +\%http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html +.RE diff --git a/man/systemd.automount.5 b/man/systemd.automount.5 new file mode 100644 index 0000000..2ce1c31 --- /dev/null +++ b/man/systemd.automount.5 @@ -0,0 +1,107 @@ +'\" t +.\" Title: systemd.automount +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd.automount +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\&.AUTOMOUNT" "5" "02/15/2012" "systemd" "systemd.automount" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd.automount \- systemd automount configuration files +.SH "SYNOPSIS" +.PP +systemd\&.automount +.SH "DESCRIPTION" +.PP +A unit configuration file whose name ends in +\&.automount +encodes information about a file system automount point controlled and supervised by systemd\&. +.PP +This man page lists the configuration options specific to this unit type\&. See +\fBsystemd.unit\fR(5) +for the common options of all unit configuration files\&. The common configuration items are configured in the generic [Unit] and [Install] sections\&. The automount specific configuration options are configured in the [Automount] section\&. +.PP +Automount units must be named after the automount directories they control\&. Example: the automount point +/home/lennart +must be configured in a unit file +home\-lennart\&.automount\&. For details about the escaping logic used to convert a file system path to a unit name see +\fBsystemd.unit\fR(5)\&. +.PP +For each automount unit file a matching mount unit file (see +\fBsystemd.mount\fR(5) +for details) must exist which is activated when the automount path is accessed\&. Example: if an automount unit +home\-lennart\&.automount +is active and the user accesses +/home/lennart +the mount unit +home\-lennart\&.mount +will be activated\&. +.PP +Automount units may be used to implement on\-demand mounting as well as parallelized mounting of file systems\&. +.PP +If an automount point is beneath another mount point in the file system hierarchy a dependency between both units is created automatically\&. +.SH "FSTAB" +.PP +Automount units may either be configured via unit files, or via +/etc/fstab +(see +\fBfstab\fR(5) +for details)\&. +.PP +For details how systemd parses +/etc/fstab +see +\fBsystemd.mount\fR(5)\&. +.PP +If an automount point is configured in both +/etc/fstab +and a unit file the configuration in the latter takes precedence\&. +.SH "OPTIONS" +.PP +Automount files must include an [Automount] section, which carries information about the file system automount points it supervises\&. The options specific to the [Automount] section of automount units are the following: +.PP +\fIWhere=\fR +.RS 4 +Takes an absolute path of a directory of the automount point\&. If the automount point is not existing at time of the automount point is installed it is created\&. This string must be reflected in the unit file name\&. (See above\&.) This option is mandatory\&. +.RE +.PP +\fIDirectoryMode=\fR +.RS 4 +Directories of automount points (and any parent directories) are automatically created if needed\&. This option specifies the file system access mode used when creating these directories\&. Takes an access mode in octal notation\&. Defaults to 0755\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(8), +\fBsystemd.unit\fR(5), +\fBsystemd.mount\fR(5), +\fBmount\fR(8), +\fBautomount\fR(8) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd.automount.xml b/man/systemd.automount.xml new file mode 100644 index 0000000..754d1e3 --- /dev/null +++ b/man/systemd.automount.xml @@ -0,0 +1,167 @@ + + + + + + + + + systemd.automount + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.automount + 5 + + + + systemd.automount + systemd automount configuration files + + + + systemd.automount + + + + Description + + A unit configuration file whose name ends in + .automount encodes information + about a file system automount point controlled and + supervised by systemd. + + This man page lists the configuration options + specific to this unit type. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. The + automount specific configuration options are configured + in the [Automount] section. + + Automount units must be named after the + automount directories they control. Example: the + automount point /home/lennart + must be configured in a unit file + home-lennart.automount. For + details about the escaping logic used to convert a + file system path to a unit name see + systemd.unit5. + + For each automount unit file a matching mount + unit file (see + systemd.mount5 + for details) must exist which is activated when the + automount path is accessed. Example: if an automount + unit home-lennart.automount is + active and the user accesses + /home/lennart the mount unit + home-lennart.mount will be + activated. + + Automount units may be used to implement + on-demand mounting as well as parallelized mounting of + file systems. + + If an automount point is beneath another mount + point in the file system hierarchy a dependency + between both units is created automatically. + + + + <filename>fstab</filename> + + Automount units may either be configured via unit + files, or via /etc/fstab (see + fstab5 + for details). + + For details how systemd parses + /etc/fstab see + systemd.mount5. + + If an automount point is configured in both + /etc/fstab and a unit file the + configuration in the latter takes precedence. + + + + Options + + Automount files must include an [Automount] + section, which carries information about the file + system automount points it supervises. The options + specific to the [Automount] section of automount units + are the following: + + + + + Where= + Takes an absolute path + of a directory of the automount + point. If the automount point is not + existing at time of the automount + point is installed it is created. This + string must be reflected in the unit + file name. (See above.) This option is + mandatory. + + + + DirectoryMode= + Directories of + automount points (and any parent + directories) are automatically created + if needed. This option specifies the + file system access mode used when + creating these directories. Takes an + access mode in octal + notation. Defaults to + 0755. + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.mount5, + mount8, + automount8 + + + + diff --git a/man/systemd.conf.5 b/man/systemd.conf.5 new file mode 100644 index 0000000..2d82d03 --- /dev/null +++ b/man/systemd.conf.5 @@ -0,0 +1,84 @@ +'\" t +.\" Title: systemd.conf +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd.conf +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\&.CONF" "5" "02/15/2012" "systemd" "systemd.conf" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd.conf \- systemd manager configuration file +.SH "SYNOPSIS" +.PP +system\&.conf +.PP +user\&.conf +.SH "DESCRIPTION" +.PP +When run as system instance systemd reads the configuration file +system\&.conf, otherwise +user\&.conf\&. These configuration files contain a few settings controlling basic manager operations\&. +.SH "OPTIONS" +.PP +All options are configured in the +[Manager] +section: +.PP +\fILogLevel=\fR, \fILogTarget=\fR, \fILogColor=\fR, \fILogLocation=\fR, \fIDumpCore=yes\fR, \fICrashShell=no\fR, \fIShowStatus=yes\fR, \fISysVConsole=yes\fR, \fICrashChVT=1\fR, \fIDefaultStandardOutput=journal\fR, \fIDefaultStandardError=inherit\fR +.RS 4 +Configures various parameters of basic manager operation\&. These options may be overridden by the respective command line arguments\&. See +\fBsystemd\fR(1) +for details about these command line arguments\&. +.RE +.PP +\fICPUAffinity=\fR +.RS 4 +Configures the initial CPU affinity for the init process\&. Takes a space\-separated list of CPU indexes\&. +.RE +.PP +\fIMountAuto=yes\fR, \fISwapAuto=yes\fR +.RS 4 +Configures whether systemd should automatically activate all swap or mounts listed in +/etc/fstab, or whether this job is left to some other system script\&. +.RE +.PP +\fIDefaultControllers=cpu\fR +.RS 4 +Configures in which cgroup controller hierarchies to create per\-service cgroups automatically, in addition to the name=systemd named hierarchy\&. Defaults to \*(Aqcpu\*(Aq\&. Takes a space separated list of controller names\&. Pass an empty string to ensure that systemd does not touch any hierarchies but its own\&. +.RE +.PP +\fIJoinControllers=cpu,cpuacct\fR +.RS 4 +Configures controllers that shall be mounted in a single hierarchy\&. By default systemd will mount all controllers which are enabled in the kernel in individual hierachies, with the exception of those listed in this setting\&. Takes a space separated list of comma separated controller names, in order to allow multiple joined hierarchies\&. Defaults to \*(Aqcpu,cpuacct\*(Aq\&. Pass an empty string to ensure that systemd mounts all controllers in separate hierarchies\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd.conf.xml b/man/systemd.conf.xml new file mode 100644 index 0000000..ba144da --- /dev/null +++ b/man/systemd.conf.xml @@ -0,0 +1,162 @@ + + + + + + + + + systemd.conf + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.conf + 5 + + + + systemd.conf + systemd manager configuration file + + + + system.conf + user.conf + + + + Description + + When run as system instance systemd reads the + configuration file system.conf, + otherwise user.conf. These + configuration files contain a few settings controlling + basic manager operations. + + + + + Options + + All options are configured in the + [Manager] section: + + + + + LogLevel= + LogTarget= + LogColor= + LogLocation= + DumpCore=yes + CrashShell=no + ShowStatus=yes + SysVConsole=yes + CrashChVT=1 + DefaultStandardOutput=journal + DefaultStandardError=inherit + + Configures various + parameters of basic manager + operation. These options may be + overridden by the respective command + line arguments. See + systemd1 + for details about these command line + arguments. + + + + CPUAffinity= + + Configures the initial + CPU affinity for the init + process. Takes a space-separated list + of CPU indexes. + + + + MountAuto=yes + SwapAuto=yes + + Configures whether + systemd should automatically activate + all swap or mounts listed in + /etc/fstab, or + whether this job is left to some other + system script. + + + + DefaultControllers=cpu + + Configures in which + cgroup controller hierarchies to + create per-service cgroups + automatically, in addition to the + name=systemd named hierarchy. Defaults + to 'cpu'. Takes a space separated list + of controller names. Pass an empty + string to ensure that systemd does not + touch any hierarchies but its + own. + + + + JoinControllers=cpu,cpuacct + + Configures controllers + that shall be mounted in a single + hierarchy. By default systemd will + mount all controllers which are + enabled in the kernel in individual + hierachies, with the exception of + those listed in this setting. Takes a + space separated list of comma + separated controller names, in order + to allow multiple joined + hierarchies. Defaults to + 'cpu,cpuacct'. Pass an empty string to + ensure that systemd mounts all + controllers in separate + hierarchies. + + + + + + See Also + + systemd1 + + + + diff --git a/man/systemd.device.5 b/man/systemd.device.5 new file mode 100644 index 0000000..23a2764 --- /dev/null +++ b/man/systemd.device.5 @@ -0,0 +1,100 @@ +'\" t +.\" Title: systemd.device +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd.device +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\&.DEVICE" "5" "02/15/2012" "systemd" "systemd.device" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd.device \- systemd device configuration files +.SH "SYNOPSIS" +.PP +systemd\&.device +.SH "DESCRIPTION" +.PP +A unit configuration file whose name ends in +\&.device +encodes information about a device unit as exposed in the sysfs/\fBudev\fR(7) +device tree\&. +.PP +This unit type has no specific options\&. See +\fBsystemd.unit\fR(5) +for the common options of all unit configuration files\&. The common configuration items are configured in the generic +[Unit] +and +[Install] +sections\&. A separate +[Device] +section does not exist, since no device\-specific options may be configured\&. +.PP +systemd will automatically create dynamic device units for all kernel devices that are marked with the "systemd" udev tag (by default all block and network devices, and a few others)\&. This may be used to define dependencies between devices and other units\&. +.PP +Device units are named after the +/sys +and +/dev +paths they control\&. Example: the device +/dev/sda5 +is exposed in systemd as +dev\-sda5\&.device\&. For details about the escaping logic used to convert a file system path to a unit name see +\fBsystemd.unit\fR(5)\&. +.SH "THE UDEV DATABASE" +.PP +The settings of device units may either be configured via unit files, or directly from the udev database (which is recommended)\&. The following udev properties are understood by systemd: +.PP +\fISYSTEMD_WANTS=\fR +.RS 4 +Adds dependencies of type +\fIWants\fR +from this unit to all listed units\&. This may be used to activate arbitrary units, when a specific device becomes available\&. Note that this and the other tags are not taken into account unless the device is tagged with the "systemd" string in the udev database, because otherwise the device is not exposed as systemd unit\&. +.RE +.PP +\fISYSTEMD_ALIAS=\fR +.RS 4 +Adds an additional alias name to the device unit\&. This must be an absolute path that is automatically transformed into a unit name\&. (See above\&.) +.RE +.PP +\fISYSTEMD_READY=\fR +.RS 4 +If set to 0 systemd will consider this device unplugged even if it shows up in the udev tree\&. If this property is unset or set to 1 the device will be considered plugged the moment it shows up in the udev tree\&. This property has no influence on the behaviour when a device disappears from the udev tree\&. This option is useful to support devices that initially show up in an uninitialized state in the tree, and for which a changed event is generated the moment they are fully set up\&. +.RE +.PP +\fIID_MODEL_FROM_DATABASE=\fR, \fIID_MODEL=\fR +.RS 4 +If set, this property is used as description string for the device unit\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(8), +\fBsystemd.unit\fR(5), +\fBudev\fR(7) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd.device.xml b/man/systemd.device.xml new file mode 100644 index 0000000..63863be --- /dev/null +++ b/man/systemd.device.xml @@ -0,0 +1,168 @@ + + + + + + + + + systemd.device + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.device + 5 + + + + systemd.device + systemd device configuration files + + + + systemd.device + + + + Description + + A unit configuration file whose name ends in + .device encodes information about + a device unit as exposed in the + sysfs/udev7 + device tree. + + This unit type has no specific options. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and + [Install] sections. A separate + [Device] section does not exist, + since no device-specific options may be + configured. + + systemd will automatically create dynamic device + units for all kernel devices that are marked with the + "systemd" udev tag (by default all block and network + devices, and a few others). This may be used to define + dependencies between devices and other + units. + + Device units are named after the + /sys and + /dev paths they control. Example: + the device /dev/sda5 is exposed + in systemd as dev-sda5.device. For + details about the escaping logic used to convert a + file system path to a unit name see + systemd.unit5. + + + + + The udev Database + + The settings of device units may either be + configured via unit files, or directly from the udev + database (which is recommended). The following udev + properties are understood by systemd: + + + + SYSTEMD_WANTS= + Adds dependencies of + type Wants from + this unit to all listed units. This + may be used to activate arbitrary + units, when a specific device becomes + available. Note that this and the + other tags are not taken into account + unless the device is tagged with the + "systemd" string in + the udev database, because otherwise + the device is not exposed as systemd + unit. + + + + SYSTEMD_ALIAS= + Adds an additional + alias name to the device unit. This + must be an absolute path that is + automatically transformed into a unit + name. (See above.) + + + + SYSTEMD_READY= + If set to 0 systemd + will consider this device unplugged + even if it shows up in the udev + tree. If this property is unset or set + to 1 the device will be considered + plugged the moment it shows up in the + udev tree. This property has no + influence on the behaviour when a + device disappears from the udev + tree. This option is useful to support + devices that initially show up in an + uninitialized state in the tree, and for + which a changed event is generated the + moment they are fully set + up. + + + + ID_MODEL_FROM_DATABASE= + ID_MODEL= + + If set, this property is + used as description string for the + device unit. + + + + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + udev7 + + + + diff --git a/man/systemd.exec.5 b/man/systemd.exec.5 new file mode 100644 index 0000000..71927dd --- /dev/null +++ b/man/systemd.exec.5 @@ -0,0 +1,635 @@ +'\" t +.\" Title: systemd.exec +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd.exec +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\&.EXEC" "5" "02/15/2012" "systemd" "systemd.exec" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd.exec \- systemd execution environment configuration +.SH "SYNOPSIS" +.PP +systemd\&.service, +systemd\&.socket, +systemd\&.mount, +systemd\&.swap +.SH "DESCRIPTION" +.PP +Unit configuration files for services, sockets, mount points and swap devices share a subset of configuration options which define the execution environment of spawned processes\&. +.PP +This man page lists the configuration options shared by these four unit types\&. See +\fBsystemd.unit\fR(5) +for the common options of all unit configuration files, and +\fBsystemd.service\fR(5), +\fBsystemd.socket\fR(5), +\fBsystemd.swap\fR(5) +and +\fBsystemd.mount\fR(5) +for more information on the specific unit configuration files\&. The execution specific configuration options are configured in the [Service], [Socket], [Mount] resp\&. [Swap] section, depending on the unit type\&. +.SH "OPTIONS" +.PP +\fIWorkingDirectory=\fR +.RS 4 +Takes an absolute directory path\&. Sets the working directory for executed processes\&. +.RE +.PP +\fIRootDirectory=\fR +.RS 4 +Takes an absolute directory path\&. Sets the root directory for executed processes, with the +\fBchroot\fR(2) +system call\&. If this is used it must be ensured that the process and all its auxiliary files are available in the +\fBchroot()\fR +jail\&. +.RE +.PP +\fIUser=\fR, \fIGroup=\fR +.RS 4 +Sets the Unix user resp\&. group the processes are executed as\&. Takes a single user resp\&. group name or ID as argument\&. If no group is set the default group of the user is chosen\&. +.RE +.PP +\fISupplementaryGroups=\fR +.RS 4 +Sets the supplementary Unix groups the processes are executed as\&. This takes a space separated list of group names or IDs\&. This option may be specified more than once in which case all listed groups are set as supplementary groups\&. This option does not override but extends the list of supplementary groups configured in the system group database for the user\&. +.RE +.PP +\fINice=\fR +.RS 4 +Sets the default nice level (scheduling priority) for executed processes\&. Takes an integer between \-20 (highest priority) and 19 (lowest priority)\&. See +\fBsetpriority\fR(2) +for details\&. +.RE +.PP +\fIOOMScoreAdjust=\fR +.RS 4 +Sets the adjustment level for the Out\-Of\-Memory killer for executed processes\&. Takes an integer between \-1000 (to disable OOM killing for this process) and 1000 (to make killing of this process under memory pressure very likely)\&. See +\m[blue]\fBproc\&.txt\fR\m[]\&\s-2\u[1]\d\s+2 +for details\&. +.RE +.PP +\fIIOSchedulingClass=\fR +.RS 4 +Sets the IO scheduling class for executed processes\&. Takes an integer between 0 and 3 or one of the strings +\fBnone\fR, +\fBrealtime\fR, +\fBbest\-effort\fR +or +\fBidle\fR\&. See +\fBioprio_set\fR(2) +for details\&. +.RE +.PP +\fIIOSchedulingPriority=\fR +.RS 4 +Sets the IO scheduling priority for executed processes\&. Takes an integer between 0 (highest priority) and 7 (lowest priority)\&. The available priorities depend on the selected IO scheduling class (see above)\&. See +\fBioprio_set\fR(2) +for details\&. +.RE +.PP +\fICPUSchedulingPolicy=\fR +.RS 4 +Sets the CPU scheduling policy for executed processes\&. Takes one of +\fBother\fR, +\fBbatch\fR, +\fBidle\fR, +\fBfifo\fR +or +\fBrr\fR\&. See +\fBsched_setscheduler\fR(2) +for details\&. +.RE +.PP +\fICPUSchedulingPriority=\fR +.RS 4 +Sets the CPU scheduling priority for executed processes\&. Takes an integer between 1 (lowest priority) and 99 (highest priority)\&. The available priority range depends on the selected CPU scheduling policy (see above)\&. See +\fBsched_setscheduler\fR(2) +for details\&. +.RE +.PP +\fICPUSchedulingResetOnFork=\fR +.RS 4 +Takes a boolean argument\&. If true elevated CPU scheduling priorities and policies will be reset when the executed processes fork, and can hence not leak into child processes\&. See +\fBsched_setscheduler\fR(2) +for details\&. Defaults to false\&. +.RE +.PP +\fICPUAffinity=\fR +.RS 4 +Controls the CPU affinity of the executed processes\&. Takes a space\-separated list of CPU indexes\&. See +\fBsched_setaffinity\fR(2) +for details\&. +.RE +.PP +\fIUMask=\fR +.RS 4 +Controls the file mode creation mask\&. Takes an access mode in octal notation\&. See +\fBumask\fR(2) +for details\&. Defaults to 0022\&. +.RE +.PP +\fIEnvironment=\fR +.RS 4 +Sets environment variables for executed processes\&. Takes a space\-separated list of variable assignments\&. This option may be specified more than once in which case all listed variables will be set\&. If the same variable is set twice the later setting will override the earlier setting\&. See +\fBenviron\fR(7) +for details\&. +.RE +.PP +\fIEnvironmentFile=\fR +.RS 4 +Similar to +\fIEnvironment=\fR +but reads the environment variables from a text file\&. The text file should contain new\-line separated variable assignments\&. Empty lines and lines starting with ; or # will be ignored, which may be used for commenting\&. The parser strips leading and trailing whitespace from the values of assignments, unless you use double quotes (")\&. The argument passed should be an absolute file name, optionally prefixed with "\-", which indicates that if the file does not exist it won\*(Aqt be read and no error or warning message is logged\&. The files listed with this directive will be read shortly before the process is executed\&. Settings from these files override settings made with +\fIEnvironment=\fR\&. If the same variable is set twice from these files the files will be read in the order they are specified and the later setting will override the earlier setting\&. +.RE +.PP +\fIStandardInput=\fR +.RS 4 +Controls where file descriptor 0 (STDIN) of the executed processes is connected to\&. Takes one of +\fBnull\fR, +\fBtty\fR, +\fBtty\-force\fR, +\fBtty\-fail\fR +or +\fBsocket\fR\&. If +\fBnull\fR +is selected standard input will be connected to +/dev/null, i\&.e\&. all read attempts by the process will result in immediate EOF\&. If +\fBtty\fR +is selected standard input is connected to a TTY (as configured by +\fITTYPath=\fR, see below) and the executed process becomes the controlling process of the terminal\&. If the terminal is already being controlled by another process the executed process waits until the current controlling process releases the terminal\&. +\fBtty\-force\fR +is similar to +\fBtty\fR, but the executed process is forcefully and immediately made the controlling process of the terminal, potentially removing previous controlling processes from the terminal\&. +\fBtty\-fail\fR +is similar to +\fBtty\fR +but if the terminal already has a controlling process start\-up of the executed process fails\&. The +\fBsocket\fR +option is only valid in socket\-activated services, and only when the socket configuration file (see +\fBsystemd.socket\fR(5) +for details) specifies a single socket only\&. If this option is set standard input will be connected to the socket the service was activated from, which is primarily useful for compatibility with daemons designed for use with the traditional +\fBinetd\fR(8) +daemon\&. This setting defaults to +\fBnull\fR\&. +.RE +.PP +\fIStandardOutput=\fR +.RS 4 +Controls where file descriptor 1 (STDOUT) of the executed processes is connected to\&. Takes one of +\fBinherit\fR, +\fBnull\fR, +\fBtty\fR, +\fBsyslog\fR, +\fBkmsg\fR, +\fBjournal\fR, +\fBsyslog+console\fR, +\fBkmsg+console\fR, +\fBjournal+console\fR +or +\fBsocket\fR\&. If set to +\fBinherit\fR +the file descriptor of standard input is duplicated for standard output\&. If set to +\fBnull\fR +standard output will be connected to +/dev/null, i\&.e\&. everything written to it will be lost\&. If set to +\fBtty\fR +standard output will be connected to a tty (as configured via +\fITTYPath=\fR, see below)\&. If the TTY is used for output only the executed process will not become the controlling process of the terminal, and will not fail or wait for other processes to release the terminal\&. +\fBsyslog\fR +connects standard output to the +\fBsyslog\fR(3) +system syslog service\&. +\fBkmsg\fR +connects it with the kernel log buffer which is accessible via +\fBdmesg\fR(1)\&. +\fBjournal\fR +connects it with the journal which is accessible via +\fBsystemd-journalctl\fR(1) +(Note that everything that is written to syslog or kmsg is implicitly stored in the journal as well, those options are hence supersets of this one)\&. +\fBsyslog+console\fR, +\fBjournal+console\fR +and +\fBkmsg+console\fR +work similarly but copy the output to the system console as well\&. +\fBsocket\fR +connects standard output to a socket from socket activation, semantics are similar to the respective option of +\fIStandardInput=\fR\&. This setting defaults to the value set with +\fBDefaultStandardOutput=\fR +in +\fBsystemd.conf\fR(5), which defaults to +\fBjournal\fR\&. +.RE +.PP +\fIStandardError=\fR +.RS 4 +Controls where file descriptor 2 (STDERR) of the executed processes is connected to\&. The available options are identical to those of +\fIStandardOutput=\fR, with one exception: if set to +\fBinherit\fR +the file descriptor used for standard output is duplicated for standard error\&. This setting defaults to the value set with +\fBDefaultStandardError=\fR +in +\fBsystemd.conf\fR(5), which defaults to +\fBinherit\fR\&. +.RE +.PP +\fITTYPath=\fR +.RS 4 +Sets the terminal device node to use if standard input, output or stderr are connected to a TTY (see above)\&. Defaults to +/dev/console\&. +.RE +.PP +\fITTYReset=\fR +.RS 4 +Reset the terminal device specified with +\fITTYPath=\fR +before and after execution\&. Defaults to +no\&. +.RE +.PP +\fITTYVHangup=\fR +.RS 4 +Disconnect all clients which have opened the terminal device specified with +\fITTYPath=\fR +before and after execution\&. Defaults to +no\&. +.RE +.PP +\fITTYVTDisallocate=\fR +.RS 4 +If the the terminal device specified with +\fITTYPath=\fR +is a virtual console terminal try to deallocate the TTY before and after execution\&. This ensures that the screen and scrollback buffer is cleared\&. Defaults to +no\&. +.RE +.PP +\fISyslogIdentifier=\fR +.RS 4 +Sets the process name to prefix log lines sent to syslog or the kernel log buffer with\&. If not set defaults to the process name of the executed process\&. This option is only useful when +\fIStandardOutput=\fR +or +\fIStandardError=\fR +are set to +\fBsyslog\fR +or +\fBkmsg\fR\&. +.RE +.PP +\fISyslogFacility=\fR +.RS 4 +Sets the syslog facility to use when logging to syslog\&. One of +\fBkern\fR, +\fBuser\fR, +\fBmail\fR, +\fBdaemon\fR, +\fBauth\fR, +\fBsyslog\fR, +\fBlpr\fR, +\fBnews\fR, +\fBuucp\fR, +\fBcron\fR, +\fBauthpriv\fR, +\fBftp\fR, +\fBlocal0\fR, +\fBlocal1\fR, +\fBlocal2\fR, +\fBlocal3\fR, +\fBlocal4\fR, +\fBlocal5\fR, +\fBlocal6\fR +or +\fBlocal7\fR\&. See +\fBsyslog\fR(3) +for details\&. This option is only useful when +\fIStandardOutput=\fR +or +\fIStandardError=\fR +are set to +\fBsyslog\fR\&. Defaults to +\fBdaemon\fR\&. +.RE +.PP +\fISyslogLevel=\fR +.RS 4 +Default syslog level to use when logging to syslog or the kernel log buffer\&. One of +\fBemerg\fR, +\fBalert\fR, +\fBcrit\fR, +\fBerr\fR, +\fBwarning\fR, +\fBnotice\fR, +\fBinfo\fR, +\fBdebug\fR\&. See +\fBsyslog\fR(3) +for details\&. This option is only useful when +\fIStandardOutput=\fR +or +\fIStandardError=\fR +are set to +\fBsyslog\fR +or +\fBkmsg\fR\&. Note that individual lines output by the daemon might be prefixed with a different log level which can be used to override the default log level specified here\&. The interpretation of these prefixes may be disabled with +\fISyslogLevelPrefix=\fR, see below\&. For details see +\fBsd-daemon\fR(7)\&. Defaults to +\fBinfo\fR\&. +.RE +.PP +\fISyslogLevelPrefix=\fR +.RS 4 +Takes a boolean argument\&. If true and +\fIStandardOutput=\fR +or +\fIStandardError=\fR +are set to +\fBsyslog\fR +or +\fBkmsg\fR +log lines written by the executed process that are prefixed with a log level will be passed on to syslog with this log level set but the prefix removed\&. If set to false, the interpretation of these prefixes is disabled and the logged lines are passed on as\-is\&. For details about this prefixing see +\fBsd-daemon\fR(7)\&. Defaults to true\&. +.RE +.PP +\fITimerSlackNSec=\fR +.RS 4 +Sets the timer slack in nanoseconds for the executed processes\&. The timer slack controls the accuracy of wake\-ups triggered by timers\&. See +\fBprctl\fR(2) +for more information\&. Note that in contrast to most other time span definitions this parameter takes an integer value in nano\-seconds and does not understand any other units\&. +.RE +.PP +\fILimitCPU=\fR, \fILimitFSIZE=\fR, \fILimitDATA=\fR, \fILimitSTACK=\fR, \fILimitCORE=\fR, \fILimitRSS=\fR, \fILimitNOFILE=\fR, \fILimitAS=\fR, \fILimitNPROC=\fR, \fILimitMEMLOCK=\fR, \fILimitLOCKS=\fR, \fILimitSIGPENDING=\fR, \fILimitMSGQUEUE=\fR, \fILimitNICE=\fR, \fILimitRTPRIO=\fR, \fILimitRTTIME=\fR +.RS 4 +These settings control various resource limits for executed processes\&. See +\fBsetrlimit\fR(2) +for details\&. Use the string +\fIinfinity\fR +to configure no limit on a specific resource\&. +.RE +.PP +\fIPAMName=\fR +.RS 4 +Sets the PAM service name to set up a session as\&. If set the executed process will be registered as a PAM session under the specified service name\&. This is only useful in conjunction with the +\fIUser=\fR +setting\&. If not set no PAM session will be opened for the executed processes\&. See +\fBpam\fR(8) +for details\&. +.RE +.PP +\fITCPWrapName=\fR +.RS 4 +If this is a socket\-activated service this sets the tcpwrap service name to check the permission for the current connection with\&. This is only useful in conjunction with socket\-activated services, and stream sockets (TCP) in particular\&. It has no effect on other socket types (e\&.g\&. datagram/UDP) and on processes unrelated to socket\-based activation\&. If the tcpwrap verification fails daemon start\-up will fail and the connection is terminated\&. See +\fBtcpd\fR(8) +for details\&. Note that this option may be used to do access control checks only\&. Shell commands and commands described in +\fBhosts_options\fR(5) +are not supported\&. +.RE +.PP +\fICapabilityBoundingSet=\fR +.RS 4 +Controls which capabilities to include in the capability bounding set for the executed process\&. See +\fBcapabilities\fR(7) +for details\&. Takes a whitespace separated list of capability names as read by +\fBcap_from_name\fR(3)\&. Capabilities listed will be included in the bounding set, all others are removed\&. If the list of capabilities is prefixed with ~ all but the listed capabilities will be included, the effect of the assignment inverted\&. Note that this option does not actually set or unset any capabilities in the effective, permitted or inherited capability sets\&. That\*(Aqs what +\fICapabilities=\fR +is for\&. If this option is not used the capability bounding set is not modified on process execution, hence no limits on the capabilities of the process are enforced\&. +.RE +.PP +\fISecureBits=\fR +.RS 4 +Controls the secure bits set for the executed process\&. See +\fBcapabilities\fR(7) +for details\&. Takes a list of strings: +\fBkeep\-caps\fR, +\fBkeep\-caps\-locked\fR, +\fBno\-setuid\-fixup\fR, +\fBno\-setuid\-fixup\-locked\fR, +\fBnoroot\fR +and/or +\fBnoroot\-locked\fR\&. +.RE +.PP +\fICapabilities=\fR +.RS 4 +Controls the +\fBcapabilities\fR(7) +set for the executed process\&. Take a capability string describing the effective, permitted and inherited capability sets as documented in +\fBcap_from_text\fR(3)\&. Note that these capability sets are usually influenced by the capabilities attached to the executed file\&. Due to that +\fICapabilityBoundingSet=\fR +is probably the much more useful setting\&. +.RE +.PP +\fIControlGroup=\fR +.RS 4 +Controls the control groups the executed processes shall be made members of\&. Takes a space\-separated list of cgroup identifiers\&. A cgroup identifier has a format like +cpu:/foo/bar, where "cpu" identifies the kernel control group controller used, and +/foo/bar +is the control group path\&. The controller name and ":" may be omitted in which case the named systemd control group hierarchy is implied\&. Alternatively, the path and ":" may be omitted, in which case the default control group path for this unit is implied\&. This option may be used to place executed processes in arbitrary groups in arbitrary hierarchies \-\- which can be configured externally with additional execution limits\&. By default systemd will place all executed processes in separate per\-unit control groups (named after the unit) in the systemd named hierarchy\&. Since every process can be in one group per hierarchy only overriding the control group path in the named systemd hierarchy will disable automatic placement in the default group\&. This option is primarily intended to place executed processes in specific paths in specific kernel controller hierarchies\&. It is however not recommended to manipulate the service control group path in the systemd named hierarchy\&. For details about control groups see +\m[blue]\fBcgroups\&.txt\fR\m[]\&\s-2\u[2]\d\s+2\&. +.RE +.PP +\fIControlGroupModify=\fR +.RS 4 +Takes a boolean argument\&. If true, the control groups created for this unit will be owned by the user specified with +\fIUser=\fR +(and the appropriate group), and he/she can create subgroups as well as add processes to the group\&. +.RE +.PP +\fIControlGroupPersistent=\fR +.RS 4 +Takes a boolean argument\&. If true, the control groups created for this unit will be marked to be persistent, i\&.e\&. systemd will not remove them when stopping the unit\&. The default is false, meaning that the control groups will be removed when the unit is stopped\&. For details about the semantics of this logic see +\m[blue]\fBPaxControlGroups\fR\m[]\&\s-2\u[3]\d\s+2\&. +.RE +.PP +\fIControlGroupAttribute=\fR +.RS 4 +Set a specific control group attribute for executed processes, and (if needed) add the the executed processes to a cgroup in the hierarchy of the controller the attribute belongs to\&. Takes two space\-separated arguments: the attribute name (syntax is +cpu\&.shares +where +cpu +refers to a specific controller and +shares +to the attribute name), and the attribute value\&. Example: +ControlGroupAttribute=cpu\&.shares 512\&. If this option is used for an attribute that belongs to a kernel controller hierarchy the unit is not already configured to be added to (for example via the +ControlGroup= +option) then the unit will be added to the controller and the default unit cgroup path is implied\&. Thus, using +\fIControlGroupAttribute=\fR +is in most case sufficient to make use of control group enforcements, explicit +\fIControlGroup=\fR +are only necessary in case the implied default control group path for a service is not desirable\&. For details about control group attributes see +\m[blue]\fBcgroups\&.txt\fR\m[]\&\s-2\u[2]\d\s+2\&. This option may appear more than once, in order to set multiple control group attributes\&. +.RE +.PP +\fICPUShares=\fR +.RS 4 +Assign the specified overall CPU time shares to the processes executed\&. Takes an integer value\&. This controls the +cpu\&.shares +control group attribute, which defaults to 1024\&. For details about this control group attribute see +\m[blue]\fBsched\-design\-CFS\&.txt\fR\m[]\&\s-2\u[4]\d\s+2\&. +.RE +.PP +\fIMemoryLimit=\fR, \fIMemorySoftLimit=\fR +.RS 4 +Limit the overall memory usage of the executed processes to a certain size\&. Takes a memory size in bytes\&. If the value is suffixed with K, M, G or T the specified memory size is parsed as Kilobytes, Megabytes, Gigabytes, resp\&. Terabytes (to the base 1024)\&. This controls the +memory\&.limit_in_bytes +and +memory\&.soft_limit_in_bytes +control group attributes\&. For details about these control group attributes see +\m[blue]\fBmemory\&.txt\fR\m[]\&\s-2\u[5]\d\s+2\&. +.RE +.PP +\fIDeviceAllow=\fR, \fIDeviceDeny=\fR +.RS 4 +Control access to specific device nodes by the executed processes\&. Takes two space separated strings: a device node path (such as +/dev/null) followed by a combination of r, w, m to control reading, writing resp\&. creating of the specific device node by the unit\&. This controls the +devices\&.allow +and +devices\&.deny +control group attributes\&. For details about these control group attributes see +\m[blue]\fBdevices\&.txt\fR\m[]\&\s-2\u[6]\d\s+2\&. +.RE +.PP +\fIBlockIOWeight=\fR +.RS 4 +Set the default or per\-device overall block IO weight value for the executed processes\&. Takes either a single weight value (between 10 and 1000) to set the default block IO weight, or a space separated pair of a file path and a weight value to specify the device specific weight value (Example: "/dev/sda 500")\&. The file path may be specified as path to a block device node or as any other file in which case the backing block device of the file system of the file is determined\&. This controls the +blkio\&.weight +and +blkio\&.weight_device +control group attributes, which default to 1000\&. Use this option multiple times to set weights for multiple devices\&. For details about these control group attributes see +\m[blue]\fBblkio\-controller\&.txt\fR\m[]\&\s-2\u[7]\d\s+2\&. +.RE +.PP +\fIBlockIOReadBandwidth=\fR, \fIBlockIOWriteBandwidth=\fR +.RS 4 +Set the per\-device overall block IO bandwith limit for the executed processes\&. Takes a space separated pair of a file path and a bandwith value (in bytes per second) to specify the device specific bandwidth\&. The file path may be specified as path to a block device node or as any other file in which case the backing block device of the file system of the file is determined\&. If the bandwith is suffixed with K, M, G, or T the specified bandwith is parsed as Kilobytes, Megabytes, Gigabytes, resp\&. Terabytes (Example: "/dev/disk/by\-path/pci\-0000:00:1f\&.2\-scsi\-0:0:0:0 5M")\&. This controls the +blkio\&.read_bps_device +and +blkio\&.write_bps_device +control group attributes\&. Use this option multiple times to set bandwith limits for multiple devices\&. For details about these control group attributes see +\m[blue]\fBblkio\-controller\&.txt\fR\m[]\&\s-2\u[7]\d\s+2\&. +.RE +.PP +\fIReadWriteDirectories=\fR, \fIReadOnlyDirectories=\fR, \fIInaccessibleDirectories=\fR +.RS 4 +Sets up a new file\-system name space for executed processes\&. These options may be used to limit access a process might have to the main file\-system hierarchy\&. Each setting takes a space\-separated list of absolute directory paths\&. Directories listed in +\fIReadWriteDirectories=\fR +are accessible from within the namespace with the same access rights as from outside\&. Directories listed in +\fIReadOnlyDirectories=\fR +are accessible for reading only, writing will be refused even if the usual file access controls would permit this\&. Directories listed in +\fIInaccessibleDirectories=\fR +will be made inaccessible for processes inside the namespace\&. Note that restricting access with these options does not extend to submounts of a directory\&. You must list submounts separately in these settings to ensure the same limited access\&. These options may be specified more than once in which case all directories listed will have limited access from within the namespace\&. +.RE +.PP +\fIPrivateTmp=\fR +.RS 4 +Takes a boolean argument\&. If true sets up a new file system namespace for the executed processes and mounts a private +/tmp +directory inside it, that is not shared by processes outside of the namespace\&. This is useful to secure access to temporary files of the process, but makes sharing between processes via +/tmp +impossible\&. Defaults to false\&. +.RE +.PP +\fIPrivateNetwork=\fR +.RS 4 +Takes a boolean argument\&. If true sets up a new network namespace for the executed processes and configures only the loopback network device +lo +inside it\&. No other network devices will be available to the executed process\&. This is useful to securely turn off network access by the executed process\&. Defaults to false\&. +.RE +.PP +\fIMountFlags=\fR +.RS 4 +Takes a mount propagation flag: +\fBshared\fR, +\fBslave\fR +or +\fBprivate\fR, which control whether namespaces set up with +\fIReadWriteDirectories=\fR, +\fIReadOnlyDirectories=\fR +and +\fIInaccessibleDirectories=\fR +receive or propagate new mounts from/to the main namespace\&. See +\fBmount\fR(1) +for details\&. Defaults to +\fBshared\fR, i\&.e\&. the new namespace will both receive new mount points from the main namespace as well as propagate new mounts to it\&. +.RE +.PP +\fIUtmpIdentifier=\fR +.RS 4 +Takes a a four character identifier string for an utmp/wtmp entry for this service\&. This should only be set for services such as +\fBgetty\fR +implementations where utmp/wtmp entries must be created and cleared before and after execution\&. If the configured string is longer than four characters it is truncated and the terminal four characters are used\&. This setting interprets %I style string replacements\&. This setting is unset by default, i\&.e\&. no utmp/wtmp entries are created or cleaned up for this service\&. +.RE +.PP +\fIIgnoreSIGPIPE=\fR +.RS 4 +Takes a boolean argument\&. If true causes SIGPIPE to be ignored in the executed process\&. Defaults to true, since SIGPIPE generally is useful only in shell pipelines\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(8), +\fBsystemd.unit\fR(5), +\fBsystemd.service\fR(5), +\fBsystemd.socket\fR(5), +\fBsystemd.swap\fR(5), +\fBsystemd.mount\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE +.SH "NOTES" +.IP " 1." 4 +proc.txt +.RS 4 +\%http://www.kernel.org/doc/Documentation/filesystems/proc.txt +.RE +.IP " 2." 4 +cgroups.txt +.RS 4 +\%http://www.kernel.org/doc/Documentation/cgroups/cgroups.txt +.RE +.IP " 3." 4 +PaxControlGroups +.RS 4 +\%http://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups +.RE +.IP " 4." 4 +sched-design-CFS.txt +.RS 4 +\%http://www.kernel.org/doc/Documentation/scheduler/sched-design-CFS.txt +.RE +.IP " 5." 4 +memory.txt +.RS 4 +\%http://www.kernel.org/doc/Documentation/cgroups/memory.txt +.RE +.IP " 6." 4 +devices.txt +.RS 4 +\%http://www.kernel.org/doc/Documentation/cgroups/devices.txt +.RE +.IP " 7." 4 +blkio-controller.txt +.RS 4 +\%http://www.kernel.org/doc/Documentation/cgroups/blkio-controller.txt +.RE diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml new file mode 100644 index 0000000..ac0f89f --- /dev/null +++ b/man/systemd.exec.xml @@ -0,0 +1,1105 @@ + + + + + + + + + systemd.exec + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.exec + 5 + + + + systemd.exec + systemd execution environment configuration + + + + systemd.service, + systemd.socket, + systemd.mount, + systemd.swap + + + + Description + + Unit configuration files for services, sockets, + mount points and swap devices share a subset of + configuration options which define the execution + environment of spawned processes. + + This man page lists the configuration options + shared by these four unit types. See + systemd.unit5 + for the common options of all unit configuration + files, and + systemd.service5, + systemd.socket5, + systemd.swap5 + and + systemd.mount5 + for more information on the specific unit + configuration files. The execution specific + configuration options are configured in the [Service], + [Socket], [Mount] resp. [Swap] section, depending on the unit + type. + + + + Options + + + + + WorkingDirectory= + + Takes an absolute + directory path. Sets the working + directory for executed + processes. + + + + RootDirectory= + + Takes an absolute + directory path. Sets the root + directory for executed processes, with + the + chroot2 + system call. If this is used it must + be ensured that the process and all + its auxiliary files are available in + the chroot() + jail. + + + + User= + Group= + + Sets the Unix user + resp. group the processes are executed + as. Takes a single user resp. group + name or ID as argument. If no group is + set the default group of the user is + chosen. + + + + SupplementaryGroups= + + Sets the supplementary + Unix groups the processes are executed + as. This takes a space separated list + of group names or IDs. This option may + be specified more than once in which + case all listed groups are set as + supplementary groups. This option does + not override but extends the list of + supplementary groups configured in the + system group database for the + user. + + + + Nice= + + Sets the default nice + level (scheduling priority) for + executed processes. Takes an integer + between -20 (highest priority) and 19 + (lowest priority). See + setpriority2 + for details. + + + + OOMScoreAdjust= + + Sets the adjustment + level for the Out-Of-Memory killer for + executed processes. Takes an integer + between -1000 (to disable OOM killing + for this process) and 1000 (to make + killing of this process under memory + pressure very likely). See proc.txt + for details. + + + + IOSchedulingClass= + + Sets the IO scheduling + class for executed processes. Takes an + integer between 0 and 3 or one of the + strings , + , + or + . See + ioprio_set2 + for details. + + + + IOSchedulingPriority= + + Sets the IO scheduling + priority for executed processes. Takes + an integer between 0 (highest + priority) and 7 (lowest priority). The + available priorities depend on the + selected IO scheduling class (see + above). See + ioprio_set2 + for details. + + + + CPUSchedulingPolicy= + + Sets the CPU + scheduling policy for executed + processes. Takes one of + , + , + , + or + . See + sched_setscheduler2 + for details. + + + + CPUSchedulingPriority= + + Sets the CPU + scheduling priority for executed + processes. Takes an integer between 1 + (lowest priority) and 99 (highest + priority). The available priority + range depends on the selected CPU + scheduling policy (see above). See + sched_setscheduler2 + for details. + + + + CPUSchedulingResetOnFork= + + Takes a boolean + argument. If true elevated CPU + scheduling priorities and policies + will be reset when the executed + processes fork, and can hence not leak + into child processes. See + sched_setscheduler2 + for details. Defaults to false. + + + + CPUAffinity= + + Controls the CPU + affinity of the executed + processes. Takes a space-separated + list of CPU indexes. See + sched_setaffinity2 + for details. + + + + UMask= + + Controls the file mode + creation mask. Takes an access mode in + octal notation. See + umask2 + for details. Defaults to + 0022. + + + + Environment= + + Sets environment + variables for executed + processes. Takes a space-separated + list of variable assignments. This + option may be specified more than once + in which case all listed variables + will be set. If the same variable is + set twice the later setting will + override the earlier setting. See + environ7 + for details. + + + EnvironmentFile= + Similar to + Environment= but + reads the environment variables from a + text file. The text file should + contain new-line separated variable + assignments. Empty lines and lines + starting with ; or # will be ignored, + which may be used for commenting. The + parser strips leading and + trailing whitespace from the values + of assignments, unless you use + double quotes ("). + The + argument passed should be an absolute + file name, optionally prefixed with + "-", which indicates that if the file + does not exist it won't be read and no + error or warning message is + logged. The files listed with this + directive will be read shortly before + the process is executed. Settings from + these files override settings made + with + Environment=. If + the same variable is set twice from + these files the files will be read in + the order they are specified and the + later setting will override the + earlier setting. + + + + StandardInput= + Controls where file + descriptor 0 (STDIN) of the executed + processes is connected to. Takes one + of , + , + , + or + . If + is selected + standard input will be connected to + /dev/null, + i.e. all read attempts by the process + will result in immediate EOF. If + is selected + standard input is connected to a TTY + (as configured by + TTYPath=, see + below) and the executed process + becomes the controlling process of the + terminal. If the terminal is already + being controlled by another process the + executed process waits until the current + controlling process releases the + terminal. + + is similar to , + but the executed process is forcefully + and immediately made the controlling + process of the terminal, potentially + removing previous controlling + processes from the + terminal. is + similar to but if + the terminal already has a controlling + process start-up of the executed + process fails. The + option is only + valid in socket-activated services, + and only when the socket configuration + file (see + systemd.socket5 + for details) specifies a single socket + only. If this option is set standard + input will be connected to the socket + the service was activated from, which + is primarily useful for compatibility + with daemons designed for use with the + traditional + inetd8 + daemon. This setting defaults to + . + + + StandardOutput= + Controls where file + descriptor 1 (STDOUT) of the executed + processes is connected to. Takes one + of , + , + , + , + , + , + , + , + or + . If set to + the file + descriptor of standard input is + duplicated for standard output. If set + to standard + output will be connected to + /dev/null, + i.e. everything written to it will be + lost. If set to + standard output will be connected to a + tty (as configured via + TTYPath=, see + below). If the TTY is used for output + only the executed process will not + become the controlling process of the + terminal, and will not fail or wait + for other processes to release the + terminal. + connects standard output to the + syslog3 + system syslog + service. + connects it with the kernel log buffer + which is accessible via + dmesg1. + connects it with the journal which is + accessible via + systemd-journalctl1 + (Note that everything that is written + to syslog or kmsg is implicitly stored + in the journal as well, those options + are hence supersets of this + one). , + and + work + similarly but copy the output to the + system console as + well. connects + standard output to a socket from + socket activation, semantics are + similar to the respective option of + StandardInput=. + This setting defaults to the value set + with + + in + systemd.conf5, + which defaults to + . + + + StandardError= + Controls where file + descriptor 2 (STDERR) of the executed + processes is connected to. The + available options are identical to + those of + StandardOutput=, + with one exception: if set to + the file + descriptor used for standard output is + duplicated for standard error. This + setting defaults to the value set with + + in + systemd.conf5, + which defaults to + . + + + TTYPath= + Sets the terminal + device node to use if standard input, + output or stderr are connected to a + TTY (see above). Defaults to + /dev/console. + + + TTYReset= + Reset the terminal + device specified with + TTYPath= before and + after execution. Defaults to + no. + + + TTYVHangup= + Disconnect all clients + which have opened the terminal device + specified with + TTYPath= + before and after execution. Defaults + to + no. + + + TTYVTDisallocate= + If the the terminal + device specified with + TTYPath= is a + virtual console terminal try to + deallocate the TTY before and after + execution. This ensures that the + screen and scrollback buffer is + cleared. Defaults to + no. + + + SyslogIdentifier= + Sets the process name + to prefix log lines sent to syslog or + the kernel log buffer with. If not set + defaults to the process name of the + executed process. This option is only + useful when + StandardOutput= or + StandardError= are + set to or + . + + + SyslogFacility= + Sets the syslog + facility to use when logging to + syslog. One of , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + or + . See + syslog3 + for details. This option is only + useful when + StandardOutput= or + StandardError= are + set to . + Defaults to + . + + + SyslogLevel= + Default syslog level + to use when logging to syslog or the + kernel log buffer. One of + , + , + , + , + , + , + , + . See + syslog3 + for details. This option is only + useful when + StandardOutput= or + StandardError= are + set to or + . Note that + individual lines output by the daemon + might be prefixed with a different log + level which can be used to override + the default log level specified + here. The interpretation of these + prefixes may be disabled with + SyslogLevelPrefix=, + see below. For details see + sd-daemon7. + + Defaults to + . + + + + SyslogLevelPrefix= + Takes a boolean + argument. If true and + StandardOutput= or + StandardError= are + set to or + log lines + written by the executed process that + are prefixed with a log level will be + passed on to syslog with this log + level set but the prefix removed. If + set to false, the interpretation of + these prefixes is disabled and the + logged lines are passed on as-is. For + details about this prefixing see + sd-daemon7. + Defaults to true. + + + + TimerSlackNSec= + Sets the timer slack + in nanoseconds for the executed + processes. The timer slack controls the + accuracy of wake-ups triggered by + timers. See + prctl2 + for more information. Note that in + contrast to most other time span + definitions this parameter takes an + integer value in nano-seconds and does + not understand any other + units. + + + + LimitCPU= + LimitFSIZE= + LimitDATA= + LimitSTACK= + LimitCORE= + LimitRSS= + LimitNOFILE= + LimitAS= + LimitNPROC= + LimitMEMLOCK= + LimitLOCKS= + LimitSIGPENDING= + LimitMSGQUEUE= + LimitNICE= + LimitRTPRIO= + LimitRTTIME= + These settings control + various resource limits for executed + processes. See + setrlimit2 + for details. Use the string + infinity to + configure no limit on a specific + resource. + + + + PAMName= + Sets the PAM service + name to set up a session as. If set + the executed process will be + registered as a PAM session under the + specified service name. This is only + useful in conjunction with the + User= setting. If + not set no PAM session will be opened + for the executed processes. See + pam8 + for details. + + + + TCPWrapName= + If this is a + socket-activated service this sets the + tcpwrap service name to check the + permission for the current connection + with. This is only useful in + conjunction with socket-activated + services, and stream sockets (TCP) in + particular. It has no effect on other + socket types (e.g. datagram/UDP) and + on processes unrelated to socket-based + activation. If the tcpwrap + verification fails daemon start-up + will fail and the connection is + terminated. See + tcpd8 + for details. Note that this option may + be used to do access control checks + only. Shell commands and commands + described in + hosts_options5 + are not supported. + + + + CapabilityBoundingSet= + + Controls which + capabilities to include in the + capability bounding set for the + executed process. See + capabilities7 + for details. Takes a whitespace + separated list of capability names as + read by + cap_from_name3. + Capabilities listed will be included + in the bounding set, all others are + removed. If the list of capabilities + is prefixed with ~ all but the listed + capabilities will be included, the + effect of the assignment + inverted. Note that this option does + not actually set or unset any + capabilities in the effective, + permitted or inherited capability + sets. That's what + Capabilities= is + for. If this option is not used the + capability bounding set is not + modified on process execution, hence + no limits on the capabilities of the + process are enforced. + + + + SecureBits= + Controls the secure + bits set for the executed process. See + capabilities7 + for details. Takes a list of strings: + , + , + , + , + and/or + . + + + + + Capabilities= + Controls the + capabilities7 + set for the executed process. Take a + capability string describing the + effective, permitted and inherited + capability sets as documented in + cap_from_text3. + Note that these capability sets are + usually influenced by the capabilities + attached to the executed file. Due to + that + CapabilityBoundingSet= + is probably the much more useful + setting. + + + + ControlGroup= + + Controls the control + groups the executed processes shall be + made members of. Takes a + space-separated list of cgroup + identifiers. A cgroup identifier has a + format like + cpu:/foo/bar, + where "cpu" identifies the kernel + control group controller used, and + /foo/bar is the + control group path. The controller + name and ":" may be omitted in which + case the named systemd control group + hierarchy is implied. Alternatively, + the path and ":" may be omitted, in + which case the default control group + path for this unit is implied. This + option may be used to place executed + processes in arbitrary groups in + arbitrary hierarchies -- which can be + configured externally with additional + execution limits. By default systemd + will place all executed processes in + separate per-unit control groups + (named after the unit) in the systemd + named hierarchy. Since every process + can be in one group per hierarchy only + overriding the control group path in + the named systemd hierarchy will + disable automatic placement in the + default group. This option is + primarily intended to place executed + processes in specific paths in + specific kernel controller + hierarchies. It is however not + recommended to manipulate the service + control group path in the systemd + named hierarchy. For details about + control groups see cgroups.txt. + + + + ControlGroupModify= + Takes a boolean + argument. If true, the control groups + created for this unit will be owned by + the user specified with + User= (and the + appropriate group), and he/she can create + subgroups as well as add processes to + the group. + + + + ControlGroupPersistent= + Takes a boolean + argument. If true, the control groups + created for this unit will be marked + to be persistent, i.e. systemd will + not remove them when stopping the + unit. The default is false, meaning + that the control groups will be + removed when the unit is stopped. For + details about the semantics of this + logic see PaxControlGroups. + + + + ControlGroupAttribute= + + Set a specific control + group attribute for executed + processes, and (if needed) add the the + executed processes to a cgroup in the + hierarchy of the controller the + attribute belongs to. Takes two + space-separated arguments: the + attribute name (syntax is + cpu.shares where + cpu refers to a + specific controller and + shares to the + attribute name), and the attribute + value. Example: + ControlGroupAttribute=cpu.shares + 512. If this option is used + for an attribute that belongs to a + kernel controller hierarchy the unit + is not already configured to be added + to (for example via the + ControlGroup= + option) then the unit will be added to + the controller and the default unit + cgroup path is implied. Thus, using + ControlGroupAttribute= + is in most case sufficient to make use + of control group enforcements, + explicit + ControlGroup= are + only necessary in case the implied + default control group path for a + service is not desirable. For details + about control group attributes see + cgroups.txt. This + option may appear more than once, in + order to set multiple control group + attributes. + + + + CPUShares= + + Assign the specified + overall CPU time shares to the + processes executed. Takes an integer + value. This controls the + cpu.shares control + group attribute, which defaults to + 1024. For details about this control + group attribute see sched-design-CFS.txt. + + + + MemoryLimit= + MemorySoftLimit= + + Limit the overall memory usage + of the executed processes to a certain + size. Takes a memory size in bytes. If + the value is suffixed with K, M, G or + T the specified memory size is parsed + as Kilobytes, Megabytes, Gigabytes, + resp. Terabytes (to the base + 1024). This controls the + memory.limit_in_bytes + and + memory.soft_limit_in_bytes + control group attributes. For details + about these control group attributes + see memory.txt. + + + + DeviceAllow= + DeviceDeny= + + Control access to + specific device nodes by the executed processes. Takes two + space separated strings: a device node + path (such as + /dev/null) + followed by a combination of r, w, m + to control reading, writing resp. + creating of the specific device node + by the unit. This controls the + devices.allow + and + devices.deny + control group attributes. For details + about these control group attributes + see devices.txt. + + + + BlockIOWeight= + + Set the default or + per-device overall block IO weight + value for the executed + processes. Takes either a single + weight value (between 10 and 1000) to + set the default block IO weight, or a + space separated pair of a file path + and a weight value to specify the + device specific weight value (Example: + "/dev/sda 500"). The file path may be + specified as path to a block device + node or as any other file in which + case the backing block device of the + file system of the file is + determined. This controls the + blkio.weight and + blkio.weight_device + control group attributes, which + default to 1000. Use this option + multiple times to set weights for + multiple devices. For details about + these control group attributes see + blkio-controller.txt. + + + + BlockIOReadBandwidth= + BlockIOWriteBandwidth= + + Set the per-device + overall block IO bandwith limit for + the executed processes. Takes a space + separated pair of a file path and a + bandwith value (in bytes per second) + to specify the device specific + bandwidth. The file path may be + specified as path to a block device + node or as any other file in which + case the backing block device of the + file system of the file is determined. + If the bandwith is suffixed with K, M, + G, or T the specified bandwith is + parsed as Kilobytes, Megabytes, + Gigabytes, resp. Terabytes (Example: + "/dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0 + 5M"). This controls the + blkio.read_bps_device + and + blkio.write_bps_device + control group attributes. Use this + option multiple times to set bandwith + limits for multiple devices. For + details about these control group + attributes see blkio-controller.txt. + + + + ReadWriteDirectories= + ReadOnlyDirectories= + InaccessibleDirectories= + + Sets up a new + file-system name space for executed + processes. These options may be used + to limit access a process might have + to the main file-system + hierarchy. Each setting takes a + space-separated list of absolute + directory paths. Directories listed in + ReadWriteDirectories= + are accessible from within the + namespace with the same access rights + as from outside. Directories listed in + ReadOnlyDirectories= + are accessible for reading only, + writing will be refused even if the + usual file access controls would + permit this. Directories listed in + InaccessibleDirectories= + will be made inaccessible for processes + inside the namespace. Note that + restricting access with these options + does not extend to submounts of a + directory. You must list submounts + separately in these settings to + ensure the same limited access. These + options may be specified more than + once in which case all directories + listed will have limited access from + within the + namespace. + + + + PrivateTmp= + + Takes a boolean + argument. If true sets up a new file + system namespace for the executed + processes and mounts a private + /tmp directory + inside it, that is not shared by + processes outside of the + namespace. This is useful to secure + access to temporary files of the + process, but makes sharing between + processes via + /tmp + impossible. Defaults to + false. + + + + PrivateNetwork= + + Takes a boolean + argument. If true sets up a new + network namespace for the executed + processes and configures only the + loopback network device + lo inside it. No + other network devices will be + available to the executed process. + This is useful to securely turn off + network access by the executed + process. Defaults to + false. + + + + MountFlags= + + Takes a mount + propagation flag: + , + or + , which + control whether namespaces set up with + ReadWriteDirectories=, + ReadOnlyDirectories= + and + InaccessibleDirectories= + receive or propagate new mounts + from/to the main namespace. See + mount1 + for details. Defaults to + , i.e. the new + namespace will both receive new mount + points from the main namespace as well + as propagate new mounts to + it. + + + + UtmpIdentifier= + + Takes a a four + character identifier string for an + utmp/wtmp entry for this service. This + should only be set for services such + as getty + implementations where utmp/wtmp + entries must be created and cleared + before and after execution. If the + configured string is longer than four + characters it is truncated and the + terminal four characters are + used. This setting interprets %I style + string replacements. This setting is + unset by default, i.e. no utmp/wtmp + entries are created or cleaned up for + this service. + + + + IgnoreSIGPIPE= + + Takes a boolean + argument. If true causes SIGPIPE to be + ignored in the executed + process. Defaults to true, since + SIGPIPE generally is useful only in + shell pipelines. + + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.service5, + systemd.socket5, + systemd.swap5, + systemd.mount5 + + + + diff --git a/man/systemd.mount.5 b/man/systemd.mount.5 new file mode 100644 index 0000000..c3d644b --- /dev/null +++ b/man/systemd.mount.5 @@ -0,0 +1,182 @@ +'\" t +.\" Title: systemd.mount +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd.mount +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\&.MOUNT" "5" "02/15/2012" "systemd" "systemd.mount" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd.mount \- systemd mount configuration files +.SH "SYNOPSIS" +.PP +systemd\&.mount +.SH "DESCRIPTION" +.PP +A unit configuration file whose name ends in +\&.mount +encodes information about a file system mount point controlled and supervised by systemd\&. +.PP +This man page lists the configuration options specific to this unit type\&. See +\fBsystemd.unit\fR(5) +for the common options of all unit configuration files\&. The common configuration items are configured in the generic [Unit] and [Install] sections\&. The mount specific configuration options are configured in the [Mount] section\&. +.PP +Additional options are listed in +\fBsystemd.exec\fR(5), which define the execution environment the +\fBmount\fR(8) +binary is executed in\&. +.PP +Mount units must be named after the mount point directories they control\&. Example: the mount point +/home/lennart +must be configured in a unit file +home\-lennart\&.mount\&. For details about the escaping logic used to convert a file system path to a unit name see +\fBsystemd.unit\fR(5)\&. +.PP +Optionally, a mount unit may be accompanied by an automount unit, to allow on\-demand or parallelized mounting\&. See +\fBsystemd.automount\fR(5)\&. +.PP +If an mount point is beneath another mount point in the file system hierarchy, a dependency between both units is created automatically\&. +.PP +Mount points created at runtime independent on unit files or +/etc/fstab +will be monitored by systemd and appear like any other mount unit in systemd\&. +.SH "/ETC/FSTAB" +.PP +Mount units may either be configured via unit files, or via +/etc/fstab +(see +\fBfstab\fR(5) +for details)\&. +.PP +When reading +/etc/fstab +a few special mount options are understood by systemd which influence how dependencies are created for mount points from +/etc/fstab\&. If +\fBMountAuto=yes\fR +is set in +system\&.conf +(which is the default), or if +\fBx\-systemd\&.mount\fR +is specified as mount option, then systemd will create a dependency of type +\fBWants\fR +from either +local\-fs\&.target +or +remote\-fs\&.target, depending whether the file system is local or remote\&. If +\fBx\-systemd\&.automount\fR +is set, an automount unit will be created for the file system\&. See +\fBsystemd.automount\fR(5) +for details\&. If +\fBx\-systemd\-device\-timeout=\fR +is specified it may be used to configure how long systemd should wait for a device to show up before giving up on an entry from +/etc/fstab\&. Specify a time in seconds or explicitly specifiy a unit as +s, +min, +h, +ms\&. +.PP +If a mount point is configured in both +/etc/fstab +and a unit file, the configuration in the latter takes precedence\&. +.SH "OPTIONS" +.PP +Mount files must include a [Mount] section, which carries information about the file system mount points it supervises\&. A number of options that may be used in this section are shared with other unit types\&. These options are documented in +\fBsystemd.exec\fR(5)\&. The options specific to the [Mount] section of mount units are the following: +.PP +\fIWhat=\fR +.RS 4 +Takes an absolute path of a device node, file or other resource to mount\&. See +\fBmount\fR(8) +for details\&. If this refers to a device node, a dependency on the respective device unit is automatically created\&. (See +\fBsystemd.device\fR(5) +for more information\&.) This option is mandatory\&. +.RE +.PP +\fIWhere=\fR +.RS 4 +Takes an absolute path of a directory of the mount point\&. If the mount point is not existing at time of mounting, it is created\&. This string must be reflected in the unit file name\&. (See above\&.) This option is mandatory\&. +.RE +.PP +\fIType=\fR +.RS 4 +Takes a string for the filesystem type\&. See +\fBmount\fR(8) +for details\&. This setting is optional\&. +.RE +.PP +\fIOptions=\fR +.RS 4 +Mount options to use when mounting\&. This takes a comma separated list of options\&. This setting is optional\&. +.RE +.PP +\fIDirectoryMode=\fR +.RS 4 +Directories of mount points (and any parent directories) are automatically created if needed\&. This option specifies the file system access mode used when creating these directories\&. Takes an access mode in octal notation\&. Defaults to 0755\&. +.RE +.PP +\fITimeoutSec=\fR +.RS 4 +Configures the time to wait for the mount command to finish\&. If a command does not exit within the configured time the mount will be considered failed and be shut down again\&. All commands still running will be terminated forcibly via SIGTERM, and after another delay of this time with SIGKILL\&. (See +\fBKillMode=\fR +below\&.) Takes a unit\-less value in seconds, or a time span value such as "5min 20s"\&. Pass 0 to disable the timeout logic\&. Defaults to 90s\&. +.RE +.PP +\fIKillMode=\fR +.RS 4 +Specifies how processes of this mount shall be killed\&. One of +\fBcontrol\-group\fR, +\fBprocess\fR, +\fBnone\fR\&. +.sp +This option is mostly equivalent to the +\fBKillMode=\fR +option of service files\&. See +\fBsystemd.service\fR(5) +for details\&. +.RE +.PP +\fIKillSignal=\fR +.RS 4 +Specifies which signal to use when killing a process of this mount\&. Defaults to SIGTERM\&. +.RE +.PP +\fISendSIGKILL=\fR +.RS 4 +Specifies whether to send SIGKILL to remaining processes after a timeout, if the normal shutdown procedure left processes of the mount around\&. Takes a boolean value\&. Defaults to "yes"\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(8), +\fBsystemd.unit\fR(5), +\fBsystemd.exec\fR(5), +\fBsystemd.device\fR(5), +\fBmount\fR(8) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml new file mode 100644 index 0000000..8f1cc51 --- /dev/null +++ b/man/systemd.mount.xml @@ -0,0 +1,278 @@ + + + + + + + + + systemd.mount + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.mount + 5 + + + + systemd.mount + systemd mount configuration files + + + + systemd.mount + + + + Description + + A unit configuration file whose name ends in + .mount encodes information about + a file system mount point controlled and supervised by + systemd. + + This man page lists the configuration options + specific to this unit type. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. The + mount specific configuration options are configured + in the [Mount] section. + + Additional options are listed in + systemd.exec5, + which define the execution environment the + mount8 + binary is executed in. + + Mount units must be named after the mount point + directories they control. Example: the mount point + /home/lennart must be configured + in a unit file + home-lennart.mount. For details + about the escaping logic used to convert a file system + path to a unit name see + systemd.unit5. + + Optionally, a mount unit may be accompanied by + an automount unit, to allow on-demand or parallelized + mounting. See + systemd.automount5. + + If an mount point is beneath another mount point + in the file system hierarchy, a dependency between both + units is created automatically. + + Mount points created at runtime independent on + unit files or /etc/fstab will be + monitored by systemd and appear like any other mount + unit in systemd. + + + + <filename>/etc/fstab</filename> + + Mount units may either be configured via unit + files, or via /etc/fstab (see + fstab5 + for details). + + When reading /etc/fstab a + few special mount options are understood by systemd + which influence how dependencies are created for mount + points from /etc/fstab. If + is set in + system.conf (which is the + default), or if is + specified as mount option, then systemd will create a + dependency of type from either + local-fs.target or + remote-fs.target, depending + whether the file system is local or remote. If + is set, an + automount unit will be created for the file + system. See + systemd.automount5 + for details. If + is + specified it may be used to configure how long systemd + should wait for a device to show up before giving up + on an entry from + /etc/fstab. Specify a time in + seconds or explicitly specifiy a unit as + s, min, + h, ms. + + If a mount point is configured in both + /etc/fstab and a unit file, the + configuration in the latter takes precedence. + + + + Options + + Mount files must include a [Mount] section, + which carries information about the file system mount points it + supervises. A number of options that may be used in + this section are shared with other unit types. These + options are documented in + systemd.exec5. The + options specific to the [Mount] section of mount + units are the following: + + + + + What= + Takes an absolute path + of a device node, file or other + resource to mount. See + mount8 + for details. If this refers to a + device node, a dependency on the + respective device unit is + automatically created. (See + systemd.device5 for more information.) + This option is + mandatory. + + + + Where= + Takes an absolute path + of a directory of the mount point. If + the mount point is not existing at + time of mounting, it is created. This + string must be reflected in the unit + file name. (See above.) This option is + mandatory. + + + + Type= + Takes a string for the + filesystem type. See + mount8 + for details. This setting is + optional. + + + + Options= + + Mount options to use + when mounting. This takes a comma + separated list of options. This + setting is optional. + + + + DirectoryMode= + Directories of mount + points (and any parent directories) + are automatically created if + needed. This option specifies the file + system access mode used when creating + these directories. Takes an access + mode in octal notation. Defaults to + 0755. + + + + TimeoutSec= + Configures the time to + wait for the mount command to + finish. If a command does not exit + within the configured time the mount + will be considered failed and be shut + down again. All commands still running + will be terminated forcibly via + SIGTERM, and after another delay of + this time with SIGKILL. (See + below.) + Takes a unit-less value in seconds, or + a time span value such as "5min + 20s". Pass 0 to disable the timeout + logic. Defaults to + 90s. + + + + KillMode= + Specifies how + processes of this mount shall be + killed. One of + , + , + . + + This option is mostly equivalent + to the + option of service files. See + systemd.service5 + for details. + + + + KillSignal= + Specifies which signal + to use when killing a process of this + mount. Defaults to SIGTERM. + + + + + SendSIGKILL= + Specifies whether to + send SIGKILL to remaining processes + after a timeout, if the normal + shutdown procedure left processes of + the mount around. Takes a boolean + value. Defaults to "yes". + + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.exec5, + systemd.device5, + mount8 + + + + diff --git a/man/systemd.path.5 b/man/systemd.path.5 new file mode 100644 index 0000000..b5df95f --- /dev/null +++ b/man/systemd.path.5 @@ -0,0 +1,131 @@ +'\" t +.\" Title: systemd.path +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd.path +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\&.PATH" "5" "02/15/2012" "systemd" "systemd.path" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd.path \- systemd path configuration files +.SH "SYNOPSIS" +.PP +systemd\&.path +.SH "DESCRIPTION" +.PP +A unit configuration file whose name ends in +\&.path +encodes information about a path monitored by systemd, for path\-based activation\&. +.PP +This man page lists the configuration options specific to this unit type\&. See +\fBsystemd.unit\fR(5) +for the common options of all unit configuration files\&. The common configuration items are configured in the generic [Unit] and [Install] sections\&. The path specific configuration options are configured in the [Path] section\&. +.PP +For each path file, a matching unit file must exist, describing the unit to activate when the path changes\&. By default, a service by the same name as the path (except for the suffix) is activated\&. Example: a path file +foo\&.path +activates a matching service +foo\&.service\&. The unit to activate may be controlled by +\fIUnit=\fR +(see below)\&. +.PP +Internally, path units use the +\fBinotify\fR(7) +API to monitor file systems\&. Due to that, it suffers by the same limitations as inotify, and for example cannot be used to monitor files or directories changed by other machines on remote NFS file systems\&. +.PP +If an path unit is beneath another mount point in the file system hierarchy, a dependency between both units is created automatically\&. +.PP +Unless +\fIDefaultDependencies=\fR +is set to +\fBfalse\fR, path units will implicitly have dependencies of type +\fIConflicts=\fR +and +\fIBefore=\fR +on +shutdown\&.target\&. These ensure that path units are terminated cleanly prior to system shutdown\&. Only path units involved with early boot or late system shutdown should disable this option\&. +.SH "OPTIONS" +.PP +Path files must include a [Path] section, which carries information about the path(s) it monitors\&. The options specific to the [Path] section of path units are the following: +.PP +\fIPathExists=\fR, \fIPathExistsGlob=\fR, \fIPathChanged=\fR, \fIPathModified=\fR, \fIDirectoryNotEmpty=\fR +.RS 4 +Defines paths to monitor for certain changes: +\fIPathExists=\fR +may be used to watch the mere existence of a file or directory\&. If the file specified exists the configured unit is activated\&. +\fIPathExistsGlob=\fR +works similar, but checks for the existance of at least one file matching the globbing pattern specified\&. +\fIPathChanged=\fR +may be used to watch a file or directory and activate the configured unit whenever it changes\&. It is not activated on every write to the watched file but it is activated if the file which was open for writing gets closed\&. +\fIPathModified=\fR +is similar, but additionally it is activated also on simple writes to the watched file\&. +\fIDirectoryNotEmpty=\fR +may be used to watch a directory and activate the configured unit whenever it contains at least one file\&. +.sp +The arguments of these directives must be absolute file system paths\&. +.sp +Multiple directives may be combined, of the same and of different types, to watch multiple paths\&. +.sp +If a path is already existing (in case of +\fIPathExists=\fR +and +\fIPathExistsGlob=\fR) or a directory already is not empty (in case of +\fIDirectoryNotEmpty=\fR) at the time the path unit is activated, then the configured unit is immediately activated as well\&. Something similar does not apply to +\fIPathChanged=\fR\&. +.RE +.PP +\fIUnit=\fR +.RS 4 +The unit to activate when any of the configured paths changes\&. The argument is a unit name, whose suffix is not +\&.path\&. If not specified, this value defaults to a service that has the same name as the path unit, except for the suffix\&. (See above\&.) It is recommended that the unit name that is activated and the unit name of the path unit are named identical, except for the suffix\&. +.RE +.PP +\fIMakeDirectory=\fR +.RS 4 +Takes a boolean argument\&. If true the directories to watch are created before watching\&. This option is ignored for +\fIPathExists=\fR +settings\&. Defaults to +\fBfalse\fR\&. +.RE +.PP +\fIDirectoryMode=\fR +.RS 4 +If +\fIMakeDirectory=\fR +is enabled use the mode specified here to create the directories in question\&. Takes an access mode in octal notation\&. Defaults to +\fB0755\fR\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(8), +\fBsystemd.unit\fR(5), +\fBsystemd.service\fR(5), +\fBinotify\fR(7) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd.path.xml b/man/systemd.path.xml new file mode 100644 index 0000000..5b1ff75 --- /dev/null +++ b/man/systemd.path.xml @@ -0,0 +1,220 @@ + + + + + + + + + systemd.path + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.path + 5 + + + + systemd.path + systemd path configuration files + + + + systemd.path + + + + Description + + A unit configuration file whose name ends in + .path encodes information about + a path monitored by systemd, for + path-based activation. + + This man page lists the configuration options + specific to this unit type. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. The + path specific configuration options are configured in + the [Path] section. + + For each path file, a matching unit file must + exist, describing the unit to activate when the path + changes. By default, a service by the same name as the + path (except for the suffix) is activated. Example: a + path file foo.path activates a + matching service foo.service. The + unit to activate may be controlled by + Unit= (see below). + + Internally, path units use the + inotify7 + API to monitor file systems. Due to that, it suffers by the + same limitations as inotify, and for example cannot be + used to monitor files or directories changed by other + machines on remote NFS file systems. + + If an path unit is beneath another mount + point in the file system hierarchy, a dependency + between both units is created automatically. + + Unless DefaultDependencies= + is set to , path units will + implicitly have dependencies of type + Conflicts= and + Before= on + shutdown.target. These ensure + that path units are terminated cleanly prior to system + shutdown. Only path units involved with early boot or + late system shutdown should disable this + option. + + + + Options + + Path files must include a [Path] section, + which carries information about the path(s) it + monitors. The options specific to the [Path] section + of path units are the following: + + + + PathExists= + PathExistsGlob= + PathChanged= + PathModified= + DirectoryNotEmpty= + + Defines paths to + monitor for certain changes: + PathExists= may be + used to watch the mere existence of a + file or directory. If the file + specified exists the configured unit + is + activated. PathExistsGlob= + works similar, but checks for the + existance of at least one file + matching the globbing pattern + specified. PathChanged= + may be used to watch a file or + directory and activate the configured + unit whenever it changes. It is not activated + on every write to the watched file but it is + activated if the file which was open for writing + gets closed. PathModified= + is similar, but additionally it is activated + also on simple writes to the watched file. + + DirectoryNotEmpty= + may be used to watch a directory and + activate the configured unit whenever + it contains at least one file. + + The arguments of these + directives must be absolute file + system paths. + + Multiple directives may be + combined, of the same and of different + types, to watch multiple paths. + + If a path is already existing + (in case of + PathExists= and + PathExistsGlob=) or + a directory already is not empty (in + case of + DirectoryNotEmpty=) + at the time the path unit is + activated, then the configured unit is + immediately activated as + well. Something similar does not apply + to PathChanged=. + + + + Unit= + + The unit to activate + when any of the configured paths + changes. The argument is a unit name, + whose suffix is not + .path. If not + specified, this value defaults to a + service that has the same name as the + path unit, except for the suffix. (See + above.) It is recommended that the + unit name that is activated and the + unit name of the path unit are named + identical, except for the + suffix. + + + MakeDirectory= + + Takes a boolean + argument. If true the directories to + watch are created before + watching. This option is ignored for + PathExists= + settings. Defaults to + . + + + DirectoryMode= + + If + MakeDirectory= is + enabled use the mode specified here to + create the directories in + question. Takes an access mode in + octal notation. Defaults to + . + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.service5, + inotify7 + + + + diff --git a/man/systemd.service.5 b/man/systemd.service.5 new file mode 100644 index 0000000..fc2c369 --- /dev/null +++ b/man/systemd.service.5 @@ -0,0 +1,473 @@ +'\" t +.\" Title: systemd.service +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd.service +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\&.SERVICE" "5" "02/15/2012" "systemd" "systemd.service" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd.service \- systemd service configuration files +.SH "SYNOPSIS" +.PP +systemd\&.service +.SH "DESCRIPTION" +.PP +A unit configuration file whose name ends in +\&.service +encodes information about a process controlled and supervised by systemd\&. +.PP +This man page lists the configuration options specific to this unit type\&. See +\fBsystemd.unit\fR(5) +for the common options of all unit configuration files\&. The common configuration items are configured in the generic +[Unit] +and +[Install] +sections\&. The service specific configuration options are configured in the +[Service] +section\&. +.PP +Additional options are listed in +\fBsystemd.exec\fR(5), which define the execution environment the commands are executed in\&. +.PP +Unless +\fIDefaultDependencies=\fR +is set to +\fBfalse\fR, service units will implicitly have dependencies of type +\fIRequires=\fR +and +\fIAfter=\fR +on +basic\&.target +as well as dependencies of type +\fIConflicts=\fR +and +\fIBefore=\fR +on +shutdown\&.target\&. These ensure that normal service units pull in basic system initialization, and are terminated cleanly prior to system shutdown\&. Only services involved with early boot or late system shutdown should disable this option\&. +.PP +If a service is requested under a certain name but no unit configuration file is found, systemd looks for a SysV init script by the same name (with the +\&.service +suffix removed) and dynamically creates a service unit from that script\&. This is useful for compatibility with SysV\&. +.SH "OPTIONS" +.PP +Service files must include a +[Service] +section, which carries information about the service and the process it supervises\&. A number of options that may be used in this section are shared with other unit types\&. These options are documented in +\fBsystemd.exec\fR(5)\&. The options specific to the +[Service] +section of service units are the following: +.PP +\fIType=\fR +.RS 4 +Configures the process start\-up type for this service unit\&. One of +\fBsimple\fR, +\fBforking\fR, +\fBoneshot\fR, +\fBdbus\fR, +\fBnotify\fR\&. +.sp +If set to +\fBsimple\fR +(the default value) it is expected that the process configured with +\fIExecStart=\fR +is the main process of the service\&. In this mode, if the process offers functionality to other processes on the system its communication channels should be installed before the daemon is started up (e\&.g\&. sockets set up by systemd, via socket activation), as systemd will immediately proceed starting follow\-up units\&. +.sp +If set to +\fBforking\fR +it is expected that the process configured with +\fIExecStart=\fR +will call +\fBfork()\fR +as part of its start\-up\&. The parent process is expected to exit when start\-up is complete and all communication channels set up\&. The child continues to run as the main daemon process\&. This is the behaviour of traditional UNIX daemons\&. If this setting is used, it is recommended to also use the +\fIPIDFile=\fR +option, so that systemd can identify the main process of the daemon\&. systemd will proceed starting follow\-up units as soon as the parent process exits\&. +.sp +Behaviour of +\fBoneshot\fR +is similar to +\fBsimple\fR, however it is expected that the process has to exit before systemd starts follow\-up units\&. +\fIRemainAfterExit=\fR +is particularly useful for this type of service\&. +.sp +Behaviour of +\fBdbus\fR +is similar to +\fBsimple\fR, however it is expected that the daemon acquires a name on the D\-Bus bus, as configured by +\fIBusName=\fR\&. systemd will proceed starting follow\-up units after the D\-Bus bus name has been acquired\&. Service units with this option configured implicitly gain dependencies on the +dbus\&.socket +unit\&. +.sp +Behaviour of +\fBnotify\fR +is similar to +\fBsimple\fR, however it is expected that the daemon sends a notification message via +\fBsd_notify\fR(3) +or an equivalent call when it finished starting up\&. systemd will proceed starting follow\-up units after this notification message has been sent\&. If this option is used +\fINotifyAccess=\fR +(see below) should be set to open access to the notification socket provided by systemd\&. If +\fINotifyAccess=\fR +is not set, it will be implicitly set to +\fBmain\fR\&. +.RE +.PP +\fIRemainAfterExit=\fR +.RS 4 +Takes a boolean value that specifies whether the service shall be considered active even when all its processes exited\&. Defaults to +\fBno\fR\&. +.RE +.PP +\fIGuessMainPID=\fR +.RS 4 +Takes a boolean value that specifies whether systemd should try to guess the main PID of a service should if it cannot be determined reliably\&. This option is ignored unless +\fBType=forking\fR +is set and +\fBPIDFile=\fR +is unset because for the other types or with an explicitly configured PID file the main PID is always known\&. The guessing algorithm might come to incorrect conclusions if a daemon consists of more than one process\&. If the main PID cannot be determined failure detection and automatic restarting of a service will not work reliably\&. Defaults to +\fByes\fR\&. +.RE +.PP +\fIPIDFile=\fR +.RS 4 +Takes an absolute file name pointing to the PID file of this daemon\&. Use of this option is recommended for services where +\fIType=\fR +is set to +\fBforking\fR\&. systemd will read the PID of the main process of the daemon after start\-up of the service\&. systemd will not write to the file configured here\&. +.RE +.PP +\fIBusName=\fR +.RS 4 +Takes a D\-Bus bus name, where this service is reachable as\&. This option is mandatory for services where +\fIType=\fR +is set to +\fBdbus\fR, but its use is otherwise recommended as well if the process takes a name on the D\-Bus bus\&. +.RE +.PP +\fIExecStart=\fR +.RS 4 +Takes a command line that is executed when this service shall be started up\&. The first token of the command line must be an absolute file name, then followed by arguments for the process\&. It is mandatory to set this option for all services\&. This option may not be specified more than once, except when +\fIType=oneshot\fR +is used in which case more than one +\fIExecStart=\fR +line is accepted which are then invoked one by one, sequentially in the order they appear in the unit file\&. +.sp +Optionally, if the absolute file name is prefixed with +@, the second token will be passed as +argv[0] +to the executed process, followed by the further arguments specified\&. If the first token is prefixed with +\- +an exit code of the command normally considered a failure (i\&.e\&. non\-zero exit status or abnormal exit due to signal) is ignored and considered success\&. If both +\- +and +@ +are used for the same command the former must precede the latter\&. Unless +\fIType=forking\fR +is set, the process started via this command line will be considered the main process of the daemon\&. The command line accepts % specifiers as described in +\fBsystemd.unit\fR(5)\&. +.sp +On top of that basic environment variable substitution is supported\&. Use +${FOO} +as part of a word, or as word of its own on the command line, in which case it will be replaced by the value of the environment variable including all whitespace it contains, resulting in a single argument\&. Use +$FOO +as a separate word on the command line, in which case it will be replaced by the value of the environment variable split up at whitespace, resulting in no or more arguments\&. Note that the first argument (i\&.e\&. the program to execute) may not be a variable, and must be a literal and absolute path name\&. +.RE +.PP +\fIExecStartPre=\fR, \fIExecStartPost=\fR +.RS 4 +Additional commands that are executed before (resp\&. after) the command in +\fIExecStart=\fR\&. Multiple command lines may be concatenated in a single directive, by separating them by semicolons (these semicolons must be passed as separate words)\&. In that case, the commands are executed one after the other, serially\&. Alternatively, these directives may be specified more than once with the same effect\&. However, the latter syntax is not recommended for compatibility with parsers suitable for XDG +\&.desktop +files\&. Use of these settings is optional\&. Specifier and environment variable substitution is supported\&. +.RE +.PP +\fIExecReload=\fR +.RS 4 +Commands to execute to trigger a configuration reload in the service\&. This argument takes multiple command lines, following the same scheme as pointed out for +\fIExecStartPre=\fR +above\&. Use of this setting is optional\&. Specifier and environment variable substitution is supported here following the same scheme as for +\fIExecStart=\fR\&. One special environment variable is set: if known +$MAINPID +is set to the main process of the daemon, and may be used for command lines like the following: +\fB/bin/kill \-HUP $MAINPID\fR\&. +.RE +.PP +\fIExecStop=\fR +.RS 4 +Commands to execute to stop the service started via +\fIExecStart=\fR\&. This argument takes multiple command lines, following the same scheme as pointed out for +\fIExecStartPre=\fR +above\&. Use of this setting is optional\&. All processes remaining for a service after the commands configured in this option are run are terminated according to the +\fIKillMode=\fR +setting (see below)\&. If this option is not specified the process is terminated right\-away when service stop is requested\&. Specifier and environment variable substitution is supported (including +$MAINPID, see above)\&. +.RE +.PP +\fIExecStopPost=\fR +.RS 4 +Additional commands that are executed after the service was stopped using the commands configured in +\fIExecStop=\fR\&. This argument takes multiple command lines, following the same scheme as pointed out for +\fIExecStartPre\fR\&. Use of these settings is optional\&. Specifier and environment variable substitution is supported\&. +.RE +.PP +\fIRestartSec=\fR +.RS 4 +Configures the time to sleep before restarting a service (as configured with +\fIRestart=\fR)\&. Takes a unit\-less value in seconds, or a time span value such as "5min 20s"\&. Defaults to 100ms\&. +.RE +.PP +\fITimeoutSec=\fR +.RS 4 +Configures the time to wait for start\-up and stop\&. If a daemon service does not signal start\-up completion within the configured time the service will be considered failed and be shut down again\&. If a service is asked to stop but does not terminate in the specified time it will be terminated forcibly via SIGTERM, and after another delay of this time with SIGKILL\&. (See +\fIKillMode=\fR +below\&.) Takes a unit\-less value in seconds, or a time span value such as "5min 20s"\&. Pass 0 to disable the timeout logic\&. Defaults to 90s\&. +.RE +.PP +\fIWatchdogSec=\fR +.RS 4 +Configures the watchdog timeout for a service\&. This is activated when the start\-up is completed\&. The service must call +\fBsd_notify\fR(3) +regularly with "WATCHDOG=1"\&. If the time between two such calls is larger than the configured time then the service is placed in a failure state\&. By setting +\fIRestart=\fR +to +\fBon\-failure\fR +or +\fBalways\fR +the service will be automatically restarted\&. The time configured here will be passed to the executed service process in the +\fIWATCHDOG_USEC=\fR +environment variable\&. If this option is used +\fINotifyAccess=\fR +(see below) should be set to open access to the notification socket provided by systemd\&. If +\fINotifyAccess=\fR +is not set, it will be implicitly set to +\fBmain\fR\&. Defaults to 0, which disables this feature\&. +.RE +.PP +\fIRestart=\fR +.RS 4 +Configures whether the main service process shall be restarted when it exits\&. Takes one of +\fBno\fR, +\fBon\-success\fR, +\fBon\-failure\fR, +\fBon\-abort\fR +or +\fBalways\fR\&. If set to +\fBno\fR +(the default) the service will not be restarted when it exits\&. If set to +\fBon\-success\fR +it will be restarted only when it exited cleanly, i\&.e\&. terminated with an exit code of 0\&. If set to +\fBon\-failure\fR +it will be restarted only when it exited with an exit code not equalling 0, when terminated by a signal, when an operation times out or when the configured watchdog timeout is triggered\&. If set to +\fBon\-abort\fR +it will be restarted only if it exits due to reception of an uncaught signal\&. If set to +\fBalways\fR +the service will be restarted regardless whether it exited cleanly or not, got terminated abnormally by a signal or hit a timeout\&. +.RE +.PP +\fIPermissionsStartOnly=\fR +.RS 4 +Takes a boolean argument\&. If true, the permission related execution options as configured with +\fIUser=\fR +and similar options (see +\fBsystemd.exec\fR(5) +for more information) are only applied to the process started with +\fIExecStart=\fR, and not to the various other +\fIExecStartPre=\fR, +\fIExecStartPost=\fR, +\fIExecReload=\fR, +\fIExecStop=\fR, +\fIExecStopPost=\fR +commands\&. If false, the setting is applied to all configured commands the same way\&. Defaults to false\&. +.RE +.PP +\fIRootDirectoryStartOnly=\fR +.RS 4 +Takes a boolean argument\&. If true, the root directory as configured with the +\fIRootDirectory=\fR +option (see +\fBsystemd.exec\fR(5) +for more information) is only applied to the process started with +\fIExecStart=\fR, and not to the various other +\fIExecStartPre=\fR, +\fIExecStartPost=\fR, +\fIExecReload=\fR, +\fIExecStop=\fR, +\fIExecStopPost=\fR +commands\&. If false, the setting is applied to all configured commands the same way\&. Defaults to false\&. +.RE +.PP +\fISysVStartPriority=\fR +.RS 4 +Set the SysV start priority to use to order this service in relation to SysV services lacking LSB headers\&. This option is only necessary to fix ordering in relation to legacy SysV services, that have no ordering information encoded in the script headers\&. As such it should only be used as temporary compatibility option, and not be used in new unit files\&. Almost always it is a better choice to add explicit ordering directives via +\fIAfter=\fR +or +\fIBefore=\fR, instead\&. For more details see +\fBsystemd.unit\fR(5)\&. If used, pass an integer value in the range 0\-99\&. +.RE +.PP +\fIKillMode=\fR +.RS 4 +Specifies how processes of this service shall be killed\&. One of +\fBcontrol\-group\fR, +\fBprocess\fR, +\fBnone\fR\&. +.sp +If set to +\fBcontrol\-group\fR +all remaining processes in the control group of this service will be terminated on service stop, after the stop command (as configured with +\fIExecStop=\fR) is executed\&. If set to +\fBprocess\fR +only the main process itself is killed\&. If set to +\fBnone\fR +no process is killed\&. In this case only the stop command will be executed on service stop, but no process be killed otherwise\&. Processes remaining alive after stop are left in their control group and the control group continues to exist after stop unless it is empty\&. Defaults to +\fBcontrol\-group\fR\&. +.sp +Processes will first be terminated via SIGTERM (unless the signal to send is changed via +\fIKillSignal=\fR)\&. If then after a delay (configured via the +\fITimeoutSec=\fR +option) processes still remain, the termination request is repeated with the SIGKILL signal (unless this is disabled via the +\fISendSIGKILL=\fR +option)\&. See +\fBkill\fR(2) +for more information\&. +.RE +.PP +\fIKillSignal=\fR +.RS 4 +Specifies which signal to use when killing a service\&. Defaults to SIGTERM\&. +.RE +.PP +\fISendSIGKILL=\fR +.RS 4 +Specifies whether to send SIGKILL to remaining processes after a timeout, if the normal shutdown procedure left processes of the service around\&. Takes a boolean value\&. Defaults to "yes"\&. +.RE +.PP +\fINonBlocking=\fR +.RS 4 +Set O_NONBLOCK flag for all file descriptors passed via socket\-based activation\&. If true, all file descriptors >= 3 (i\&.e\&. all except STDIN/STDOUT/STDERR) will have the O_NONBLOCK flag set and hence are in non\-blocking mode\&. This option is only useful in conjunction with a socket unit, as described in +\fBsystemd.socket\fR(5)\&. Defaults to false\&. +.RE +.PP +\fINotifyAccess=\fR +.RS 4 +Controls access to the service status notification socket, as accessible via the +\fBsd_notify\fR(3) +call\&. Takes one of +\fBnone\fR +(the default), +\fBmain\fR +or +\fBall\fR\&. If +\fBnone\fR +no daemon status updates are accepted from the service processes, all status update messages are ignored\&. If +\fBmain\fR +only service updates sent from the main process of the service are accepted\&. If +\fBall\fR +all services updates from all members of the service\*(Aqs control group are accepted\&. This option should be set to open access to the notification socket when using +\fIType=notify\fR +or +\fIWatchdogUsec=\fR +(see above)\&. If those options are used but +\fINotifyAccess=\fR +not configured it will be implicitly set to +\fBmain\fR\&. +.RE +.PP +\fISockets=\fR +.RS 4 +Specifies the name of the socket units this service shall inherit the sockets from when the service is started\&. Normally it should not be necessary to use this setting as all sockets whose unit shares the same name as the service (ignoring the different suffix of course) are passed to the spawned process\&. +.sp +Note that the same socket may be passed to multiple processes at the same time\&. Also note that a different service may be activated on incoming traffic than inherits the sockets\&. Or in other words: The +\fIService=\fR +setting of +\&.socket +units doesn\*(Aqt have to match the inverse of the +\fISockets=\fR +setting of the +\&.service +it refers to\&. +.RE +.PP +\fIFsckPassNo=\fR +.RS 4 +Set the fsck passno priority to use to order this service in relation to other file system checking services\&. This option is only necessary to fix ordering in relation to fsck jobs automatically created for all +/etc/fstab +entries with a value in the fs_passno column > 0\&. As such it should only be used as option for fsck services\&. Almost always it is a better choice to add explicit ordering directives via +\fIAfter=\fR +or +\fIBefore=\fR, instead\&. For more details see +\fBsystemd.unit\fR(5)\&. If used, pass an integer value in the same range as +/etc/fstab\*(Aqs fs_passno column\&. See +\fBfstab\fR(5) +for details\&. +.RE +.PP +\fIStartLimitInterval=\fR, \fIStartLimitBurst=\fR +.RS 4 +Configure service start rate limiting\&. By default services which are started more often than 5 times within 10s are not permitted to start any more times until the 10s interval ends\&. With these two options this rate limiting may be modified\&. Use +\fIStartLimitInterval=\fR +to configure the checking interval (defaults to 10s, set to 0 to disable any kind of rate limiting)\&. Use +\fIStartLimitBurst=\fR +to configure how many starts per interval are allowed (defaults to 5)\&. These configuration options are particularly useful in conjunction with +\fIRestart=\fR\&. +.RE +.PP +\fIStartLimitAction=\fR +.RS 4 +Configure the action to take if the rate limit configured with +\fIStartLimitInterval=\fR +and +\fIStartLimitBurst=\fR +is hit\&. Takes one of +\fBnone\fR, +\fBreboot\fR, +\fBreboot\-force\fR +or +\fBreboot\-immediate\fR\&. If +\fBnone\fR +is set, hitting the rate limit will trigger no action besides that the start will not be permitted\&. +\fBreboot\fR +causes a reboot following the normal shutdown procedure (i\&.e\&. equivalent to +\fBsystemctl reboot\fR), +\fBreboot\-force\fR +causes an forced reboot which will terminate all processes forcibly but should cause no dirty file systems on reboot (i\&.e\&. equivalent to +\fBsystemctl reboot \-f\fR) and +\fBreboot\-immediate\fR +causes immediate execution of the +\fBreboot\fR(2) +system call, which might result in data loss\&. Defaults to +\fBnone\fR\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(8), +\fBsystemd.unit\fR(5), +\fBsystemd.exec\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd.service.xml b/man/systemd.service.xml new file mode 100644 index 0000000..837a992 --- /dev/null +++ b/man/systemd.service.xml @@ -0,0 +1,837 @@ + + + + + + + + + systemd.service + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.service + 5 + + + + systemd.service + systemd service configuration files + + + + systemd.service + + + + Description + + A unit configuration file whose name ends in + .service encodes information + about a process controlled and supervised by + systemd. + + This man page lists the configuration options + specific to this unit type. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and + [Install] sections. The service + specific configuration options are configured in the + [Service] section. + + Additional options are listed in + systemd.exec5, + which define the execution environment the commands + are executed in. + + Unless DefaultDependencies= + is set to , service units will + implicitly have dependencies of type + Requires= and + After= on + basic.target as well as + dependencies of type Conflicts= and + Before= on + shutdown.target. These ensure + that normal service units pull in basic system + initialization, and are terminated cleanly prior to + system shutdown. Only services involved with early + boot or late system shutdown should disable this + option. + + If a service is requested under a certain name + but no unit configuration file is found, systemd looks + for a SysV init script by the same name (with the + .service suffix removed) and + dynamically creates a service unit from that + script. This is useful for compatibility with + SysV. + + + + Options + + Service files must include a + [Service] section, which carries + information about the service and the process it + supervises. A number of options that may be used in + this section are shared with other unit types. These + options are documented in + systemd.exec5. The + options specific to the [Service] + section of service units are the following: + + + + Type= + + Configures the process + start-up type for this service + unit. One of , + , + , + , + . + + If set to + (the default + value) it is expected that the process + configured with + ExecStart= is the + main process of the service. In this + mode, if the process offers + functionality to other processes on + the system its communication channels + should be installed before the daemon + is started up (e.g. sockets set up by + systemd, via socket activation), as + systemd will immediately proceed + starting follow-up units. + + If set to + it is + expected that the process configured + with ExecStart= + will call fork() + as part of its start-up. The parent process is + expected to exit when start-up is + complete and all communication + channels set up. The child continues + to run as the main daemon + process. This is the behaviour of + traditional UNIX daemons. If this + setting is used, it is recommended to + also use the + PIDFile= option, so + that systemd can identify the main + process of the daemon. systemd will + proceed starting follow-up units as + soon as the parent process + exits. + + Behaviour of + is similar + to , however + it is expected that the process has to + exit before systemd starts follow-up + units. RemainAfterExit= + is particularly useful for this type + of service. + + Behaviour of + is similar to + , however it is + expected that the daemon acquires a + name on the D-Bus bus, as configured + by + BusName=. systemd + will proceed starting follow-up units + after the D-Bus bus name has been + acquired. Service units with this + option configured implicitly gain + dependencies on the + dbus.socket + unit. + + Behaviour of + is similar to + , however it is + expected that the daemon sends a + notification message via + sd_notify3 + or an equivalent call when it finished + starting up. systemd will proceed + starting follow-up units after this + notification message has been sent. If + this option is used + NotifyAccess= (see + below) should be set to open access to + the notification socket provided by + systemd. If + NotifyAccess= is + not set, it will be implicitly set to + . + + + + + RemainAfterExit= + + Takes a boolean value + that specifies whether the service + shall be considered active even when + all its processes exited. Defaults to + . + + + + + GuessMainPID= + + Takes a boolean value + that specifies whether systemd should + try to guess the main PID of a service + should if it cannot be determined + reliably. This option is ignored + unless + is set and + is unset because for the other types + or with an explicitly configured PID + file the main PID is always known. The + guessing algorithm might come to + incorrect conclusions if a daemon + consists of more than one process. If + the main PID cannot be determined + failure detection and automatic + restarting of a service will not work + reliably. Defaults to + . + + + + + PIDFile= + + Takes an absolute file + name pointing to the PID file of this + daemon. Use of this option is + recommended for services where + Type= is set to + . systemd will + read the PID of the main process of + the daemon after start-up of the + service. systemd will not write to the + file configured here. + + + + + BusName= + + Takes a D-Bus bus + name, where this service is reachable + as. This option is mandatory for + services where + Type= is set to + , but its use + is otherwise recommended as well if + the process takes a name on the D-Bus + bus. + + + + + ExecStart= + Takes a command line + that is executed when this service + shall be started up. The first token + of the command line must be an + absolute file name, then followed by + arguments for the process. It is + mandatory to set this option for all + services. This option may not be + specified more than once, except when + Type=oneshot is + used in which case more than one + ExecStart= line is + accepted which are then invoked one by + one, sequentially in the order they + appear in the unit file. + + Optionally, if the absolute file + name is prefixed with + @, the second token + will be passed as + argv[0] to the + executed process, followed by the + further arguments specified. If the + first token is prefixed with + - an exit code of + the command normally considered a + failure (i.e. non-zero exit status or + abnormal exit due to signal) is ignored + and considered success. If both + - and + @ are used for the + same command the former must precede + the latter. Unless + Type=forking is + set, the process started via this + command line will be considered the + main process of the daemon. The + command line accepts % specifiers as + described in + systemd.unit5. + + On top of that basic environment + variable substitution is + supported. Use + ${FOO} as part of a + word, or as word of its own on the + command line, in which case it will be + replaced by the value of the + environment variable including all + whitespace it contains, resulting in a + single argument. Use + $FOO as a separate + word on the command line, in which + case it will be replaced by the value + of the environment variable split up + at whitespace, resulting in no or more + arguments. Note that the first + argument (i.e. the program to execute) + may not be a variable, and must be a + literal and absolute path + name. + + + + ExecStartPre= + ExecStartPost= + Additional commands + that are executed before (resp. after) + the command in + ExecStart=. Multiple + command lines may be concatenated in a + single directive, by separating them + by semicolons (these semicolons must + be passed as separate words). In that + case, the commands are executed one + after the other, + serially. Alternatively, these + directives may be specified more than + once with the same effect. However, + the latter syntax is not recommended + for compatibility with parsers + suitable for XDG + .desktop files. + Use of these settings is + optional. Specifier and environment + variable substitution is + supported. + + + + ExecReload= + Commands to execute to + trigger a configuration reload in the + service. This argument takes multiple + command lines, following the same + scheme as pointed out for + ExecStartPre= + above. Use of this setting is + optional. Specifier and environment + variable substitution is supported + here following the same scheme as for + ExecStart=. One + special environment variable is set: + if known $MAINPID is + set to the main process of the + daemon, and may be used for command + lines like the following: + /bin/kill -HUP + $MAINPID. + + + + ExecStop= + Commands to execute to + stop the service started via + ExecStart=. This + argument takes multiple command lines, + following the same scheme as pointed + out for + ExecStartPre= + above. Use of this setting is + optional. All processes remaining for + a service after the commands + configured in this option are run are + terminated according to the + KillMode= setting + (see below). If this option is not + specified the process is terminated + right-away when service stop is + requested. Specifier and environment + variable substitution is supported + (including + $MAINPID, see + above). + + + + ExecStopPost= + Additional commands + that are executed after the service + was stopped using the commands + configured in + ExecStop=. This + argument takes multiple command lines, + following the same scheme as pointed + out for + ExecStartPre. Use + of these settings is + optional. Specifier and environment + variable substitution is + supported. + + + + RestartSec= + Configures the time to + sleep before restarting a service (as + configured with + Restart=). Takes a + unit-less value in seconds, or a time + span value such as "5min + 20s". Defaults to + 100ms. + + + + TimeoutSec= + Configures the time to + wait for start-up and stop. If a + daemon service does not signal + start-up completion within the + configured time the service will be + considered failed and be shut down + again. If a service is asked to stop + but does not terminate in the + specified time it will be terminated + forcibly via SIGTERM, and after + another delay of this time with + SIGKILL. (See + KillMode= + below.) Takes a unit-less value in seconds, or a + time span value such as "5min + 20s". Pass 0 to disable the timeout + logic. Defaults to + 90s. + + + + WatchdogSec= + Configures the + watchdog timeout for a service. This + is activated when the start-up is + completed. The service must call + sd_notify3 + regularly with "WATCHDOG=1". If the + time between two such calls is larger + than the configured time then the + service is placed in a failure + state. By setting + Restart= + to or + the service + will be automatically restarted. The + time configured here will be passed to + the executed service process in the + WATCHDOG_USEC= + environment variable. If + this option is used + NotifyAccess= (see + below) should be set to open access to + the notification socket provided by + systemd. If + NotifyAccess= is not + set, it will be implicitly set to + . Defaults to 0, + which disables this + feature. + + + + Restart= + Configures whether the + main service process shall be + restarted when it exits. Takes one of + , + , + , + or + . If set to + (the default) the + service will not be restarted when it + exits. If set to + it will be + restarted only when it exited cleanly, + i.e. terminated with an exit code of + 0. If set to + it will be + restarted only when it exited with an + exit code not equalling 0, when + terminated by a signal, when an + operation times out or when the + configured watchdog timeout is + triggered. If set to + it will be + restarted only if it exits due to + reception of an uncaught signal. If + set to the + service will be restarted regardless + whether it exited cleanly or not, + got terminated abnormally by a + signal or hit a timeout. + + + + PermissionsStartOnly= + Takes a boolean + argument. If true, the permission + related execution options as + configured with + User= and similar + options (see + systemd.exec5 + for more information) are only applied + to the process started with + ExecStart=, and not + to the various other + ExecStartPre=, + ExecStartPost=, + ExecReload=, + ExecStop=, + ExecStopPost= + commands. If false, the setting is + applied to all configured commands the + same way. Defaults to + false. + + + + RootDirectoryStartOnly= + Takes a boolean + argument. If true, the root directory + as configured with the + RootDirectory= + option (see + systemd.exec5 + for more information) is only applied + to the process started with + ExecStart=, and not + to the various other + ExecStartPre=, + ExecStartPost=, + ExecReload=, + ExecStop=, + ExecStopPost= + commands. If false, the setting is + applied to all configured commands the + same way. Defaults to + false. + + + + SysVStartPriority= + Set the SysV start + priority to use to order this service + in relation to SysV services lacking + LSB headers. This option is only + necessary to fix ordering in relation + to legacy SysV services, that have no + ordering information encoded in the + script headers. As such it should only + be used as temporary compatibility + option, and not be used in new unit + files. Almost always it is a better + choice to add explicit ordering + directives via + After= or + Before=, + instead. For more details see + systemd.unit5. If + used, pass an integer value in the + range 0-99. + + + + KillMode= + Specifies how + processes of this service shall be + killed. One of + , + , + . + + If set to + all + remaining processes in the control + group of this service will be + terminated on service stop, after the + stop command (as configured with + ExecStop=) is + executed. If set to + only the main + process itself is killed. If set to + no process is + killed. In this case only the stop + command will be executed on service + stop, but no process be killed + otherwise. Processes remaining alive + after stop are left in their control + group and the control group continues + to exist after stop unless it is + empty. Defaults to + . + + Processes will first be + terminated via SIGTERM (unless the + signal to send is changed via + KillSignal=). If + then after a delay (configured via the + TimeoutSec= option) + processes still remain, the + termination request is repeated with + the SIGKILL signal (unless this is + disabled via the + SendSIGKILL= + option). See + kill2 + for more + information. + + + + KillSignal= + Specifies which signal + to use when killing a + service. Defaults to SIGTERM. + + + + + SendSIGKILL= + Specifies whether to + send SIGKILL to remaining processes + after a timeout, if the normal + shutdown procedure left processes of + the service around. Takes a boolean + value. Defaults to "yes". + + + + + NonBlocking= + Set O_NONBLOCK flag + for all file descriptors passed via + socket-based activation. If true, all + file descriptors >= 3 (i.e. all except + STDIN/STDOUT/STDERR) will have + the O_NONBLOCK flag set and hence are in + non-blocking mode. This option is only + useful in conjunction with a socket + unit, as described in + systemd.socket5. Defaults + to false. + + + + NotifyAccess= + Controls access to the + service status notification socket, as + accessible via the + sd_notify3 + call. Takes one of + (the default), + or + . If + no daemon status + updates are accepted from the service + processes, all status update messages + are ignored. If + only service updates sent from the + main process of the service are + accepted. If all + services updates from all members of + the service's control group are + accepted. This option should be set to + open access to the notification socket + when using + Type=notify or + WatchdogUsec= (see + above). If those options are used but + NotifyAccess= not + configured it will be implicitly set + to + . + + + + Sockets= + Specifies the name of + the socket units this service shall + inherit the sockets from when the + service is started. Normally it + should not be necessary to use this + setting as all sockets whose unit + shares the same name as the service + (ignoring the different suffix of course) + are passed to the spawned + process. + + Note that the same socket may be + passed to multiple processes at the + same time. Also note that a different + service may be activated on incoming + traffic than inherits the sockets. Or + in other words: The + Service= setting of + .socket units + doesn't have to match the inverse of the + Sockets= setting of + the .service it + refers to. + + + + FsckPassNo= + Set the fsck passno + priority to use to order this service + in relation to other file system + checking services. This option is only + necessary to fix ordering in relation + to fsck jobs automatically created for + all /etc/fstab + entries with a value in the fs_passno + column > 0. As such it should only be + used as option for fsck + services. Almost always it is a better + choice to add explicit ordering + directives via + After= or + Before=, + instead. For more details see + systemd.unit5. If + used, pass an integer value in the + same range as + /etc/fstab's + fs_passno column. See + fstab5 + for details. + + + + StartLimitInterval= + StartLimitBurst= + + Configure service + start rate limiting. By default + services which are started more often + than 5 times within 10s are not + permitted to start any more times + until the 10s interval ends. With + these two options this rate limiting + may be modified. Use + StartLimitInterval= + to configure the checking interval + (defaults to 10s, set to 0 to disable + any kind of rate limiting). Use + StartLimitBurst= to + configure how many starts per interval + are allowed (defaults to 5). These + configuration options are particularly + useful in conjunction with + Restart=. + + + + StartLimitAction= + + Configure the action + to take if the rate limit configured + with + StartLimitInterval= + and + StartLimitBurst= is + hit. Takes one of + , + , + or + . If + is set, + hitting the rate limit will trigger no + action besides that the start will not + be + permitted. + causes a reboot following the normal + shutdown procedure (i.e. equivalent to + systemctl reboot), + causes + an forced reboot which will terminate + all processes forcibly but should + cause no dirty file systems on reboot + (i.e. equivalent to systemctl + reboot -f) and + + causes immediate execution of the + reboot2 + system call, which might result in + data loss. Defaults to + . + + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.exec5 + + + + diff --git a/man/systemd.snapshot.5 b/man/systemd.snapshot.5 new file mode 100644 index 0000000..dc59f23 --- /dev/null +++ b/man/systemd.snapshot.5 @@ -0,0 +1,58 @@ +'\" t +.\" Title: systemd.snapshot +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd.snapshot +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\&.SNAPSHOT" "5" "02/15/2012" "systemd" "systemd.snapshot" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd.snapshot \- systemd snapshot units +.SH "SYNOPSIS" +.PP +systemd\&.snapshot +.SH "DESCRIPTION" +.PP +Snapshot units are not configured via unit configuration files\&. Nonetheless they are named similar to filenames\&. A unit name whose name ends in +\&.snapshot +refers to a dynamic snapshot of the systemd runtime state\&. +.PP +Snapshots are not configured on disk but created dynamically via +\fBsystemctl snapshot\fR +(see +\fBsystemctl\fR(8) +for details) or an equivalent command\&. When created, they will automatically get dependencies on the currently activated units\&. They act as saved runtime state of the systemd manager\&. Later on, the user may choose to return to the saved state via +\fBsystemctl isolate\fR\&. They are useful to roll back to a defined state after temporarily starting/stopping services or similar\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(8), +\fBsystemd.unit\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd.snapshot.xml b/man/systemd.snapshot.xml new file mode 100644 index 0000000..a3e2322 --- /dev/null +++ b/man/systemd.snapshot.xml @@ -0,0 +1,87 @@ + + + + + + + + + systemd.snapshot + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.snapshot + 5 + + + + systemd.snapshot + systemd snapshot units + + + + systemd.snapshot + + + + Description + + Snapshot units are not configured via unit + configuration files. Nonetheless they are named + similar to filenames. A unit name whose name ends in + .snapshot refers to a dynamic + snapshot of the systemd runtime state. + + Snapshots are not configured on disk but created + dynamically via systemctl snapshot + (see + systemctl8 + for details) or an equivalent command. When created, + they will automatically get dependencies on the + currently activated units. They act as saved + runtime state of the systemd manager. Later on, the + user may choose to return to the saved state via + systemctl isolate. They are + useful to roll back to a defined state after + temporarily starting/stopping services or + similar. + + + + See Also + + systemd1, + systemctl8, + systemd.unit5 + + + + diff --git a/man/systemd.socket.5 b/man/systemd.socket.5 new file mode 100644 index 0000000..2f286ec --- /dev/null +++ b/man/systemd.socket.5 @@ -0,0 +1,389 @@ +'\" t +.\" Title: systemd.socket +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd.socket +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\&.SOCKET" "5" "02/15/2012" "systemd" "systemd.socket" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd.socket \- systemd socket configuration files +.SH "SYNOPSIS" +.PP +systemd\&.socket +.SH "DESCRIPTION" +.PP +A unit configuration file whose name ends in +\&.socket +encodes information about an IPC or network socket or a file system FIFO controlled and supervised by systemd, for socket\-based activation\&. +.PP +This man page lists the configuration options specific to this unit type\&. See +\fBsystemd.unit\fR(5) +for the common options of all unit configuration files\&. The common configuration items are configured in the generic [Unit] and [Install] sections\&. The socket specific configuration options are configured in the [Socket] section\&. +.PP +Additional options are listed in +\fBsystemd.exec\fR(5), which define the execution environment the +\fBExecStartPre=\fR, +\fBExecStartPost=\fR, +\fBExecStopPre=\fR +and +\fBExecStoptPost=\fR +commands are executed in\&. +.PP +For each socket file a matching service file (see +\fBsystemd.service\fR(5) +for details) must exist, describing the service to start on incoming traffic on the socket\&. Depending on the setting of +\fBAccept=\fR +(see below), this must either be named like the socket unit, but with the suffix replaced; or it must be a template file named the same way\&. Example: a socket file +foo\&.socket +needs a matching service +foo\&.service +if +\fBAccept=false\fR +is set\&. If +\fBAccept=true\fR +is set a service template file +foo@\&.service +must exist from which services are instantiated for each incoming connection\&. +.PP +Unless +\fIDefaultDependencies=\fR +is set to +\fBfalse\fR, socket units will implicitly have dependencies of type +\fIRequires=\fR +and +\fIAfter=\fR +on +sysinit\&.target +as well as dependencies of type +\fIConflicts=\fR +and +\fIBefore=\fR +on +shutdown\&.target\&. These ensure that socket units pull in basic system initialization, and are terminated cleanly prior to system shutdown\&. Only sockets involved with early boot or late system shutdown should disable this option\&. +.PP +Socket units may be used to implement on\-demand starting of services, as well as parallelized starting of services\&. +.PP +Note that the daemon software configured for socket activation with socket units needs to be able to accept sockets from systemd, either via systemd\*(Aqs native socket passing interface (see +\fBsd_listen_fds\fR(3) +for details) or via the traditional +\fBinetd\fR(8)\-style socket passing (i\&.e\&. sockets passed in via STDIN and STDOUT, using +\fIStandardInput=socket\fR +in the service file)\&. +.SH "OPTIONS" +.PP +Socket files must include a [Socket] section, which carries information about the socket or FIFO it supervises\&. A number of options that may be used in this section are shared with other unit types\&. These options are documented in +\fBsystemd.exec\fR(5)\&. The options specific to the [Socket] section of socket units are the following: +.PP +\fIListenStream=\fR, \fIListenDatagram=\fR, \fIListenSequentialPacket=\fR +.RS 4 +Specifies an address to listen on for a stream (SOCK_STREAM), datagram (SOCK_DGRAM) resp\&. sequential packet (SOCK_SEQPACKET) socket\&. The address can be written in various formats: +.sp +If the address starts with a slash (/), it is read as file system socket in the AF_UNIX socket family\&. +.sp +If the address starts with an at symbol (@) it is read as abstract namespace socket in the AF_UNIX family\&. The @ is replaced with a NUL character before binding\&. For details see +\fBunix\fR(7)\&. +.sp +If the address string is a single number it is read as port number to listen on for both IPv4 and IPv6\&. +.sp +If the address string is a string in the format v\&.w\&.x\&.y:z it is read as IPv4 specifier for listening on an address v\&.w\&.x\&.y on a port z\&. +.sp +If the address string is a string in the format [x]:y it is read as IPv6 address x on a port y\&. +.sp +Note that SOCK_SEQPACKET (i\&.e\&. +\fIListenSequentialPacket=\fR) is only available for AF_UNIX sockets\&. SOCK_STREAM (i\&.e\&. +\fIListenStream=\fR) when used for IP sockets refers to TCP sockets, SOCK_DGRAM (i\&.e\&. +\fIListenDatagram=\fR) to UDP\&. +.sp +These options may be specified more than once in which case incoming traffic on any of the sockets will trigger service activation, and all listed sockets will be passed to the service, regardless whether there is incoming traffic on them or not\&. +.sp +If an IP address is used here, it is often desirable to listen on it before the interface it is configured on is up and running, and even regardless whether it will be up and running ever at all\&. To deal with this it is recommended to set the +\fIFreeBind=\fR +option described below\&. +.RE +.PP +\fIListenFIFO=\fR +.RS 4 +Specifies a file system FIFO to listen on\&. This expects an absolute file system path as argument\&. Behaviour otherwise is very similar to the +\fIListenDatagram=\fR +directive above\&. +.RE +.PP +\fIListenSpecial=\fR +.RS 4 +Specifies a special file in the file system to listen on\&. This expects an absolute file system path as argument\&. Behaviour otherwise is very similar to the +\fIListenFIFO=\fR +directive above\&. Use this to open character device nodes as well as special files in +/proc +and +/sys\&. +.RE +.PP +\fIListenNetlink=\fR +.RS 4 +Specifies a Netlink family to create a socket for to listen on\&. This expects a short string referring to the AF_NETLINK family name (such as +\fIaudit\fR +or +\fIkobject\-uevent\fR) as argument, optionally suffixed by a whitespace followed by a multicast group integer\&. Behaviour otherwise is very similar to the +\fIListenDatagram=\fR +directive above\&. +.RE +.PP +\fIListenMessageQueue=\fR +.RS 4 +Specifies a POSIX message queue name to listen on\&. This expects a valid message queue name (i\&.e\&. beginning with /)\&. Behaviour otherwise is very similar to the +\fIListenFIFO=\fR +directive above\&. On Linux message queue descriptors are actually file descriptors and can be inherited between processes\&. +.RE +.PP +\fIBindIPv6Only=\fR +.RS 4 +Takes a one of +\fBdefault\fR, +\fBboth\fR +or +\fBipv6\-only\fR\&. Controls the IPV6_V6ONLY socket option (see +\fBipv6\fR(7) +for details)\&. If +\fBboth\fR, IPv6 sockets bound will be accessible via both IPv4 and IPv6\&. If +\fBipv6\-only\fR, they will be accessible via IPv6 only\&. If +\fBdefault\fR +(which is the default, surprise!) the system wide default setting is used, as controlled by +/proc/sys/net/ipv6/bindv6only\&. +.RE +.PP +\fIBacklog=\fR +.RS 4 +Takes an unsigned integer argument\&. Specifies the number of connections to queue that have not been accepted yet\&. This setting matters only for stream and sequential packet sockets\&. See +\fBlisten\fR(2) +for details\&. Defaults to SOMAXCONN (128)\&. +.RE +.PP +\fIBindToDevice=\fR +.RS 4 +Specifies a network interface name to bind this socket to\&. If set traffic will only be accepted from the specified network interfaces\&. This controls the SO_BINDTODEVICE socket option (see +\fBsocket\fR(7) +for details)\&. If this option is used, an automatic dependency from this socket unit on the network interface device unit (\fBsystemd.device\fR(5) +is created\&. +.RE +.PP +\fIDirectoryMode=\fR +.RS 4 +If listening on a file system socket of FIFO, the parent directories are automatically created if needed\&. This option specifies the file system access mode used when creating these directories\&. Takes an access mode in octal notation\&. Defaults to 0755\&. +.RE +.PP +\fISocketMode=\fR +.RS 4 +If listening on a file system socket of FIFO, this option specifies the file system access mode used when creating the file node\&. Takes an access mode in octal notation\&. Defaults to 0666\&. +.RE +.PP +\fIAccept=\fR +.RS 4 +Takes a boolean argument\&. If true, a service instance is spawned for each incoming connection and only the connection socket is passed to it\&. If false, all listening sockets themselves are passed to the started service unit, and only one service unit is spawned for all connections (also see above)\&. This value is ignored for datagram sockets and FIFOs where a single service unit unconditionally handles all incoming traffic\&. Defaults to +\fBfalse\fR\&. For performance reasons, it is recommended to write new daemons only in a way that is suitable for +\fBAccept=false\fR\&. This option is mostly useful to allow daemons designed for usage with +\fBinetd\fR(8), to work unmodified with systemd socket activation\&. +.RE +.PP +\fIMaxConnections=\fR +.RS 4 +The maximum number of connections to simultaneously run services instances for, when +\fBAccept=true\fR +is set\&. If more concurrent connections are coming in, they will be refused until at least one existing connection is terminated\&. This setting has no effect for sockets configured with +\fBAccept=no\fR +or datagram sockets\&. Defaults to 64\&. +.RE +.PP +\fIKeepAlive=\fR +.RS 4 +Takes a boolean argument\&. If true, the TCP/IP stack will send a keep alive message after 2h (depending on the configuration of +/proc/sys/net/ipv4/tcp_keepalive_time) for all TCP streams accepted on this socket\&. This controls the SO_KEEPALIVE socket option (see +\fBsocket\fR(7) +and the +\m[blue]\fBTCP Keepalive HOWTO\fR\m[]\&\s-2\u[1]\d\s+2 +for details\&.) Defaults to +\fBfalse\fR\&. +.RE +.PP +\fIPriority=\fR +.RS 4 +Takes an integer argument controlling the priority for all traffic sent from this socket\&. This controls the SO_PRIORITY socket option (see +\fBsocket\fR(7) +for details\&.)\&. +.RE +.PP +\fIReceiveBuffer=\fR, \fISendBuffer=\fR +.RS 4 +Takes an integer argument controlling the receive resp\&. send buffer sizes of this socket\&. This controls the SO_RCVBUF resp\&. SO_SNDBUF socket options (see +\fBsocket\fR(7) +for details\&.)\&. +.RE +.PP +\fIIPTOS=\fR +.RS 4 +Takes an integer argument controlling the IP Type\-Of\-Service field for packets generated from this socket\&. This controls the IP_TOS socket option (see +\fBip\fR(7) +for details\&.)\&. Either a numeric string or one of +\fBlow\-delay\fR, +\fBthroughput\fR, +\fBreliability\fR +or +\fBlow\-cost\fR +may be specified\&. +.RE +.PP +\fIIPTTL=\fR +.RS 4 +Takes an integer argument controlling the IPv4 Time\-To\-Live/IPv6 Hop\-Count field for packets generated from this socket\&. This sets the IP_TTL/IPV6_UNICAST_HOPS socket options (see +\fBip\fR(7) +and +\fBipv6\fR(7) +for details\&.) +.RE +.PP +\fIMark=\fR +.RS 4 +Takes an integer value\&. Controls the firewall mark of packets generated by this socket\&. This can be used in the firewall logic to filter packets from this socket\&. This sets the SO_MARK socket option\&. See +\fBiptables\fR(8) +for details\&. +.RE +.PP +\fIPipeSize=\fR +.RS 4 +Takes an integer value\&. Controls the pipe buffer size of FIFOs configured in this socket unit\&. See +\fBfcntl\fR(2) +for details\&. +.RE +.PP +\fIMessageQueueMaxMessages=\fR, \fIMessageQueueMessageSize=\fR +.RS 4 +These two settings take integer values and control the mq_maxmsg resp\&. mq_msgsize field when creating the message queue\&. Note that either none or both of these variables need to be set\&. See +\fBmq_setattr\fR(3) +for details\&. +.RE +.PP +\fIFreeBind=\fR +.RS 4 +Takes a boolean value\&. Controls whether the socket can be bound to non\-local IP addresses\&. This is useful to configure sockets listening on specific IP addresses before those IP addresses are successfully configured on a network interface\&. This sets the IP_FREEBIND socket option\&. For robustness reasons it is recommended to use this option whenever you bind a socket to a specific IP address\&. Defaults to +\fBfalse\fR\&. +.RE +.PP +\fITransparent=\fR +.RS 4 +Takes a boolean value\&. Controls the IP_TRANSPARENT socket option\&. Defaults to +\fBfalse\fR\&. +.RE +.PP +\fIBroadcast=\fR +.RS 4 +Takes a boolean value\&. This controls the SO_BROADCAST socket option, which allows broadcast datagrams to be sent from this socket\&. Defaults to +\fBfalse\fR\&. +.RE +.PP +\fIPassCredentials=\fR +.RS 4 +Takes a boolean value\&. This controls the SO_PASSCRED socket option, which allows UNIX sockets to receive the credentials of the sending process in an ancillary message\&. Defaults to +\fBfalse\fR\&. +.RE +.PP +\fITCPCongestion=\fR +.RS 4 +Takes a string value\&. Controls the TCP congestion algorithm used by this socket\&. Should be one of "westwood", "veno", "cubic", "lp" or any other available algorithm supported by the IP stack\&. This setting applies only to stream sockets\&. +.RE +.PP +\fIExecStartPre=\fR, \fIExecStartPost=\fR +.RS 4 +Takes one or more command lines, which are executed before (resp\&. after) the listening sockets/FIFOs are created and bound\&. The first token of the command line must be an absolute file name, then followed by arguments for the process\&. Multiple command lines may be specified following the same scheme as used for +\fIExecStartPre=\fR +of service unit files\&. +.RE +.PP +\fIExecStopPre=\fR, \fIExecStopPost=\fR +.RS 4 +Additional commands that are executed before (resp\&. after) the listening sockets/FIFOs are closed and removed\&. Multiple command lines may be specified following the same scheme as used for +\fIExecStartPre=\fR +of service unit files\&. +.RE +.PP +\fITimeoutSec=\fR +.RS 4 +Configures the time to wait for the commands specified in +\fIExecStartPre=\fR, +\fIExecStartPost=\fR, +\fIExecStopPre=\fR +and +\fIExecStopPost=\fR +to finish\&. If a command does not exit within the configured time, the socket will be considered failed and be shut down again\&. All commands still running, will be terminated forcibly via SIGTERM, and after another delay of this time with SIGKILL\&. (See +\fBKillMode=\fR +below\&.) Takes a unit\-less value in seconds, or a time span value such as "5min 20s"\&. Pass 0 to disable the timeout logic\&. Defaults to 90s\&. +.RE +.PP +\fIKillMode=\fR +.RS 4 +Specifies how processes of this socket unit shall be killed\&. One of +\fBcontrol\-group\fR, +\fBprocess\fR, +\fBnone\fR\&. +.sp +This option is mostly equivalent to the +\fBKillMode=\fR +option of service files\&. See +\fBsystemd.service\fR(5) +for details\&. +.RE +.PP +\fIKillSignal=\fR +.RS 4 +Specifies which signal to use when killing a process of this socket\&. Defaults to SIGTERM\&. +.RE +.PP +\fISendSIGKILL=\fR +.RS 4 +Specifies whether to send SIGKILL to remaining processes after a timeout, if the normal shutdown procedure left processes of the socket around\&. Takes a boolean value\&. Defaults to "yes"\&. +.RE +.PP +\fIService=\fR +.RS 4 +Specifies the service unit name to activate on incoming traffic\&. This defaults to the service that bears the same name as the socket (ignoring the different suffixes)\&. In most cases it should not be necessary to use this option\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(8), +\fBsystemd.unit\fR(5), +\fBsystemd.exec\fR(5), +\fBsystemd.service\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE +.SH "NOTES" +.IP " 1." 4 +TCP Keepalive HOWTO +.RS 4 +\%http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/ +.RE diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml new file mode 100644 index 0000000..ef5b28c --- /dev/null +++ b/man/systemd.socket.xml @@ -0,0 +1,663 @@ + + + + + + + + + systemd.socket + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.socket + 5 + + + + systemd.socket + systemd socket configuration files + + + + systemd.socket + + + + Description + + A unit configuration file whose name ends in + .socket encodes information about + an IPC or network socket or a file system FIFO + controlled and supervised by systemd, for socket-based + activation. + + This man page lists the configuration options + specific to this unit type. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. The + socket specific configuration options are configured + in the [Socket] section. + + Additional options are listed in + systemd.exec5, + which define the execution environment the + , + , + and + commands are executed + in. + + For each socket file a matching service file + (see + systemd.service5 + for details) must exist, describing the service to + start on incoming traffic on the socket. Depending on + the setting of (see below), + this must either be named like the socket unit, but + with the suffix replaced; or it must be a template + file named the same way. Example: a socket file + foo.socket needs a matching + service foo.service if + is set. If + is set a service template + file foo@.service must exist from + which services are instantiated for each incoming + connection. + + Unless DefaultDependencies= + is set to , socket units will + implicitly have dependencies of type + Requires= and + After= on + sysinit.target as well as + dependencies of type Conflicts= and + Before= on + shutdown.target. These ensure + that socket units pull in basic system + initialization, and are terminated cleanly prior to + system shutdown. Only sockets involved with early + boot or late system shutdown should disable this + option. + + Socket units may be used to implement on-demand + starting of services, as well as parallelized starting + of services. + + Note that the daemon software configured for + socket activation with socket units needs to be able + to accept sockets from systemd, either via systemd's + native socket passing interface (see + sd_listen_fds3 + for details) or via the traditional + inetd8-style + socket passing (i.e. sockets passed in via STDIN and + STDOUT, using StandardInput=socket + in the service file). + + + + Options + + Socket files must include a [Socket] section, + which carries information about the socket or FIFO it + supervises. A number of options that may be used in + this section are shared with other unit types. These + options are documented in + systemd.exec5. The + options specific to the [Socket] section of socket + units are the following: + + + + ListenStream= + ListenDatagram= + ListenSequentialPacket= + Specifies an address + to listen on for a stream + (SOCK_STREAM), datagram (SOCK_DGRAM) + resp. sequential packet + (SOCK_SEQPACKET) socket. The address + can be written in various formats: + + If the address starts with a + slash (/), it is read as file system + socket in the AF_UNIX socket + family. + + If the address starts with an + at symbol (@) it is read as abstract + namespace socket in the AF_UNIX + family. The @ is replaced with a NUL + character before binding. For details + see + unix7. + + If the address string is a + single number it is read as port + number to listen on for both IPv4 and + IPv6. + + If the address string is a + string in the format v.w.x.y:z it is + read as IPv4 specifier for listening + on an address v.w.x.y on a port + z. + + If the address string is a + string in the format [x]:y it is read + as IPv6 address x on a port y. + + Note that SOCK_SEQPACKET + (i.e. ListenSequentialPacket=) + is only available for AF_UNIX + sockets. SOCK_STREAM + (i.e. ListenStream=) + when used for IP sockets refers to TCP + sockets, SOCK_DGRAM + (i.e. ListenDatagram=) + to UDP. + + These options may be specified + more than once in which case incoming + traffic on any of the sockets will trigger + service activation, and all listed + sockets will be passed to the service, + regardless whether there is incoming + traffic on them or not. + + If an IP address is used here, it + is often desirable to listen on it + before the interface it is configured + on is up and running, and even + regardless whether it will be up and + running ever at all. To deal with this it is + recommended to set the + FreeBind= option + described below. + + + + ListenFIFO= + Specifies a file + system FIFO to listen on. This expects + an absolute file system path as + argument. Behaviour otherwise is very + similar to the + ListenDatagram= + directive above. + + + + ListenSpecial= + Specifies a special + file in the file system to listen + on. This expects an absolute file + system path as argument. Behaviour + otherwise is very similar to the + ListenFIFO= + directive above. Use this to open + character device nodes as well as + special files in + /proc and + /sys. + + + + ListenNetlink= + Specifies a Netlink + family to create a socket for to + listen on. This expects a short string + referring to the AF_NETLINK family + name (such as audit + or kobject-uevent) + as argument, optionally suffixed by a + whitespace followed by a multicast + group integer. Behaviour otherwise is + very similar to the + ListenDatagram= + directive above. + + + + ListenMessageQueue= + Specifies a POSIX + message queue name to listen on. This + expects a valid message queue name + (i.e. beginning with /). Behaviour + otherwise is very similar to the + ListenFIFO= + directive above. On Linux message + queue descriptors are actually file + descriptors and can be inherited + between processes. + + + + BindIPv6Only= + Takes a one of + , + or + . Controls + the IPV6_V6ONLY socket option (see + ipv67 + for details). If + , IPv6 sockets + bound will be accessible via both IPv4 + and IPv6. If + , they will + be accessible via IPv6 only. If + (which is the + default, surprise!) the system wide + default setting is used, as controlled + by + /proc/sys/net/ipv6/bindv6only. + + + + + Backlog= + Takes an unsigned + integer argument. Specifies the number + of connections to queue that have not + been accepted yet. This setting + matters only for stream and sequential + packet sockets. See + listen2 + for details. Defaults to SOMAXCONN + (128). + + + + BindToDevice= + Specifies a network + interface name to bind this socket + to. If set traffic will only be + accepted from the specified network + interfaces. This controls the + SO_BINDTODEVICE socket option (see + socket7 + for details). If this option is used, + an automatic dependency from this + socket unit on the network interface + device unit + (systemd.device5 + is created. + + + + DirectoryMode= + If listening on a file + system socket of FIFO, the parent + directories are automatically created + if needed. This option specifies the + file system access mode used when + creating these directories. Takes an + access mode in octal + notation. Defaults to + 0755. + + + + SocketMode= + If listening on a file + system socket of FIFO, this option + specifies the file system access mode + used when creating the file + node. Takes an access mode in octal + notation. Defaults to + 0666. + + + + Accept= + Takes a boolean + argument. If true, a service instance + is spawned for each incoming + connection and only the connection + socket is passed to it. If false, all + listening sockets themselves are + passed to the started service unit, + and only one service unit is spawned + for all connections (also see + above). This value is ignored for + datagram sockets and FIFOs where + a single service unit unconditionally + handles all incoming traffic. Defaults + to . For + performance reasons, it is recommended + to write new daemons only in a way + that is suitable for + . This + option is mostly useful to allow + daemons designed for usage with + inetd8, + to work unmodified with systemd socket + activation. + + + + MaxConnections= + The maximum number of + connections to simultaneously run + services instances for, when + is + set. If more concurrent connections + are coming in, they will be refused + until at least one existing connection + is terminated. This setting has no + effect for sockets configured with + or datagram + sockets. Defaults to + 64. + + + + KeepAlive= + Takes a boolean + argument. If true, the TCP/IP stack + will send a keep alive message after + 2h (depending on the configuration of + /proc/sys/net/ipv4/tcp_keepalive_time) + for all TCP streams accepted on this + socket. This controls the SO_KEEPALIVE + socket option (see + socket7 + and the TCP + Keepalive HOWTO for details.) + Defaults to + . + + + + Priority= + Takes an integer + argument controlling the priority for + all traffic sent from this + socket. This controls the SO_PRIORITY + socket option (see + socket7 + for details.). + + + + ReceiveBuffer= + SendBuffer= + Takes an integer + argument controlling the receive + resp. send buffer sizes of this + socket. This controls the SO_RCVBUF + resp. SO_SNDBUF socket options (see + socket7 + for details.). + + + + IPTOS= + Takes an integer + argument controlling the IP + Type-Of-Service field for packets + generated from this socket. This + controls the IP_TOS socket option (see + ip7 + for details.). Either a numeric string + or one of , + , + or + may be + specified. + + + + IPTTL= + Takes an integer + argument controlling the IPv4 + Time-To-Live/IPv6 Hop-Count field for + packets generated from this + socket. This sets the + IP_TTL/IPV6_UNICAST_HOPS socket + options (see + ip7 + and + ipv67 + for details.) + + + + Mark= + Takes an integer + value. Controls the firewall mark of + packets generated by this socket. This + can be used in the firewall logic to + filter packets from this socket. This + sets the SO_MARK socket option. See + iptables8 + for details. + + + + PipeSize= + Takes an integer + value. Controls the pipe buffer size + of FIFOs configured in this socket + unit. See + fcntl2 + for details. + + + + MessageQueueMaxMessages=, + MessageQueueMessageSize= + These two settings + take integer values and control the + mq_maxmsg resp. mq_msgsize field when + creating the message queue. Note that + either none or both of these variables + need to be set. See + mq_setattr3 + for details. + + + + FreeBind= + Takes a boolean + value. Controls whether the socket can + be bound to non-local IP + addresses. This is useful to configure + sockets listening on specific IP + addresses before those IP addresses + are successfully configured on a + network interface. This sets the + IP_FREEBIND socket option. For + robustness reasons it is recommended + to use this option whenever you bind a + socket to a specific IP + address. Defaults to . + + + + Transparent= + Takes a boolean + value. Controls the IP_TRANSPARENT + socket option. Defaults to + . + + + + Broadcast= + Takes a boolean + value. This controls the SO_BROADCAST + socket option, which allows broadcast + datagrams to be sent from this + socket. Defaults to + . + + + + PassCredentials= + Takes a boolean + value. This controls the SO_PASSCRED + socket option, which allows UNIX sockets to + receive the credentials of the sending + process in an ancillary message. + Defaults to + . + + + + TCPCongestion= + Takes a string + value. Controls the TCP congestion + algorithm used by this socket. Should + be one of "westwood", "veno", "cubic", + "lp" or any other available algorithm + supported by the IP stack. This + setting applies only to stream + sockets. + + + + ExecStartPre= + ExecStartPost= + Takes one or more + command lines, which are executed + before (resp. after) the listening + sockets/FIFOs are created and + bound. The first token of the command + line must be an absolute file name, + then followed by arguments for the + process. Multiple command lines may be + specified following the same scheme as + used for + ExecStartPre= of + service unit files. + + + + ExecStopPre= + ExecStopPost= + Additional commands + that are executed before (resp. after) + the listening sockets/FIFOs are closed + and removed. Multiple command lines + may be specified following the same + scheme as used for + ExecStartPre= of + service unit files. + + + + TimeoutSec= + Configures the time to + wait for the commands specified in + ExecStartPre=, + ExecStartPost=, + ExecStopPre= and + ExecStopPost= to + finish. If a command does not exit + within the configured time, the socket + will be considered failed and be shut + down again. All commands still running, + will be terminated forcibly via + SIGTERM, and after another delay of + this time with SIGKILL. (See + below.) + Takes a unit-less value in seconds, or + a time span value such as "5min + 20s". Pass 0 to disable the timeout + logic. Defaults to + 90s. + + + + KillMode= + Specifies how + processes of this socket unit shall be + killed. One of + , + , + . + + This option is mostly equivalent + to the + option of service files. See + systemd.service5 + for details. + + + + KillSignal= + Specifies which signal + to use when killing a process of this + socket. Defaults to SIGTERM. + + + + + SendSIGKILL= + Specifies whether to + send SIGKILL to remaining processes + after a timeout, if the normal + shutdown procedure left processes of + the socket around. Takes a boolean + value. Defaults to "yes". + + + + + Service= + Specifies the service + unit name to activate on incoming + traffic. This defaults to the service + that bears the same name as the socket + (ignoring the different suffixes). In + most cases it should not be necessary + to use this option. + + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.exec5, + systemd.service5 + + + + diff --git a/man/systemd.special.7.in b/man/systemd.special.7.in new file mode 100644 index 0000000..e1e552f --- /dev/null +++ b/man/systemd.special.7.in @@ -0,0 +1,422 @@ +'\" t +.\" Title: systemd.special +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd.special +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\&.SPECIAL" "7" "02/15/2012" "systemd" "systemd.special" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd.special \- special systemd units +.SH "SYNOPSIS" +.PP +basic\&.target, +ctrl\-alt\-del\&.target, +dbus\&.service, +default\&.target, +display\-manager\&.service, +emergency\&.target, +exit\&.service, +graphical\&.target, +halt\&.target, +kbrequest\&.target, +local\-fs\&.target, +local\-fs\-pre\&.target, +mail\-transfer\-agent\&.target, +multi\-user\&.target, +network\&.target, +nss\-lookup\&.target, +poweroff\&.target, +reboot\&.target, +remote\-fs\&.target, +remote\-fs\-pre\&.target, +rescue\&.target, +rpcbind\&.target, +runlevel2\&.target, +runlevel3\&.target, +runlevel4\&.target, +runlevel5\&.target, +shutdown\&.target, +sigpwr\&.target, +sockets\&.target, +swap\&.target, +sysinit\&.target, +syslog\&.target, +systemd\-initctl\&.service, +systemd\-initctl\&.socket, +systemd\-stdout\-syslog\-bridge\&.service, +systemd\-stdout\-syslog\-bridge\&.socket, +time\-sync\&.target, +umount\&.target +.SH "DESCRIPTION" +.PP +A few units are treated specially by systemd\&. They have special internal semantics and cannot be renamed\&. +.SH "SPECIAL SYSTEM UNITS" +.PP +basic\&.target +.RS 4 +A special target unit covering early boot\-up\&. +.sp +systemd automatically adds dependencies of the types Requires and After for this target unit to all SysV service units configured for runlevel 1 to 5\&. +.sp +Usually this should pull\-in all sockets, mount points, swap devices and other basic initialization necessary for the general purpose daemons\&. Most normal daemons should have dependencies of type After and Requires on this unit\&. +.RE +.PP +ctrl\-alt\-del\&.target +.RS 4 +systemd starts this target whenever Control+Alt+Del is pressed on the console\&. Usually this should be aliased (symlinked) to +reboot\&.target\&. +.RE +.PP +dbus\&.service +.RS 4 +A special unit for the D\-Bus system bus\&. As soon as this service is fully started up systemd will connect to it and register its service\&. +.RE +.PP +default\&.target +.RS 4 +The default unit systemd starts at bootup\&. Usually this should be aliased (symlinked) to +multi\-user\&.target +or +graphical\&.target\&. +.sp +The default unit systemd starts at bootup can be overridden with the +\fIsystemd\&.unit=\fR +kernel command line option\&. +.RE +.PP +display\-manager\&.service +.RS 4 +The display manager service\&. Usually this should be aliased (symlinked) to +xdm\&.service +or a similar display manager service\&. +.sp +systemd automatically adds dependencies of type After for this target unit to all SysV init script service units with a LSB header referring to the +$x\-display\-manager +facility, for compatibility with Debian\&. +.RE +.PP +emergency\&.target +.RS 4 +A special target unit that starts an emergency shell on the main console\&. This unit is supposed to be used with the kernel command line option +\fIsystemd\&.unit=\fR +and has otherwise little use\&. +.RE +.PP +graphical\&.target +.RS 4 +A special target unit for setting up a graphical login screen\&. This pulls in +multi\-user\&.target\&. +.sp +Units that are needed for graphical login shall add Wants dependencies for their unit to this unit (or +multi\-user\&.target) during installation\&. +.RE +.PP +halt\&.target +.RS 4 +A special target unit for shutting down and halting the system\&. +.sp +Applications wanting to halt the system should start this unit\&. +.RE +.PP +kbrequest\&.target +.RS 4 +systemd starts this target whenever Alt+ArrowUp is pressed on the console\&. This is a good candidate to be aliased (symlinked) to +rescue\&.target\&. +.RE +.PP +local\-fs\&.target +.RS 4 +systemd automatically adds dependencies of type After to all mount units that refer to local mount points for this target unit\&. In addition, systemd adds dependencies of type Wants to this target unit for those mounts listed in +/etc/fstab +that have the +\fBauto\fR +and +\fBcomment=systemd\&.mount\fR +mount options set\&. +.sp +systemd automatically adds dependencies of type After for this target unit to all SysV init script service units with an LSB header referring to the +$local_fs +facility\&. +.RE +.PP +local\-fs\-pre\&.target +.RS 4 +This target unit is automatically ordered before all local mount points marked with +\fBauto\fR +(see above)\&. It can be used to execute certain units before all local mounts\&. +.RE +.PP +mail\-transfer\-agent\&.target +.RS 4 +The mail transfer agent (MTA) service\&. Usually this should pull\-in all units necessary for sending/receiving mails on the local host\&. +.sp +systemd automatically adds dependencies of type After for this target unit to all SysV init script service units with an LSB header referring to the +$mail\-transfer\-agent +or +$mail\-transport\-agent +facilities, for compatibility with Debian\&. +.RE +.PP +multi\-user\&.target +.RS 4 +A special target unit for setting up a multi\-user system (non\-graphical)\&. This is pulled in by +graphical\&.target\&. +.sp +Units that are needed for a multi\-user system shall add Wants dependencies to this unit for their unit during installation\&. +.RE +.PP +network\&.target +.RS 4 +systemd automatically adds dependencies of type After for this target unit to all SysV init script service units with an LSB header referring to the +$network +facility\&. +.RE +.PP +nss\-lookup\&.target +.RS 4 +systemd automatically adds dependencies of type After for this target unit to all SysV init script service units with an LSB header referring to the +$named +facility\&. +.RE +.PP +poweroff\&.target +.RS 4 +A special target unit for shutting down and powering off the system\&. +.sp +Applications wanting to power off the system should start this unit\&. +.sp +runlevel0\&.target +is an alias for this target unit, for compatibility with SysV\&. +.RE +.PP +reboot\&.target +.RS 4 +A special target unit for shutting down and rebooting the system\&. +.sp +Applications wanting to reboot the system should start this unit\&. +.sp +runlevel6\&.target +is an alias for this target unit, for compatibility with SysV\&. +.RE +.PP +remote\-fs\&.target +.RS 4 +Similar to +local\-fs\&.target, but for remote mount points\&. +.sp +systemd automatically adds dependencies of type After for this target unit to all SysV init script service units with an LSB header referring to the +$remote_fs +facility\&. +.RE +.PP +remote\-fs\-pre\&.target +.RS 4 +This target unit is automatically ordered before all remote mount points marked with +\fBauto\fR +(see above)\&. It can be used to execute certain units before all remote mounts\&. +.RE +.PP +rescue\&.target +.RS 4 +A special target unit for setting up the base system and a rescue shell\&. +.sp +runlevel1\&.target +is an alias for this target unit, for compatibility with SysV\&. +.RE +.PP +rpcbind\&.target +.RS 4 +systemd automatically adds dependencies of type After for this target unit to all SysV init script service units with an LSB header referring to the +$rpcbind +facility\&. +.RE +.PP +runlevel2\&.target +.RS 4 +This is a target that is called whenever the SysV compatibility code asks for runlevel 2\&. It is a good idea to make this an alias for (i\&.e\&. symlink to) +multi\-user\&.target\&. +.RE +.PP +runlevel3\&.target +.RS 4 +This is a target that is called whenever the SysV compatibility code asks for runlevel 3\&. It is a good idea to make this an alias for (i\&.e\&. symlink to) +multi\-user\&.target +or +graphical\&.target\&. +.RE +.PP +runlevel4\&.target +.RS 4 +This is a target that is called whenever the SysV compatibility code asks for runlevel 4\&. It is a good idea to make this an alias for (i\&.e\&. symlink to) +multi\-user\&.target +or +graphical\&.target\&. +.RE +.PP +runlevel5\&.target +.RS 4 +This is a target that is called whenever the SysV compatibility code asks for runlevel 5\&. It is a good idea to make this an alias for (i\&.e\&. symlink to) +multi\-user\&.target +or +graphical\&.target\&. +.RE +.PP +shutdown\&.target +.RS 4 +A special target unit that terminates the services on system shutdown\&. +.sp +Services that shall be terminated on system shutdown shall add Conflicts dependencies to this unit for their service unit, which is implicitly done when +\fIDefaultDependencies=yes\fR +is set (the default)\&. +.sp +systemd automatically adds dependencies of type Conflicts to this target unit for all SysV init script service units that shall be terminated in SysV runlevels 0 or 6\&. +.RE +.PP +sigpwr\&.target +.RS 4 +A special target that is started when systemd receives the SIGPWR process signal, which is normally sent by the kernel or UPS daemons when power fails\&. +.RE +.PP +sockets\&.target +.RS 4 +A special target unit that sets up all service sockets\&. +.sp +Services that can be socket\-activated shall add Wants dependencies to this unit for their socket unit during installation\&. +.RE +.PP +swap\&.target +.RS 4 +Similar to +local\-fs\&.target, but for swap partitions and swap files\&. +.RE +.PP +sysinit\&.target +.RS 4 +A special target unit covering early boot\-up scripts\&. +.sp +systemd automatically adds dependencies of the types Wants and After for all SysV service units configured for runlevels that are not 0 to 6 to this target unit\&. This covers the special boot\-up runlevels some distributions have, such as S or b\&. +.RE +.PP +syslog\&.target +.RS 4 +systemd automatically adds dependencies of type After for this target unit to all SysV init script service units with an LSB header referring to the +$syslog +facility\&. +.RE +.PP +systemd\-initctl\&.service +.RS 4 +This provides compatibility with the SysV /dev/initctl file system FIFO for communication with the init system\&. +.sp +This is a socket\-activated service, see +system\-initctl\&.socket\&. +.RE +.PP +systemd\-initctl\&.socket +.RS 4 +Socket activation unit for +system\-initctl\&.service\&. +.RE +.PP +systemd\-stdout\-syslog\-bridge\&.service +.RS 4 +This is internally used by systemd to provide syslog logging to the processes it maintains\&. +.sp +This is a socket\-activated service, see +system\-stdout\-syslog\-bridge\&.socket\&. +.RE +.PP +systemd\-stdout\-syslog\-bridge\&.socket +.RS 4 +Socket activation unit for +system\-stdout\-syslog\-bridge\&.service\&. systemd will automatically add dependencies of types Requires and After to all units that have been configured for stdout or stderr to be connected to syslog or the kernel log buffer\&. +.RE +.PP +systemd\-shutdownd\&.service +.RS 4 +This is internally used by +\fBshutdown\fR(8) +to implement delayed shutdowns\&. +.sp +This is a socket\-activated service, see +system\-shutdownd\&.socket\&. +.RE +.PP +systemd\-shutdownd\&.socket +.RS 4 +Socket activation unit for +system\-shutdownd\&.service\&. +.RE +.PP +time\-sync\&.target +.RS 4 +systemd automatically adds dependencies of type After for this target unit to all SysV init script service units with an LSB header referring to the +$time +facility\&. +.RE +.PP +umount\&.target +.RS 4 +A special target unit that umounts all mount and automount points on system shutdown\&. +.sp +Mounts that shall be unmounted on system shutdown shall add Conflicts dependencies to this unit for their mount unit, which is implicitly done when +\fIDefaultDependencies=yes\fR +is set (the default)\&. +.RE +.SH "SPECIAL USER UNITS" +.PP +When systemd runs as a user instance, the following special units are available, which have similar definitions as their system counterparts: +default\&.target, +local\-fs\&.target, +remote\-fs\&.target, +shutdown\&.target, +sockets\&.target, +swap\&.target\&. +.PP +In addition the following special unit is understood only when systemd runs as service instance: +.PP +exit\&.service +.RS 4 +A special service unit for shutting down the user service manager\&. +.sp +Applications wanting to terminate the user service manager should start this unit\&. If systemd receives SIGTERM or SIGINT when running as user service daemon it will start this unit\&. +.sp +Normally, this pulls in +shutdown\&.target +which in turn should be conflicted by all units that want to be shut down on user service manager exit\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd.unit\fR(5), +\fBsystemd.service\fR(5), +\fBsystemd.socket\fR(5), +\fBsystemd.target\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd.special.html.in b/man/systemd.special.html.in new file mode 100644 index 0000000..ed731b7 --- /dev/null +++ b/man/systemd.special.html.in @@ -0,0 +1,361 @@ +systemd.special

Name

systemd.special — special systemd units

Synopsis

basic.target, + ctrl-alt-del.target, + dbus.service, + default.target, + display-manager.service, + emergency.target, + exit.service, + graphical.target, + halt.target, + kbrequest.target, + local-fs.target, + local-fs-pre.target, + mail-transfer-agent.target, + multi-user.target, + network.target, + nss-lookup.target, + poweroff.target, + reboot.target, + remote-fs.target, + remote-fs-pre.target, + rescue.target, + rpcbind.target, + runlevel2.target, + runlevel3.target, + runlevel4.target, + runlevel5.target, + shutdown.target, + sigpwr.target, + sockets.target, + swap.target, + sysinit.target, + syslog.target, + systemd-initctl.service, + systemd-initctl.socket, + systemd-stdout-syslog-bridge.service, + systemd-stdout-syslog-bridge.socket, + time-sync.target, + umount.target

Description

A few units are treated specially by + systemd. They have special internal semantics and + cannot be renamed.

Special System Units

basic.target

A special target unit + covering early boot-up.

systemd automatically + adds dependencies of the types + Requires and After for this + target unit to all SysV + service units configured for + runlevel 1 to 5.

Usually this should pull-in + all sockets, mount points, + swap devices and other basic + initialization necessary for + the general purpose + daemons. Most normal daemons + should have dependencies of + type After and Requires on + this unit.

ctrl-alt-del.target

systemd starts this + target whenever + Control+Alt+Del is pressed on + the console. Usually this + should be aliased (symlinked) + to + reboot.target.

dbus.service

A special unit for the + D-Bus system bus. As soon as + this service is fully started + up systemd will connect to it + and register its + service.

default.target

The default unit systemd + starts at bootup. Usually this + should be aliased (symlinked) + to + multi-user.target + or + graphical.target.

The default unit systemd + starts at bootup can be + overridden with the + systemd.unit= + kernel command line option.

display-manager.service

The display manager + service. Usually this should + be aliased (symlinked) to + xdm.service + or a similar display manager + service.

systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with a LSB header + referring to the + $x-display-manager + facility, for compatibility + with Debian.

emergency.target

A special target unit + that starts an emergency + shell on the main + console. This unit is supposed + to be used with the kernel + command line option + systemd.unit= + and has otherwise little use. +

graphical.target

A special target unit + for setting up a graphical + login screen. This pulls in + multi-user.target.

Units that are needed + for graphical login shall add + Wants dependencies for their + unit to this unit (or + multi-user.target) + during installation.

halt.target

A special target unit + for shutting down and halting the system.

Applications wanting to + halt the system should start + this unit.

kbrequest.target

systemd starts this + target whenever Alt+ArrowUp is + pressed on the console. This + is a good candidate to be + aliased (symlinked) to + rescue.target.

local-fs.target

systemd automatically + adds dependencies of type + After to all mount units that + refer to local mount points + for this target unit. In + addition, systemd adds + dependencies of type Wants to + this target unit for those + mounts listed in + /etc/fstab + that have the + auto and + comment=systemd.mount + mount options set.

systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $local_fs + facility.

local-fs-pre.target

This target unit is + automatically ordered before + all local mount points marked + with auto + (see above). It can be used to + execute certain units before + all local mounts.

mail-transfer-agent.target

The mail transfer agent + (MTA) service. Usually this + should pull-in all units + necessary for + sending/receiving mails on the + local host.

systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $mail-transfer-agent + or + $mail-transport-agent + facilities, for compatibility + with Debian.

multi-user.target

A special target unit + for setting up a multi-user + system (non-graphical). This + is pulled in by + graphical.target.

Units that are needed + for a multi-user system shall + add Wants dependencies to + this unit for their unit during + installation.

network.target

systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $network + facility.

nss-lookup.target

systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $named + facility.

poweroff.target

A special target unit + for shutting down and powering off the system.

Applications wanting to + power off the system should start + this unit.

runlevel0.target + is an alias for this target + unit, for compatibility with SysV.

reboot.target

A special target unit + for shutting down and rebooting the system.

Applications wanting to + reboot the system should start + this unit.

runlevel6.target + is an alias for this target + unit, for compatibility with SysV.

remote-fs.target

Similar to + local-fs.target, + but for remote mount + points.

systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $remote_fs + facility.

remote-fs-pre.target

This target unit is + automatically ordered before + all remote mount points marked + with auto + (see above). It can be used to + execute certain units before + all remote mounts.

rescue.target

A special target unit + for setting up the base system + and a rescue shell.

runlevel1.target + is an alias for this target + unit, for compatibility with SysV.

rpcbind.target

systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $rpcbind + facility.

runlevel2.target

This is a target that is + called whenever the SysV + compatibility code asks for + runlevel 2. It is a good idea + to make this an alias for + (i.e. symlink to) + multi-user.target.

runlevel3.target

This is a target that is + called whenever the SysV + compatibility code asks for + runlevel 3. It is a good idea + to make this an alias for + (i.e. symlink to) + multi-user.target + or + graphical.target.

runlevel4.target

This is a target that is + called whenever the SysV + compatibility code asks for + runlevel 4. It is a good idea + to make this an alias for + (i.e. symlink to) + multi-user.target + or + graphical.target.

runlevel5.target

This is a target that is + called whenever the SysV + compatibility code asks for + runlevel 5. It is a good idea + to make this an alias for + (i.e. symlink to) + multi-user.target + or + graphical.target.

shutdown.target

A special target unit + that terminates the services + on system shutdown.

Services that shall be + terminated on system shutdown + shall add Conflicts + dependencies to this unit for + their service unit, which is + implicitly done when + DefaultDependencies=yes + is set (the default).

systemd automatically + adds dependencies of type + Conflicts to this target unit + for all SysV init script + service units that shall be + terminated in SysV runlevels 0 + or 6.

sigpwr.target

A special target that is + started when systemd receives + the SIGPWR process signal, + which is normally sent by the + kernel or UPS daemons when + power fails.

sockets.target

A special target unit + that sets up all service + sockets.

Services that can be + socket-activated shall add + Wants dependencies to this + unit for their socket unit + during installation.

swap.target

Similar to + local-fs.target, but for swap + partitions and swap + files.

sysinit.target

A special target unit + covering early boot-up scripts.

systemd automatically + adds dependencies of the types + Wants and After for all + SysV service units configured + for runlevels that are not 0 + to 6 to this target unit. + This covers the special + boot-up runlevels some + distributions have, such as S + or b.

syslog.target

systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $syslog + facility.

systemd-initctl.service

This provides + compatibility with the SysV + /dev/initctl file system FIFO + for communication with the + init system.

This is a + socket-activated service, see + system-initctl.socket.

systemd-initctl.socket

Socket activation unit + for + system-initctl.service.

systemd-stdout-syslog-bridge.service

This is internally used + by systemd to provide syslog + logging to the processes it + maintains.

This is a + socket-activated service, see + system-stdout-syslog-bridge.socket.

systemd-stdout-syslog-bridge.socket

Socket activation unit + for + system-stdout-syslog-bridge.service. systemd + will automatically add + dependencies of types Requires + and After to all units that + have been configured for + stdout or stderr to be + connected to syslog or the + kernel log buffer.

systemd-shutdownd.service

This is internally used + by + shutdown(8) + to implement delayed shutdowns.

This is a + socket-activated service, see + system-shutdownd.socket.

systemd-shutdownd.socket

Socket activation unit + for + system-shutdownd.service.

time-sync.target

systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $time + facility.

umount.target

A special target unit + that umounts all mount and + automount points on system + shutdown.

Mounts that shall be + unmounted on system shutdown + shall add Conflicts + dependencies to this unit for + their mount unit, which is + implicitly done when + DefaultDependencies=yes + is set (the default).

Special User Units

When systemd runs as a user instance, the + following special units are available, which have + similar definitions as their system counterparts: + default.target, + local-fs.target, + remote-fs.target, + shutdown.target, + sockets.target, + swap.target.

In addition the following special unit is + understood only when systemd runs as service instance:

exit.service

A special service unit + for shutting down the + user service manager.

Applications wanting to + terminate the user service + manager should start this + unit. If systemd receives + SIGTERM or SIGINT when running + as user service daemon it will + start this unit.

Normally, this pulls in + shutdown.target + which in turn should be + conflicted by all units that + want to be shut down on + user service manager exit.

See Also

+ systemd.unit(5), + systemd.service(5), + systemd.socket(5), + systemd.target(5) +

diff --git a/man/systemd.special.xml.in b/man/systemd.special.xml.in new file mode 100644 index 0000000..116a43c --- /dev/null +++ b/man/systemd.special.xml.in @@ -0,0 +1,725 @@ + + + + + + + + + systemd.special + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.special + 7 + + + + systemd.special + special systemd units + + + + basic.target, + ctrl-alt-del.target, + dbus.service, + default.target, + display-manager.service, + emergency.target, + exit.service, + graphical.target, + halt.target, + kbrequest.target, + local-fs.target, + local-fs-pre.target, + mail-transfer-agent.target, + multi-user.target, + network.target, + nss-lookup.target, + poweroff.target, + reboot.target, + remote-fs.target, + remote-fs-pre.target, + rescue.target, + rpcbind.target, + runlevel2.target, + runlevel3.target, + runlevel4.target, + runlevel5.target, + shutdown.target, + sigpwr.target, + sockets.target, + swap.target, + sysinit.target, + syslog.target, + systemd-initctl.service, + systemd-initctl.socket, + systemd-stdout-syslog-bridge.service, + systemd-stdout-syslog-bridge.socket, + time-sync.target, + umount.target + + + + Description + + A few units are treated specially by + systemd. They have special internal semantics and + cannot be renamed. + + + + Special System Units + + + + basic.target + + A special target unit + covering early boot-up. + systemd automatically + adds dependencies of the types + Requires and After for this + target unit to all SysV + service units configured for + runlevel 1 to 5. + Usually this should pull-in + all sockets, mount points, + swap devices and other basic + initialization necessary for + the general purpose + daemons. Most normal daemons + should have dependencies of + type After and Requires on + this unit. + + + + ctrl-alt-del.target + + systemd starts this + target whenever + Control+Alt+Del is pressed on + the console. Usually this + should be aliased (symlinked) + to + reboot.target. + + + + dbus.service + + A special unit for the + D-Bus system bus. As soon as + this service is fully started + up systemd will connect to it + and register its + service. + + + + default.target + + The default unit systemd + starts at bootup. Usually this + should be aliased (symlinked) + to + multi-user.target + or + graphical.target. + The default unit systemd + starts at bootup can be + overridden with the + systemd.unit= + kernel command line option. + + + + display-manager.service + + The display manager + service. Usually this should + be aliased (symlinked) to + xdm.service + or a similar display manager + service. + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with a LSB header + referring to the + $x-display-manager + facility, for compatibility + with Debian. + + + + emergency.target + + A special target unit + that starts an emergency + shell on the main + console. This unit is supposed + to be used with the kernel + command line option + systemd.unit= + and has otherwise little use. + + + + + graphical.target + + A special target unit + for setting up a graphical + login screen. This pulls in + multi-user.target. + + Units that are needed + for graphical login shall add + Wants dependencies for their + unit to this unit (or + multi-user.target) + during installation. + + + + halt.target + + A special target unit + for shutting down and halting the system. + + Applications wanting to + halt the system should start + this unit. + + + + kbrequest.target + + systemd starts this + target whenever Alt+ArrowUp is + pressed on the console. This + is a good candidate to be + aliased (symlinked) to + rescue.target. + + + + local-fs.target + + systemd automatically + adds dependencies of type + After to all mount units that + refer to local mount points + for this target unit. In + addition, systemd adds + dependencies of type Wants to + this target unit for those + mounts listed in + /etc/fstab + that have the + and + + mount options set. + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $local_fs + facility. + + + + local-fs-pre.target + + This target unit is + automatically ordered before + all local mount points marked + with + (see above). It can be used to + execute certain units before + all local mounts. + + + + mail-transfer-agent.target + + The mail transfer agent + (MTA) service. Usually this + should pull-in all units + necessary for + sending/receiving mails on the + local host. + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $mail-transfer-agent + or + $mail-transport-agent + facilities, for compatibility + with Debian. + + + + multi-user.target + + A special target unit + for setting up a multi-user + system (non-graphical). This + is pulled in by + graphical.target. + + Units that are needed + for a multi-user system shall + add Wants dependencies to + this unit for their unit during + installation. + + + + network.target + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $network + facility. + + + + nss-lookup.target + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $named + facility. + + + + poweroff.target + + A special target unit + for shutting down and powering off the system. + + Applications wanting to + power off the system should start + this unit. + + runlevel0.target + is an alias for this target + unit, for compatibility with SysV. + + + + reboot.target + + A special target unit + for shutting down and rebooting the system. + + Applications wanting to + reboot the system should start + this unit. + + runlevel6.target + is an alias for this target + unit, for compatibility with SysV. + + + + remote-fs.target + + Similar to + local-fs.target, + but for remote mount + points. + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $remote_fs + facility. + + + + remote-fs-pre.target + + This target unit is + automatically ordered before + all remote mount points marked + with + (see above). It can be used to + execute certain units before + all remote mounts. + + + + rescue.target + + A special target unit + for setting up the base system + and a rescue shell. + + runlevel1.target + is an alias for this target + unit, for compatibility with SysV. + + + + rpcbind.target + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $rpcbind + facility. + + + + runlevel2.target + + This is a target that is + called whenever the SysV + compatibility code asks for + runlevel 2. It is a good idea + to make this an alias for + (i.e. symlink to) + multi-user.target. + + + + runlevel3.target + + This is a target that is + called whenever the SysV + compatibility code asks for + runlevel 3. It is a good idea + to make this an alias for + (i.e. symlink to) + multi-user.target + or + graphical.target. + + + + runlevel4.target + + This is a target that is + called whenever the SysV + compatibility code asks for + runlevel 4. It is a good idea + to make this an alias for + (i.e. symlink to) + multi-user.target + or + graphical.target. + + + + runlevel5.target + + This is a target that is + called whenever the SysV + compatibility code asks for + runlevel 5. It is a good idea + to make this an alias for + (i.e. symlink to) + multi-user.target + or + graphical.target. + + + + shutdown.target + + A special target unit + that terminates the services + on system shutdown. + + Services that shall be + terminated on system shutdown + shall add Conflicts + dependencies to this unit for + their service unit, which is + implicitly done when + DefaultDependencies=yes + is set (the default). + + systemd automatically + adds dependencies of type + Conflicts to this target unit + for all SysV init script + service units that shall be + terminated in SysV runlevels 0 + or 6. + + + + sigpwr.target + + A special target that is + started when systemd receives + the SIGPWR process signal, + which is normally sent by the + kernel or UPS daemons when + power fails. + + + + sockets.target + + A special target unit + that sets up all service + sockets. + + Services that can be + socket-activated shall add + Wants dependencies to this + unit for their socket unit + during installation. + + + + swap.target + + Similar to + local-fs.target, but for swap + partitions and swap + files. + + + + sysinit.target + + A special target unit + covering early boot-up scripts. + systemd automatically + adds dependencies of the types + Wants and After for all + SysV service units configured + for runlevels that are not 0 + to 6 to this target unit. + This covers the special + boot-up runlevels some + distributions have, such as S + or b. + + + + syslog.target + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $syslog + facility. + + + + systemd-initctl.service + + This provides + compatibility with the SysV + /dev/initctl file system FIFO + for communication with the + init system. + This is a + socket-activated service, see + system-initctl.socket. + + + + systemd-initctl.socket + + Socket activation unit + for + system-initctl.service. + + + + systemd-stdout-syslog-bridge.service + + This is internally used + by systemd to provide syslog + logging to the processes it + maintains. + This is a + socket-activated service, see + system-stdout-syslog-bridge.socket. + + + + systemd-stdout-syslog-bridge.socket + + Socket activation unit + for + system-stdout-syslog-bridge.service. systemd + will automatically add + dependencies of types Requires + and After to all units that + have been configured for + stdout or stderr to be + connected to syslog or the + kernel log buffer. + + + + systemd-shutdownd.service + + This is internally used + by + shutdown8 + to implement delayed shutdowns. + This is a + socket-activated service, see + system-shutdownd.socket. + + + + systemd-shutdownd.socket + + Socket activation unit + for + system-shutdownd.service. + + + + time-sync.target + + systemd automatically + adds dependencies of type + After for this target unit to + all SysV init script service + units with an LSB header + referring to the + $time + facility. + + + + umount.target + + A special target unit + that umounts all mount and + automount points on system + shutdown. + + Mounts that shall be + unmounted on system shutdown + shall add Conflicts + dependencies to this unit for + their mount unit, which is + implicitly done when + DefaultDependencies=yes + is set (the default). + + + + + + + Special User Units + + When systemd runs as a user instance, the + following special units are available, which have + similar definitions as their system counterparts: + default.target, + local-fs.target, + remote-fs.target, + shutdown.target, + sockets.target, + swap.target. + + In addition the following special unit is + understood only when systemd runs as service instance: + + + + exit.service + + A special service unit + for shutting down the + user service manager. + + Applications wanting to + terminate the user service + manager should start this + unit. If systemd receives + SIGTERM or SIGINT when running + as user service daemon it will + start this unit. + + Normally, this pulls in + shutdown.target + which in turn should be + conflicted by all units that + want to be shut down on + user service manager exit. + + + + + + + See Also + + systemd.unit5, + systemd.service5, + systemd.socket5, + systemd.target5 + + + + diff --git a/man/systemd.swap.5 b/man/systemd.swap.5 new file mode 100644 index 0000000..9b6571a --- /dev/null +++ b/man/systemd.swap.5 @@ -0,0 +1,142 @@ +'\" t +.\" Title: systemd.swap +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd.swap +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\&.SWAP" "5" "02/15/2012" "systemd" "systemd.swap" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd.swap \- systemd swap configuration files +.SH "SYNOPSIS" +.PP +systemd\&.swap +.SH "DESCRIPTION" +.PP +A unit configuration file whose name ends in +\&.swap +encodes information about a swap device or file for memory paging controlled and supervised by systemd\&. +.PP +This man page lists the configuration options specific to this unit type\&. See +\fBsystemd.unit\fR(5) +for the common options of all unit configuration files\&. The common configuration items are configured in the generic [Unit] and [Install] sections\&. The swap specific configuration options are configured in the [Swap] section\&. +.PP +Swap units must be named after the devices (resp\&. files) they control\&. Example: the swap device +/dev/sda5 +must be configured in a unit file +dev\-sda5\&.swap\&. For details about the escaping logic used to convert a file system path to a unit name see +\fBsystemd.unit\fR(5)\&. +.PP +All swap units automatically get the appropriate dependencies on the devices (resp\&. on the mount points of the files) they are activated from\&. +.PP +Swap units with +\fIDefaultDependencies=\fR +enabled implicitly acquire a conflicting dependency to +umount\&.target +so that they are deactivated at shutdown\&. +.SH "FSTAB" +.PP +Swap units may either be configured via unit files, or via +/etc/fstab +(see +\fBfstab\fR(5) +for details)\&. +.PP +If a swap device or file is configured in both +/etc/fstab +and a unit file the configuration in the latter takes precedence\&. +.PP +Unless the +\fBnoauto\fR +option is set for them all swap units configured in +/etc/fstab +are also added as requirements to +swap\&.target, so that they are waited for and activated during boot\&. +.SH "OPTIONS" +.PP +Swap files must include a [Swap] section, which carries information about the swap device it supervises\&. A number of options that may be used in this section are shared with other unit types\&. These options are documented in +\fBsystemd.exec\fR(5)\&. The options specific to the [Swap] section of swap units are the following: +.PP +\fIWhat=\fR +.RS 4 +Takes an absolute path of a device node or file to use for paging\&. See +\fBswapon\fR(8) +for details\&. If this refers to a device node, a dependency on the respective device unit is automatically created\&. (See +\fBsystemd.device\fR(5) +for more information\&.) If this refers to a file, a dependency on the respective mount unit is automatically created\&. (See +\fBsystemd.mount\fR(5) +for more information\&.) This option is mandatory\&. +.RE +.PP +\fIPriority=\fR +.RS 4 +Swap priority to use when activating the swap device or file\&. This takes an integer\&. This setting is optional\&. +.RE +.PP +\fITimeoutSec=\fR +.RS 4 +Configures the time to wait for the swapon command to finish\&. If a command does not exit within the configured time the swap will be considered failed and be shut down again\&. All commands still running will be terminated forcibly via SIGTERM, and after another delay of this time with SIGKILL\&. (See +\fBKillMode=\fR +below\&.) Takes a unit\-less value in seconds, or a time span value such as "5min 20s"\&. Pass 0 to disable the timeout logic\&. Defaults to 90s\&. +.RE +.PP +\fIKillMode=\fR +.RS 4 +Specifies how processes of this swap shall be killed\&. One of +\fBcontrol\-group\fR, +\fBprocess\fR, +\fBnone\fR\&. +.sp +This option is mostly equivalent to the +\fBKillMode=\fR +option of service files\&. See +\fBsystemd.service\fR(5) +for details\&. +.RE +.PP +\fIKillSignal=\fR +.RS 4 +Specifies which signal to use when killing a process of this swap\&. Defaults to SIGTERM\&. +.RE +.PP +\fISendSIGKILL=\fR +.RS 4 +Specifies whether to send SIGKILL to remaining processes after a timeout, if the normal shutdown procedure left processes of the swap around\&. Takes a boolean value\&. Defaults to "yes"\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(8), +\fBsystemd.unit\fR(5), +\fBsystemd.exec\fR(5), +\fBsystemd.device\fR(5), +\fBsystemd.mount\fR(5), +\fBswapon\fR(8) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml new file mode 100644 index 0000000..ab00f9f --- /dev/null +++ b/man/systemd.swap.xml @@ -0,0 +1,222 @@ + + + + + + + + + systemd.swap + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.swap + 5 + + + + systemd.swap + systemd swap configuration files + + + + systemd.swap + + + + Description + + A unit configuration file whose name ends in + .swap encodes information about a + swap device or file for memory paging controlled and + supervised by systemd. + + This man page lists the configuration options + specific to this unit type. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. The swap + specific configuration options are configured in the + [Swap] section. + + Swap units must be named after the devices + (resp. files) they control. Example: the swap device + /dev/sda5 must be configured in a + unit file dev-sda5.swap. For + details about the escaping logic used to convert a + file system path to a unit name see + systemd.unit5. + + All swap units automatically get the appropriate + dependencies on the devices (resp. on the mount points + of the files) they are activated from. + + Swap units with + DefaultDependencies= enabled + implicitly acquire a conflicting dependency to + umount.target so that they are + deactivated at shutdown. + + + + <filename>fstab</filename> + + Swap units may either be configured via unit + files, or via /etc/fstab (see + fstab5 + for details). + + If a swap device or file is configured in both + /etc/fstab and a unit file the + configuration in the latter takes precedence. + + Unless the option is set + for them all swap units configured in + /etc/fstab are also added as + requirements to swap.target, so + that they are waited for and activated during + boot. + + + + Options + + Swap files must include a [Swap] section, which + carries information about the swap device it + supervises. A number of options that may be used in + this section are shared with other unit types. These + options are documented in + systemd.exec5. The + options specific to the [Swap] section of swap units + are the following: + + + + + What= + Takes an absolute path + of a device node or file to use for + paging. See + swapon8 + for details. If this refers to a + device node, a dependency on the + respective device unit is + automatically created. (See + systemd.device5 + for more information.) If this refers + to a file, a dependency on the + respective mount unit is automatically + created. (See + systemd.mount5 + for more information.) This option is + mandatory. + + + + Priority= + + Swap priority to use + when activating the swap device or + file. This takes an integer. This + setting is optional. + + + + TimeoutSec= + Configures the time to + wait for the swapon command to + finish. If a command does not exit + within the configured time the swap + will be considered failed and be shut + down again. All commands still running + will be terminated forcibly via + SIGTERM, and after another delay of + this time with SIGKILL. (See + below.) + Takes a unit-less value in seconds, or + a time span value such as "5min + 20s". Pass 0 to disable the timeout + logic. Defaults to + 90s. + + + + KillMode= + Specifies how + processes of this swap shall be + killed. One of + , + , + . + + This option is mostly equivalent + to the + option of service files. See + systemd.service5 + for details. + + + + KillSignal= + Specifies which signal + to use when killing a process of this + swap. Defaults to SIGTERM. + + + + + SendSIGKILL= + Specifies whether to + send SIGKILL to remaining processes + after a timeout, if the normal + shutdown procedure left processes of + the swap around. Takes a boolean + value. Defaults to "yes". + + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.exec5, + systemd.device5, + systemd.mount5, + swapon8 + + + + diff --git a/man/systemd.target.5 b/man/systemd.target.5 new file mode 100644 index 0000000..6d33aec --- /dev/null +++ b/man/systemd.target.5 @@ -0,0 +1,74 @@ +'\" t +.\" Title: systemd.target +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd.target +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\&.TARGET" "5" "02/15/2012" "systemd" "systemd.target" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd.target \- systemd target configuration files +.SH "SYNOPSIS" +.PP +systemd\&.target +.SH "DESCRIPTION" +.PP +A unit configuration file whose name ends in +\&.target +encodes information about a target unit of systemd, which is used for grouping units and as well\-known synchronization points during start\-up\&. +.PP +This unit type has no specific options\&. See +\fBsystemd.unit\fR(5) +for the common options of all unit configuration files\&. The common configuration items are configured in the generic [Unit] and [Install] sections\&. A separate [Target] section does not exist, since no target\-specific options may be configured\&. +.PP +Target units do not offer any additional functionality on top of the generic functionality provided by units\&. They exist merely to group units via dependencies (useful as boot targets), and to establish standardized names for synchronization points used in dependencies between units\&. Among other things, target units are a more flexible replacement for SysV runlevels in the classic SysV init system\&. (And for compatibility reasons special target units such as +runlevel3\&.target +exist which are used by the SysV runlevel compatibility code in systemd\&. See +\fBsystemd.special\fR(7) +for details)\&. +.PP +Unless +\fIDefaultDependencies=\fR +is set to +\fBfalse\fR, target units will implicitly complement all configured dependencies of type +\fIWants=\fR, +\fIRequires=\fR, +\fIRequiresOverridable=\fR +with dependencies of type +\fIAfter=\fR +if the units in question also have +\fIDefaultDependencies=true\fR\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(8), +\fBsystemd.unit\fR(5), +\fBsystemd.special\fR(7) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd.target.xml b/man/systemd.target.xml new file mode 100644 index 0000000..6b1dbfb --- /dev/null +++ b/man/systemd.target.xml @@ -0,0 +1,108 @@ + + + + + + + + + systemd.target + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.target + 5 + + + + systemd.target + systemd target configuration files + + + + systemd.target + + + + Description + + A unit configuration file whose name ends in + .target encodes information about + a target unit of systemd, which is used for grouping + units and as well-known synchronization points during + start-up. + + This unit type has no specific options. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. A + separate [Target] section does not exist, since no + target-specific options may be configured. + + Target units do not offer any additional + functionality on top of the generic functionality + provided by units. They exist merely to group units via dependencies + (useful as boot targets), and to establish + standardized names for synchronization points used in + dependencies between units. Among other things, target + units are a more flexible replacement for SysV + runlevels in the classic SysV init system. (And for + compatibility reasons special + target units such as + runlevel3.target exist which are used by + the SysV runlevel compatibility code in systemd. See + systemd.special7 + for details). + + Unless DefaultDependencies= + is set to , target units will + implicitly complement all configured dependencies of + type Wants=, + Requires=, + RequiresOverridable= with + dependencies of type After= if the + units in question also have + DefaultDependencies=true. + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.special7 + + + + diff --git a/man/systemd.timer.5 b/man/systemd.timer.5 new file mode 100644 index 0000000..016dd68 --- /dev/null +++ b/man/systemd.timer.5 @@ -0,0 +1,114 @@ +'\" t +.\" Title: systemd.timer +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd.timer +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\&.TIMER" "5" "02/15/2012" "systemd" "systemd.timer" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd.timer \- systemd timer configuration files +.SH "SYNOPSIS" +.PP +systemd\&.timer +.SH "DESCRIPTION" +.PP +A unit configuration file whose name ends in +\&.timer +encodes information about a timer controlled and supervised by systemd, for timer\-based activation\&. +.PP +This man page lists the configuration options specific to this unit type\&. See +\fBsystemd.unit\fR(5) +for the common options of all unit configuration files\&. The common configuration items are configured in the generic [Unit] and [Install] sections\&. The timer specific configuration options are configured in the [Timer] section\&. +.PP +For each timer file, a matching unit file must exist, describing the unit to activate when the timer elapses\&. By default, a service by the same name as the timer (except for the suffix) is activated\&. Example: a timer file +foo\&.timer +activates a matching service +foo\&.service\&. The unit to activate may be controlled by +\fIUnit=\fR +(see below)\&. +.PP +Unless +\fIDefaultDependencies=\fR +is set to +\fBfalse\fR, timer units will implicitly have dependencies of type +\fIConflicts=\fR +and +\fIBefore=\fR +on +shutdown\&.target\&. These ensure that timer units are stopped cleanly prior to system shutdown\&. Only timer units involved with early boot or late system shutdown should disable this option\&. +.SH "OPTIONS" +.PP +Timer files must include a [Timer] section, which carries information about the timer it defines\&. The options specific to the [Timer] section of timer units are the following: +.PP +\fIOnActiveSec=\fR, \fIOnBootSec=\fR, \fIOnStartupSec=\fR, \fIOnUnitActiveSec=\fR, \fIOnUnitInactiveSec=\fR +.RS 4 +Defines timers relative to different starting points: +\fIOnActiveSec=\fR +defines a timer relative to the moment the timer itself is activated\&. +\fIOnBootSec=\fR +defines a timer relative to when the machine was booted up\&. +\fIOnStartupSec=\fR +defines a timer relative to when systemd was started\&. +\fIOnUnitActiveSec=\fR +defines a timer relative to when the unit the timer is activating was last activated\&. +\fIOnUnitInactiveSec=\fR +defines a timer relative to when the unit the timer is activating was last deactivated\&. +.sp +Multiple directives may be combined of the same and of different types\&. For example, by combining +\fIOnBootSec=\fR +and +\fIOnUnitActiveSec=\fR +it is possible to define a timer that elapses in regular intervals and activates a specific service each time\&. +.sp +The arguments to the directives are time spans configured in seconds\&. Example: "OnBootSec=50" means 50s after boot\-up\&. The argument may also include time units\&. Example: "OnBootSec=5h 30min" means 5 hours and 30 minutes after boot\-up\&. For details about the syntax of time spans see +\fBsystemd.unit\fR(5)\&. +.sp +If a timer configured with +\fIOnBootSec=\fR +or +\fIOnStartupSec=\fR +is already in the past when the timer unit is activated, it will immediately elapse and the configured unit is started\&. This is not the case for timers defined in the other directives\&. +.PP +These are monotonic timers, independent of wall\-clock time and timezones\&. If the computer is temporarily suspended, the monotonic clock stops too\&. +.RE +.PP +\fIUnit=\fR +.RS 4 +The unit to activate when this timer elapses\&. The argument is a unit name, whose suffix is not +\&.timer\&. If not specified, this value defaults to a service that has the same name as the timer unit, except for the suffix\&. (See above\&.) It is recommended that the unit name that is activated and the unit name of the timer unit are named identically, except for the suffix\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(8), +\fBsystemd.unit\fR(5), +\fBsystemd.service\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml new file mode 100644 index 0000000..9b6b486 --- /dev/null +++ b/man/systemd.timer.xml @@ -0,0 +1,192 @@ + + + + + + + + + systemd.timer + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.timer + 5 + + + + systemd.timer + systemd timer configuration files + + + + systemd.timer + + + + Description + + A unit configuration file whose name ends in + .timer encodes information about + a timer controlled and supervised by systemd, for + timer-based activation. + + This man page lists the configuration options + specific to this unit type. See + systemd.unit5 + for the common options of all unit configuration + files. The common configuration items are configured + in the generic [Unit] and [Install] sections. The + timer specific configuration options are configured in + the [Timer] section. + + For each timer file, a matching unit file must + exist, describing the unit to activate when the timer + elapses. By default, a service by the same name as the + timer (except for the suffix) is activated. Example: a + timer file foo.timer activates a + matching service foo.service. The + unit to activate may be controlled by + Unit= (see below). + + Unless DefaultDependencies= + is set to , timer units will + implicitly have dependencies of type + Conflicts= and + Before= on + shutdown.target. These ensure + that timer units are stopped cleanly prior to system + shutdown. Only timer units involved with early boot or + late system shutdown should disable this + option. + + + + Options + + Timer files must include a [Timer] section, + which carries information about the timer it + defines. The options specific to the [Timer] section + of timer units are the following: + + + + OnActiveSec= + OnBootSec= + OnStartupSec= + OnUnitActiveSec= + OnUnitInactiveSec= + + Defines timers + relative to different starting points: + OnActiveSec= defines a + timer relative to the moment the timer + itself is + activated. OnBootSec= + defines a timer relative to when the + machine was booted + up. OnStartupSec= + defines a timer relative to when + systemd was + started. OnUnitActiveSec= + defines a timer relative to when the + unit the timer is activating was last + activated. OnUnitInactiveSec= + defines a timer relative to when the + unit the timer is activating was last + deactivated. + + Multiple directives may be + combined of the same and of different + types. For example, by combining + OnBootSec= and + OnUnitActiveSec= it is + possible to define a timer that + elapses in regular intervals and + activates a specific service each + time. + + The arguments to the directives + are time spans configured in + seconds. Example: "OnBootSec=50" means + 50s after boot-up. The argument may + also include time units. Example: + "OnBootSec=5h 30min" means 5 hours and 30 + minutes after boot-up. For details + about the syntax of time spans see + systemd.unit5. + + If a timer configured with + OnBootSec= or + OnStartupSec= is + already in the past when the timer + unit is activated, it will immediately + elapse and the configured unit is + started. This is not the case for + timers defined in the other + directives. + + These are monotonic timers, + independent of wall-clock time and timezones. If the + computer is temporarily suspended, the + monotonic clock stops too. + + + + Unit= + + The unit to activate + when this timer elapses. The argument is a + unit name, whose suffix is not + .timer. If not + specified, this value defaults to a + service that has the same name as the + timer unit, except for the + suffix. (See above.) It is recommended + that the unit name that is activated + and the unit name of the timer unit + are named identically, except for the + suffix. + + + + + + See Also + + systemd1, + systemctl8, + systemd.unit5, + systemd.service5 + + + + diff --git a/man/systemd.unit.5 b/man/systemd.unit.5 new file mode 100644 index 0000000..10b4f1b --- /dev/null +++ b/man/systemd.unit.5 @@ -0,0 +1,577 @@ +'\" t +.\" Title: systemd.unit +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: systemd.unit +.\" Source: systemd +.\" Language: English +.\" +.TH "SYSTEMD\&.UNIT" "5" "02/15/2012" "systemd" "systemd.unit" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +systemd.unit \- systemd unit configuration files +.SH "SYNOPSIS" +.PP +systemd\&.service, +systemd\&.socket, +systemd\&.device, +systemd\&.mount, +systemd\&.automount, +systemd\&.swap, +systemd\&.target, +systemd\&.path, +systemd\&.timer, +systemd\&.snapshot +.SH "DESCRIPTION" +.PP +A unit configuration file encodes information about a service, a socket, a device, a mount point, an automount point, a swap file or partition, a start\-up target, a file system path or a timer controlled and supervised by +\fBsystemd\fR(1)\&. The syntax is inspired by +\m[blue]\fBXDG Desktop Entry Specification\fR\m[]\&\s-2\u[1]\d\s+2 +\&.desktop +files, which are in turn inspired by Microsoft Windows +\&.ini +files\&. +.PP +This man pages lists the common configuration options of all the unit types\&. These options need to be configured in the [Unit] resp\&. [Install] section of the unit files\&. +.PP +In addition to the generic [Unit] and [Install] sections described here, each unit should have a type\-specific section, e\&.g\&. [Service] for a service unit\&. See the respective man pages for more information\&. +.PP +Unit files may contain additional options on top of those listed here\&. If systemd encounters an unknown option it will write a warning log message but continue loading the unit\&. If an option is prefixed with +\fBX\-\fR +it is ignored completely by systemd\&. Applications may use this to include additional information in the unit files\&. +.PP +Boolean arguments used in unit files can be written in various formats\&. For positive settings the strings +\fB1\fR, +\fByes\fR, +\fBtrue\fR +and +\fBon\fR +are equivalent\&. For negative settings the strings +\fB0\fR, +\fBno\fR, +\fBfalse\fR +and +\fBoff\fR +are equivalent\&. +.PP +Time span values encoded in unit files can be written in various formats\&. A stand\-alone number specifies a time in seconds\&. If suffixed with a time unit, the unit is honored\&. A concatenation of multiple values with units is supported, in which case the values are added up\&. Example: "50" refers to 50 seconds; "2min 200ms" refers to 2 minutes plus 200 milliseconds, i\&.e\&. 120200ms\&. The following time units are understood: s, min, h, d, w, ms, us\&. +.PP +Empty lines and lines starting with # or ; are ignored\&. This may be used for commenting\&. Lines ending in a backslash are concatenated with the following line while reading and the backslash is replaced by a space character\&. This may be used to wrap long lines\&. +.PP +If a line starts with +\fB\&.include\fR +followed by a file name, the specified file will be parsed at this point\&. Make sure that the file that is included has the appropiate section headers before any directives\&. +.PP +Along with a unit file +foo\&.service +a directory +foo\&.service\&.wants/ +may exist\&. All units symlinked from such a directory are implicitly added as dependencies of type +\fIWanted=\fR +to the unit\&. This is useful to hook units into the start\-up of other units, without having to modify their unit configuration files\&. For details about the semantics of +\fIWanted=\fR +see below\&. The preferred way to create symlinks in the +\&.wants/ +directory of a service is with the +\fBenable\fR +command of the +\fBsystemctl\fR(1) +tool which reads information from the [Install] section of unit files\&. (See below\&.) A similar functionality exists for +\fIRequires=\fR +type dependencies as well, the directory suffix is +\&.requires/ +in this case\&. +.PP +Note that while systemd offers a flexible dependency system between units it is recommended to use this functionality only sparsely and instead rely on techniques such as bus\-based or socket\-based activation which makes dependencies implicit, which both results in a simpler and more flexible system\&. +.PP +Some unit names reflect paths existing in the file system name space\&. Example: a device unit +dev\-sda\&.device +refers to a device with the device node +/dev/sda +in the file system namespace\&. If this applies a special way to escape the path name is used, so that the result is usable as part of a file name\&. Basically, given a path, "/" is replaced by "\-", and all unprintable characters and the "\-" are replaced by C\-style "\ex20" escapes\&. The root directory "/" is encoded as single dash, while otherwise the initial and ending "/" is removed from all paths during transformation\&. This escaping is reversible\&. +.PP +Optionally, units may be instantiated from a template file at runtime\&. This allows creation of multiple units from a single configuration file\&. If systemd looks for a unit configuration file it will first search for the literal unit name in the filesystem\&. If that yields no success and the unit name contains an @ character, systemd will look for a unit template that shares the same name but with the instance string (i\&.e\&. the part between the @ character and the suffix) removed\&. Example: if a service +getty@tty3\&.service +is requested and no file by that name is found, systemd will look for +getty@\&.service +and instantiate a service from that configuration file if it is found\&. +.PP +To refer to the instance string from within the configuration file you may use the special +%i +specifier in many of the configuration options\&. Other specifiers exist, the full list is: +.sp +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.B Table\ \&1.\ \&Specifiers available in unit files +.TS +allbox tab(:); +lB lB lB. +T{ +Specifier +T}:T{ +Meaning +T}:T{ +Details +T} +.T& +l l l +l l l +l l l +l l l +l l l +l l l +l l l +l l l +l l l +l l l +l l l. +T{ +%n +T}:T{ +Full unit name +T}:T{ +\ \& +T} +T{ +%N +T}:T{ +Unescaped full unit name +T}:T{ +\ \& +T} +T{ +%p +T}:T{ +Prefix name +T}:T{ +This refers to the string before the @, i\&.e\&. "getty" in the example above, where "tty3" is the instance name\&. +T} +T{ +%P +T}:T{ +Unescaped prefix name +T}:T{ +\ \& +T} +T{ +%i +T}:T{ +Instance name +T}:T{ +This is the string between the @ character and the suffix\&. +T} +T{ +%I +T}:T{ +Unescaped instance name +T}:T{ +\ \& +T} +T{ +%f +T}:T{ +Unescaped file name +T}:T{ +This is either the unescaped instance name (if set) with / prepended (if necessary), or the prefix name similarly prepended with /\&. +T} +T{ +%c +T}:T{ +Control group path of the unit +T}:T{ +\ \& +T} +T{ +%r +T}:T{ +Root control group path of systemd +T}:T{ +\ \& +T} +T{ +%R +T}:T{ +Parent directory of the root control group path of systemd +T}:T{ +\ \& +T} +T{ +%t +T}:T{ +Runtime socket dir +T}:T{ +This is either /run (for the system manager) or $XDG_RUNTIME_DIR (for user managers)\&. +T} +.TE +.sp 1 +.PP +If a unit file is empty (i\&.e\&. has the file size 0) or is symlinked to +/dev/null +its configuration will not be loaded and it appears with a load state of +masked, and cannot be activated\&. Use this as an effective way to fully disable a unit, making it impossible to start it even manually\&. +.PP +The unit file format is covered by the +\m[blue]\fBInterface Stability Promise\fR\m[]\&\s-2\u[2]\d\s+2\&. +.SH "OPTIONS" +.PP +Unit file may include a [Unit] section, which carries generic information about the unit that is not dependent on the type of unit: +.PP +\fIDescription=\fR +.RS 4 +A free\-form string describing the unit\&. This is intended for use in UIs to show descriptive information along with the unit name\&. +.RE +.PP +\fIRequires=\fR +.RS 4 +Configures requirement dependencies on other units\&. If this unit gets activated, the units listed here will be activated as well\&. If one of the other units gets deactivated or its activation fails, this unit will be deactivated\&. This option may be specified more than once, in which case requirement dependencies for all listed names are created\&. Note that requirement dependencies do not influence the order in which services are started or stopped\&. This has to be configured independently with the +\fIAfter=\fR +or +\fIBefore=\fR +options\&. If a unit +foo\&.service +requires a unit +bar\&.service +as configured with +\fIRequires=\fR +and no ordering is configured with +\fIAfter=\fR +or +\fIBefore=\fR, then both units will be started simultaneously and without any delay between them if +foo\&.service +is activated\&. Often it is a better choice to use +\fIWants=\fR +instead of +\fIRequires=\fR +in order to achieve a system that is more robust when dealing with failing services\&. +.RE +.PP +\fIRequiresOverridable=\fR +.RS 4 +Similar to +\fIRequires=\fR\&. Dependencies listed in +\fIRequiresOverridable=\fR +which cannot be fulfilled or fail to start are ignored if the startup was explicitly requested by the user\&. If the start\-up was pulled in indirectly by some dependency or automatic start\-up of units that is not requested by the user this dependency must be fulfilled and otherwise the transaction fails\&. Hence, this option may be used to configure dependencies that are normally honored unless the user explicitly starts up the unit, in which case whether they failed or not is irrelevant\&. +.RE +.PP +\fIRequisite=\fR, \fIRequisiteOverridable=\fR +.RS 4 +Similar to +\fIRequires=\fR +resp\&. +\fIRequiresOverridable=\fR\&. However, if a unit listed here is not started already it will not be started and the transaction fails immediately\&. +.RE +.PP +\fIWants=\fR +.RS 4 +A weaker version of +\fIRequires=\fR\&. A unit listed in this option will be started if the configuring unit is\&. However, if the listed unit fails to start up or cannot be added to the transaction this has no impact on the validity of the transaction as a whole\&. This is the recommended way to hook start\-up of one unit to the start\-up of another unit\&. Note that dependencies of this type may also be configured outside of the unit configuration file by adding a symlink to a +\&.wants/ +directory accompanying the unit file\&. For details see above\&. +.RE +.PP +\fIBindTo=\fR +.RS 4 +Configures requirement dependencies, very similar in style to +\fIRequires=\fR, however in addition to this behaviour it also declares that this unit is stopped when any of the units listed suddenly disappears\&. Units can suddenly, unexpectedly disappear if a service terminates on its own choice, a device is unplugged or a mount point unmounted without involvement of systemd\&. +.RE +.PP +\fIConflicts=\fR +.RS 4 +Configures negative requirement dependencies\&. If a unit has a +\fIConflicts=\fR +setting on another unit, starting the former will stop the latter and vice versa\&. Note that this setting is independent of and orthogonal to the +\fIAfter=\fR +and +\fIBefore=\fR +ordering dependencies\&. +.sp +If a unit A that conflicts with a unit B is scheduled to be started at the same time as B, the transaction will either fail (in case both are required part of the transaction) or be modified to be fixed (in case one or both jobs are not a required part of the transaction)\&. In the latter case the job that is not the required will be removed, or in case both are not required the unit that conflicts will be started and the unit that is conflicted is stopped\&. +.RE +.PP +\fIBefore=\fR, \fIAfter=\fR +.RS 4 +Configures ordering dependencies between units\&. If a unit +foo\&.service +contains a setting +\fBBefore=bar\&.service\fR +and both units are being started, +bar\&.service\*(Aqs start\-up is delayed until +foo\&.service +is started up\&. Note that this setting is independent of and orthogonal to the requirement dependencies as configured by +\fIRequires=\fR\&. It is a common pattern to include a unit name in both the +\fIAfter=\fR +and +\fIRequires=\fR +option in which case the unit listed will be started before the unit that is configured with these options\&. This option may be specified more than once, in which case ordering dependencies for all listed names are created\&. +\fIAfter=\fR +is the inverse of +\fIBefore=\fR, i\&.e\&. while +\fIAfter=\fR +ensures that the configured unit is started after the listed unit finished starting up, +\fIBefore=\fR +ensures the opposite, i\&.e\&. that the configured unit is fully started up before the listed unit is started\&. Note that when two units with an ordering dependency between them are shut down, the inverse of the start\-up order is applied\&. i\&.e\&. if a unit is configured with +\fIAfter=\fR +on another unit, the former is stopped before the latter if both are shut down\&. If one unit with an ordering dependency on another unit is shut down while the latter is started up, the shut down is ordered before the start\-up regardless whether the ordering dependency is actually of type +\fIAfter=\fR +or +\fIBefore=\fR\&. If two units have no ordering dependencies between them they are shut down resp\&. started up simultaneously, and no ordering takes place\&. +.RE +.PP +\fIOnFailure=\fR +.RS 4 +Lists one or more units that are activated when this unit enters the \*(Aqfailed\*(Aq state\&. +.RE +.PP +\fIPropagateReloadTo=\fR, \fIPropagateReloadFrom=\fR +.RS 4 +Lists one or more units where reload requests on the unit will be propagated to/on the other unit will be propagated from\&. Issuing a reload request on a unit will automatically also enqueue a reload request on all units that the reload request shall be propagated to via these two settings\&. +.RE +.PP +\fIOnFailureIsolate=\fR +.RS 4 +Takes a boolean argument\&. If +\fBtrue\fR +the unit listed in +\fIOnFailure=\fR +will be enqueued in isolation mode, i\&.e\&. all units that are not its dependency will be stopped\&. If this is set only a single unit may be listed in +\fIOnFailure=\fR\&. Defaults to +\fBfalse\fR\&. +.RE +.PP +\fIIgnoreOnIsolate=\fR +.RS 4 +Takes a boolean argument\&. If +\fBtrue\fR +this unit will not be stopped when isolating another unit\&. Defaults to +\fBfalse\fR\&. +.RE +.PP +\fIIgnoreOnSnapshot=\fR +.RS 4 +Takes a boolean argument\&. If +\fBtrue\fR +this unit will not be included in snapshots\&. Defaults to +\fBtrue\fR +for device and snapshot units, +\fBfalse\fR +for the others\&. +.RE +.PP +\fIStopWhenUnneeded=\fR +.RS 4 +Takes a boolean argument\&. If +\fBtrue\fR +this unit will be stopped when it is no longer used\&. Note that in order to minimize the work to be executed, systemd will not stop units by default unless they are conflicting with other units, or the user explicitly requested their shut down\&. If this option is set, a unit will be automatically cleaned up if no other active unit requires it\&. Defaults to +\fBfalse\fR\&. +.RE +.PP +\fIRefuseManualStart=\fR, \fIRefuseManualStop=\fR +.RS 4 +Takes a boolean argument\&. If +\fBtrue\fR +this unit can only be activated (resp\&. deactivated) indirectly\&. In this case explicit start\-up (resp\&. termination) requested by the user is denied, however if it is started (resp\&. stopped) as a dependency of another unit, start\-up (resp\&. termination) will succeed\&. This is mostly a safety feature to ensure that the user does not accidentally activate units that are not intended to be activated explicitly, and not accidentally deactivate units that are not intended to be deactivated\&. These options default to +\fBfalse\fR\&. +.RE +.PP +\fIAllowIsolate=\fR +.RS 4 +Takes a boolean argument\&. If +\fBtrue\fR +this unit may be used with the +\fBsystemctl isolate\fR +command\&. Otherwise this will be refused\&. It probably is a good idea to leave this disabled except for target units that shall be used similar to runlevels in SysV init systems, just as a precaution to avoid unusable system states\&. This option defaults to +\fBfalse\fR\&. +.RE +.PP +\fIDefaultDependencies=\fR +.RS 4 +Takes a boolean argument\&. If +\fBtrue\fR +(the default), a few default dependencies will implicitly be created for the unit\&. The actual dependencies created depend on the unit type\&. For example, for service units, these dependencies ensure that the service is started only after basic system initialization is completed and is properly terminated on system shutdown\&. See the respective man pages for details\&. Generally, only services involved with early boot or late shutdown should set this option to +\fBfalse\fR\&. It is highly recommended to leave this option enabled for the majority of common units\&. If set to +\fBfalse\fR +this option does not disable all implicit dependencies, just non\-essential ones\&. +.RE +.PP +\fIJobTimeoutSec=\fR +.RS 4 +When clients are waiting for a job of this unit to complete, time out after the specified time\&. If this time limit is reached the job will be cancelled, the unit however will not change state or even enter the \*(Aqfailed\*(Aq mode\&. This value defaults to 0 (job timeouts disabled), except for device units\&. NB: this timeout is independent from any unit\-specific timeout (for example, the timeout set with +\fITimeout=\fR +in service units) as the job timeout has no effect on the unit itself, only on the job that might be pending for it\&. Or in other words: unit\-specific timeouts are useful to abort unit state changes, and revert them\&. The job timeout set with this option however is useful to abort only the job waiting for the unit state to change\&. +.RE +.PP +\fIConditionPathExists=\fR, \fIConditionPathExistsGlob=\fR, \fIConditionPathIsDirectory=\fR, \fIConditionPathIsSymbolicLink=\fR, \fIConditionPathIsMountPoint=\fR, \fIConditionDirectoryNotEmpty=\fR, \fIConditionFileIsExecutable=\fR, \fIConditionKernelCommandLine=\fR, \fIConditionVirtualization=\fR, \fIConditionSecurity=\fR, \fIConditionCapability=\fR, \fIConditionNull=\fR +.RS 4 +Before starting a unit verify that the specified condition is true\&. With +\fIConditionPathExists=\fR +a file existence condition can be checked before a unit is started\&. If the specified absolute path name does not exist, startup of a unit will not actually happen, however the unit is still useful for ordering purposes in this case\&. The condition is checked at the time the queued start job is to be executed\&. If the absolute path name passed to +\fIConditionPathExists=\fR +is prefixed with an exclamation mark (!), the test is negated, and the unit is only started if the path does not exist\&. +\fIConditionPathExistsGlob=\fR +works in a similar way, but checks for the existence of at least one file or directory matching the specified globbing pattern\&. +\fIConditionPathIsDirectory=\fR +is similar to +\fIConditionPathExists=\fR +but verifies whether a certain path exists and is a directory\&. +\fIConditionPathIsSymbolicLink=\fR +is similar to +\fIConditionPathExists=\fR +but verifies whether a certain path exists and is a symbolic link\&. +\fIConditionPathIsMountPoint=\fR +is similar to +\fIConditionPathExists=\fR +but verifies whether a certain path exists and is a mount point\&. +\fIConditionFileIsExecutable=\fR +is similar to +\fIConditionPathExists=\fR +but verifies whether a certain path exists, is a regular file and marked executable\&. +\fIConditionDirectoryNotEmpty=\fR +is similar to +\fIConditionPathExists=\fR +but verifies whether a certain path exists and is a non\-empty directory\&. Similarly +\fIConditionKernelCommandLine=\fR +may be used to check whether a specific kernel command line option is set (or if prefixed with the exclamation mark unset)\&. The argument must either be a single word, or an assignment (i\&.e\&. two words, separated by the equality sign)\&. In the former case the kernel command line is searched for the word appearing as is, or as left hand side of an assignment\&. In the latter case the exact assignment is looked for with right and left hand side matching\&. +\fIConditionVirtualization=\fR +may be used to check whether the system is executed in a virtualized environment and optionally test whether it is a specific implementation\&. Takes either boolean value to check if being executed in any virtualized environment, or one of +\fIvm\fR +and +\fIcontainer\fR +to test against a specific type of virtualization solution, or one of +\fIqemu\fR, +\fIkvm\fR, +\fIvmware\fR, +\fImicrosoft\fR, +\fIoracle\fR, +\fIxen\fR, +\fIbochs\fR, +\fIchroot\fR, +\fIopenvz\fR, +\fIlxc\fR, +\fIlxc\-libvirt\fR, +\fIsystemd\-nspawn\fR, +\fIpidns\fR +to test against a specific implementation\&. If multiple virtualization technologies are nested only the innermost is considered\&. The test may be negated by prepending an exclamation mark\&. +\fIConditionSecurity=\fR +may be used to check whether the given security module is enabled on the system\&. Currently the only recognized value is +\fIselinux\fR\&. The test may be negated by prepending an exclamation mark\&. +\fIConditionCapability=\fR +may be used to check whether the given capability exists in the capability bounding set of the service manager (i\&.e\&. this does not check whether capability is actually available in the permitted or effective sets, see +\fBcapabilities\fR(7) +for details)\&. Pass a capability name such as +CAP_MKNOD, possibly prefixed with an exclamation mark to negate the check\&. Finally, +\fIConditionNull=\fR +may be used to add a constant condition check value to the unit\&. It takes a boolean argument\&. If set to +\fIfalse\fR +the condition will always fail, otherwise succeed\&. If multiple conditions are specified the unit will be executed if all of them apply (i\&.e\&. a logical AND is applied)\&. Condition checks can be prefixed with a pipe symbol (|) in which case a condition becomes a triggering condition\&. If at least one triggering condition is defined for a unit then the unit will be executed if at least one of the triggering conditions apply and all of the non\-triggering conditions\&. If you prefix an argument with the pipe symbol and an exclamation mark the pipe symbol must be passed first, the exclamation second\&. Except for +\fIConditionPathIsSymbolicLink=\fR, all path checks follow symlinks\&. +.RE +.PP +\fINames=\fR +.RS 4 +Additional names for this unit\&. The names listed here must have the same suffix (i\&.e\&. type) as the unit file name\&. This option may be specified more than once, in which case all listed names are used\&. Note that this option is different from the +\fIAlias=\fR +option from the [Install] section mentioned below\&. See below for details\&. Note that in almost all cases this option is not what you want\&. A symlink alias in the file system is generally preferable since it can be used as lookup key\&. If a unit with a symlinked alias name is not loaded and needs to be it is easily found via the symlink\&. However, if a unit with an alias name configured with this setting is not loaded it will not be discovered\&. This settings\*(Aq only use is in conjunction with service instances\&. +.RE +.PP +Unit file may include a [Install] section, which carries installation information for the unit\&. This section is not interpreted by +\fBsystemd\fR(1) +during runtime\&. It is used exclusively by the +\fBenable\fR +and +\fBdisable\fR +commands of the +\fBsystemctl\fR(1) +tool during installation of a unit: +.PP +\fIAlias=\fR +.RS 4 +Additional names this unit shall be installed under\&. The names listed here must have the same suffix (i\&.e\&. type) as the unit file name\&. This option may be specified more than once, in which case all listed names are used\&. At installation time, +\fBsystemctl enable\fR +will create symlinks from these names to the unit file name\&. Note that this is different from the +\fINames=\fR +option from the [Unit] section mentioned above: The names from +\fINames=\fR +apply unconditionally if the unit is loaded\&. The names from +\fIAlias=\fR +apply only if the unit has actually been installed with the +\fBsystemctl enable\fR +command\&. Also, if systemd searches for a unit, it will discover symlinked alias names as configured with +\fIAlias=\fR, but not names configured with +\fINames=\fR +only\&. It is a common pattern to list a name in both options\&. In this case, a unit will be active under all names if installed, but also if not installed but requested explicitly under its main name\&. +.RE +.PP +\fIWantedBy=\fR +.RS 4 +Installs a symlink in the +\&.wants/ +subdirectory for a unit\&. This has the effect that when the listed unit name is activated the unit listing it is activated too\&. +\fBWantedBy=foo\&.service\fR +in a service +bar\&.service +is mostly equivalent to +\fBAlias=foo\&.service\&.wants/bar\&.service\fR +in the same file\&. +.RE +.PP +\fIAlso=\fR +.RS 4 +Additional units to install when this unit is installed\&. If the user requests installation of a unit with this option configured, +\fBsystemctl enable\fR +will automatically install units listed in this option as well\&. +.RE +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(8), +\fBsystemd.special\fR(7), +\fBsystemd.service\fR(5), +\fBsystemd.socket\fR(5), +\fBsystemd.device\fR(5), +\fBsystemd.mount\fR(5), +\fBsystemd.automount\fR(5), +\fBsystemd.swap\fR(5), +\fBsystemd.target\fR(5), +\fBsystemd.path\fR(5), +\fBsystemd.timer\fR(5), +\fBsystemd.snapshot\fR(5), +\fBcapabilities\fR(7) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE +.SH "NOTES" +.IP " 1." 4 +XDG Desktop Entry Specification +.RS 4 +\%http://standards.freedesktop.org/desktop-entry-spec/latest/ +.RE +.IP " 2." 4 +Interface Stability Promise +.RS 4 +\%http://www.freedesktop.org/wiki/Software/systemd/InterfaceStabilityPromise +.RE diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml new file mode 100644 index 0000000..eecff73 --- /dev/null +++ b/man/systemd.unit.xml @@ -0,0 +1,970 @@ + + + + + + + + + systemd.unit + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd.unit + 5 + + + + systemd.unit + systemd unit configuration files + + + + systemd.service, + systemd.socket, + systemd.device, + systemd.mount, + systemd.automount, + systemd.swap, + systemd.target, + systemd.path, + systemd.timer, + systemd.snapshot + + + + Description + + A unit configuration file encodes information + about a service, a socket, a device, a mount point, an + automount point, a swap file or partition, a start-up + target, a file system path or a timer controlled and + supervised by + systemd1. The + syntax is inspired by XDG + Desktop Entry Specification .desktop files, which are in turn + inspired by Microsoft Windows + .ini files. + + This man pages lists the common configuration + options of all the unit types. These options need to + be configured in the [Unit] resp. [Install] + section of the unit files. + + In addition to the generic [Unit] and [Install] + sections described here, each unit should have a + type-specific section, e.g. [Service] for a service + unit. See the respective man pages for more + information. + + Unit files may contain additional options on top + of those listed here. If systemd encounters an unknown + option it will write a warning log message but + continue loading the unit. If an option is prefixed + with it is ignored completely by + systemd. Applications may use this to include + additional information in the unit files. + + Boolean arguments used in unit files can be + written in various formats. For positive settings the + strings , , + and are + equivalent. For negative settings the strings + , , + and are + equivalent. + + Time span values encoded in unit files can be + written in various formats. A stand-alone number + specifies a time in seconds. If suffixed with a time + unit, the unit is honored. A concatenation of + multiple values with units is supported, in which case + the values are added up. Example: "50" refers to 50 + seconds; "2min 200ms" refers to 2 minutes plus 200 + milliseconds, i.e. 120200ms. The following time units + are understood: s, min, h, d, w, ms, us. + + Empty lines and lines starting with # or ; are + ignored. This may be used for commenting. Lines ending + in a backslash are concatenated with the following + line while reading and the backslash is replaced by a + space character. This may be used to wrap long lines. + + If a line starts with + followed by a file name, the specified file will be + parsed at this point. Make sure that the file that is + included has the appropiate section headers before + any directives. + + Along with a unit file + foo.service a directory + foo.service.wants/ may exist. All + units symlinked from such a directory are implicitly + added as dependencies of type + Wanted= to the unit. This is useful + to hook units into the start-up of other units, + without having to modify their unit configuration + files. For details about the semantics of + Wanted= see below. The preferred + way to create symlinks in the + .wants/ directory of a service is + with the enable command of the + systemctl1 + tool which reads information from the [Install] + section of unit files. (See below.) A similar + functionality exists for Requires= + type dependencies as well, the directory suffix is + .requires/ in this case. + + Note that while systemd offers a flexible + dependency system between units it is recommended to + use this functionality only sparsely and instead rely + on techniques such as bus-based or socket-based + activation which makes dependencies implicit, which + both results in a simpler and more flexible + system. + + Some unit names reflect paths existing in the + file system name space. Example: a device unit + dev-sda.device refers to a device + with the device node /dev/sda in + the file system namespace. If this applies a special + way to escape the path name is used, so that the + result is usable as part of a file name. Basically, + given a path, "/" is replaced by "-", and all + unprintable characters and the "-" are replaced by + C-style "\x20" escapes. The root directory "/" is + encoded as single dash, while otherwise the initial + and ending "/" is removed from all paths during + transformation. This escaping is reversible. + + Optionally, units may be instantiated from a + template file at runtime. This allows creation of + multiple units from a single configuration file. If + systemd looks for a unit configuration file it will + first search for the literal unit name in the + filesystem. If that yields no success and the unit + name contains an @ character, systemd will look for a + unit template that shares the same name but with the + instance string (i.e. the part between the @ character + and the suffix) removed. Example: if a service + getty@tty3.service is requested + and no file by that name is found, systemd will look + for getty@.service and + instantiate a service from that configuration file if + it is found. + + To refer to the instance string from + within the configuration file you may use the special + %i specifier in many of the + configuration options. Other specifiers exist, the + full list is: + + + Specifiers available in unit files + + + + + + + Specifier + Meaning + Details + + + + + %n + Full unit name + + + + %N + Unescaped full unit name + + + + %p + Prefix name + This refers to the string before the @, i.e. "getty" in the example above, where "tty3" is the instance name. + + + %P + Unescaped prefix name + + + + %i + Instance name + This is the string between the @ character and the suffix. + + + %I + Unescaped instance name + + + + %f + Unescaped file name + This is either the unescaped instance name (if set) with / prepended (if necessary), or the prefix name similarly prepended with /. + + + %c + Control group path of the unit + + + + %r + Root control group path of systemd + + + + %R + Parent directory of the root control group path of systemd + + + + %t + Runtime socket dir + This is either /run (for the system manager) or $XDG_RUNTIME_DIR (for user managers). + + + +
+ + If a unit file is empty (i.e. has the file size + 0) or is symlinked to /dev/null + its configuration will not be loaded and it appears + with a load state of masked, and + cannot be activated. Use this as an effective way to + fully disable a unit, making it impossible to start it + even manually. + + The unit file format is covered by the + Interface + Stability Promise. +
+ + + Options + + Unit file may include a [Unit] section, which + carries generic information about the unit that is not + dependent on the type of unit: + + + + + Description= + A free-form string + describing the unit. This is intended + for use in UIs to show descriptive + information along with the unit + name. + + + + Requires= + + Configures requirement + dependencies on other units. If this + unit gets activated, the units listed + here will be activated as well. If one + of the other units gets deactivated or + its activation fails, this unit will + be deactivated. This option may be + specified more than once, in which + case requirement dependencies for all + listed names are created. Note that + requirement dependencies do not + influence the order in which services + are started or stopped. This has to be + configured independently with the + After= or + Before= options. If + a unit + foo.service + requires a unit + bar.service as + configured with + Requires= and no + ordering is configured with + After= or + Before=, then both + units will be started simultaneously + and without any delay between them if + foo.service is + activated. Often it is a better choice + to use Wants= + instead of + Requires= in order + to achieve a system that is more + robust when dealing with failing + services. + + + + RequiresOverridable= + + Similar to + Requires=. + Dependencies listed in + RequiresOverridable= + which cannot be fulfilled or fail to + start are ignored if the startup was + explicitly requested by the user. If + the start-up was pulled in indirectly + by some dependency or automatic + start-up of units that is not + requested by the user this dependency + must be fulfilled and otherwise the + transaction fails. Hence, this option + may be used to configure dependencies + that are normally honored unless the + user explicitly starts up the unit, in + which case whether they failed or not + is irrelevant. + + + + Requisite= + RequisiteOverridable= + + Similar to + Requires= + resp. RequiresOverridable=. However, + if a unit listed here is not started + already it will not be started and the + transaction fails + immediately. + + + + Wants= + + A weaker version of + Requires=. A unit + listed in this option will be started + if the configuring unit is. However, + if the listed unit fails to start up + or cannot be added to the transaction + this has no impact on the validity of + the transaction as a whole. This is + the recommended way to hook start-up + of one unit to the start-up of another + unit. Note that dependencies of this + type may also be configured outside of + the unit configuration file by + adding a symlink to a + .wants/ directory + accompanying the unit file. For + details see above. + + + + BindTo= + + Configures requirement + dependencies, very similar in style to + Requires=, however + in addition to this behaviour it also + declares that this unit is stopped + when any of the units listed suddenly + disappears. Units can suddenly, + unexpectedly disappear if a service + terminates on its own choice, a device + is unplugged or a mount point + unmounted without involvement of + systemd. + + + + Conflicts= + + Configures negative + requirement dependencies. If a unit + has a + Conflicts= setting + on another unit, starting the former + will stop the latter and vice + versa. Note that this setting is + independent of and orthogonal to the + After= and + Before= ordering + dependencies. + + If a unit A that conflicts with + a unit B is scheduled to be started at + the same time as B, the transaction + will either fail (in case both are + required part of the transaction) or + be modified to be fixed (in case one + or both jobs are not a required part + of the transaction). In the latter + case the job that is not the required + will be removed, or in case both are + not required the unit that conflicts + will be started and the unit that is + conflicted is + stopped. + + + + Before= + After= + + Configures ordering + dependencies between units. If a unit + foo.service + contains a setting + + and both units are being started, + bar.service's + start-up is delayed until + foo.service is + started up. Note that this setting is + independent of and orthogonal to the + requirement dependencies as configured + by Requires=. It is + a common pattern to include a unit + name in both the + After= and + Requires= option in + which case the unit listed will be + started before the unit that is + configured with these options. This + option may be specified more than + once, in which case ordering + dependencies for all listed names are + created. After= is + the inverse of + Before=, i.e. while + After= ensures that + the configured unit is started after + the listed unit finished starting up, + Before= ensures the + opposite, i.e. that the configured + unit is fully started up before the + listed unit is started. Note that when + two units with an ordering dependency + between them are shut down, the + inverse of the start-up order is + applied. i.e. if a unit is configured + with After= on + another unit, the former is stopped + before the latter if both are shut + down. If one unit with an ordering + dependency on another unit is shut + down while the latter is started up, + the shut down is ordered before the + start-up regardless whether the + ordering dependency is actually of + type After= or + Before=. If two + units have no ordering dependencies + between them they are shut down + resp. started up simultaneously, and + no ordering takes + place. + + + + OnFailure= + + Lists one or more + units that are activated when this + unit enters the + 'failed' + state. + + + + PropagateReloadTo= + PropagateReloadFrom= + + Lists one or more + units where reload requests on the + unit will be propagated to/on the + other unit will be propagated + from. Issuing a reload request on a + unit will automatically also enqueue a + reload request on all units that the + reload request shall be propagated to + via these two + settings. + + + + OnFailureIsolate= + + Takes a boolean + argument. If the + unit listed in + OnFailure= will be + enqueued in isolation mode, i.e. all + units that are not its dependency will + be stopped. If this is set only a + single unit may be listed in + OnFailure=. Defaults + to + . + + + + IgnoreOnIsolate= + + Takes a boolean + argument. If + this unit will not be stopped when + isolating another unit. Defaults to + . + + + + IgnoreOnSnapshot= + + Takes a boolean + argument. If + this unit will not be included in + snapshots. Defaults to + for device and + snapshot units, + for the others. + + + + StopWhenUnneeded= + + Takes a boolean + argument. If + this unit will be stopped when it is + no longer used. Note that in order to + minimize the work to be executed, + systemd will not stop units by default + unless they are conflicting with other + units, or the user explicitly + requested their shut down. If this + option is set, a unit will be + automatically cleaned up if no other + active unit requires it. Defaults to + . + + + + RefuseManualStart= + RefuseManualStop= + + Takes a boolean + argument. If + this unit can only be activated + (resp. deactivated) indirectly. In + this case explicit start-up + (resp. termination) requested by the + user is denied, however if it is + started (resp. stopped) as a + dependency of another unit, start-up + (resp. termination) will succeed. This + is mostly a safety feature to ensure + that the user does not accidentally + activate units that are not intended + to be activated explicitly, and not + accidentally deactivate units that are + not intended to be deactivated. + These options default to + . + + + + AllowIsolate= + + Takes a boolean + argument. If + this unit may be used with the + systemctl isolate + command. Otherwise this will be + refused. It probably is a good idea to + leave this disabled except for target + units that shall be used similar to + runlevels in SysV init systems, just + as a precaution to avoid unusable + system states. This option defaults to + . + + + + DefaultDependencies= + + Takes a boolean + argument. If + (the default), a few default + dependencies will implicitly be + created for the unit. The actual + dependencies created depend on the + unit type. For example, for service + units, these dependencies ensure that + the service is started only after + basic system initialization is + completed and is properly terminated on + system shutdown. See the respective + man pages for details. Generally, only + services involved with early boot or + late shutdown should set this option + to . It is + highly recommended to leave this + option enabled for the majority of + common units. If set to + this option + does not disable all implicit + dependencies, just non-essential + ones. + + + + JobTimeoutSec= + + When clients are + waiting for a job of this unit to + complete, time out after the specified + time. If this time limit is reached + the job will be cancelled, the unit + however will not change state or even + enter the 'failed' + mode. This value defaults to 0 (job + timeouts disabled), except for device + units. NB: this timeout is independent + from any unit-specific timeout (for + example, the timeout set with + Timeout= in service + units) as the job timeout has no + effect on the unit itself, only on the + job that might be pending for it. Or + in other words: unit-specific timeouts + are useful to abort unit state + changes, and revert them. The job + timeout set with this option however + is useful to abort only the job + waiting for the unit state to + change. + + + + ConditionPathExists= + ConditionPathExistsGlob= + ConditionPathIsDirectory= + ConditionPathIsSymbolicLink= + ConditionPathIsMountPoint= + ConditionDirectoryNotEmpty= + ConditionFileIsExecutable= + ConditionKernelCommandLine= + ConditionVirtualization= + ConditionSecurity= + ConditionCapability= + ConditionNull= + + Before starting a unit + verify that the specified condition is + true. With + ConditionPathExists= + a file existence condition can be + checked before a unit is started. If + the specified absolute path name does + not exist, startup of a unit will not + actually happen, however the unit is + still useful for ordering purposes in + this case. The condition is checked at + the time the queued start job is to be + executed. If the absolute path name + passed to + ConditionPathExists= + is prefixed with an exclamation mark + (!), the test is negated, and the unit + is only started if the path does not + exist. + ConditionPathExistsGlob= + works in a similar way, but checks for + the existence of at least one file or + directory matching the specified + globbing + pattern. ConditionPathIsDirectory= + is similar to + ConditionPathExists= + but verifies whether a certain path + exists and is a + directory. ConditionPathIsSymbolicLink= + is similar to + ConditionPathExists= + but verifies whether a certain path + exists and is a symbolic + link. ConditionPathIsMountPoint= + is similar to + ConditionPathExists= + but verifies whether a certain path + exists and is a mount + point. ConditionFileIsExecutable= + is similar to + ConditionPathExists= + but verifies whether a certain path + exists, is a regular file and marked + executable. + ConditionDirectoryNotEmpty= + is similar to + ConditionPathExists= + but verifies whether a certain path + exists and is a non-empty + directory. Similarly + ConditionKernelCommandLine= + may be used to check whether a + specific kernel command line option is + set (or if prefixed with the + exclamation mark unset). The argument + must either be a single word, or an + assignment (i.e. two words, separated + by the equality sign). In the former + case the kernel command line is + searched for the word appearing as is, + or as left hand side of an + assignment. In the latter case the + exact assignment is looked for with + right and left hand side + matching. ConditionVirtualization= + may be used to check whether the + system is executed in a virtualized + environment and optionally test + whether it is a specific + implementation. Takes either boolean + value to check if being executed in + any virtualized environment, or one of + vm and + container to test + against a specific type of + virtualization solution, or one of + qemu, + kvm, + vmware, + microsoft, + oracle, + xen, + bochs, + chroot, + openvz, + lxc, + lxc-libvirt, + systemd-nspawn, + pidns to test + against a specific implementation. If + multiple virtualization technologies + are nested only the innermost is + considered. The test may be negated by + prepending an exclamation mark. + ConditionSecurity= + may be used to check whether the given + security module is enabled on the + system. Currently the only recognized + value is selinux. + The test may be negated by prepending + an exclamation + mark. ConditionCapability= + may be used to check whether the given + capability exists in the capability + bounding set of the service manager + (i.e. this does not check whether + capability is actually available in + the permitted or effective sets, see + capabilities7 + for details). Pass a capability name + such as CAP_MKNOD, + possibly prefixed with an exclamation + mark to negate the check. Finally, + ConditionNull= may + be used to add a constant condition + check value to the unit. It takes a + boolean argument. If set to + false the condition + will always fail, otherwise + succeed. If multiple conditions are + specified the unit will be executed if + all of them apply (i.e. a logical AND + is applied). Condition checks can be + prefixed with a pipe symbol (|) in + which case a condition becomes a + triggering condition. If at least one + triggering condition is defined for a + unit then the unit will be executed if + at least one of the triggering + conditions apply and all of the + non-triggering conditions. If you + prefix an argument with the pipe + symbol and an exclamation mark the + pipe symbol must be passed first, the + exclamation second. Except for + ConditionPathIsSymbolicLink=, + all path checks follow + symlinks. + + + + Names= + + Additional names for + this unit. The names listed here must + have the same suffix (i.e. type) as + the unit file name. This option may be + specified more than once, in which + case all listed names are used. Note + that this option is different from the + Alias= option from + the [Install] section mentioned + below. See below for details. Note + that in almost all cases this option + is not what you want. A symlink alias + in the file system is generally + preferable since it can be used as + lookup key. If a unit with a symlinked + alias name is not loaded and needs to + be it is easily found via the + symlink. However, if a unit with an + alias name configured with this + setting is not loaded it will not be + discovered. This settings' only use is + in conjunction with service + instances. + + + + + Unit file may include a [Install] section, which + carries installation information for the unit. This + section is not interpreted by + systemd1 + during runtime. It is used exclusively by the + enable and + disable commands of the + systemctl1 + tool during installation of a unit: + + + + Alias= + + Additional names this + unit shall be installed under. The + names listed here must have the same + suffix (i.e. type) as the unit file + name. This option may be specified + more than once, in which case all + listed names are used. At installation + time, + systemctl enable + will create symlinks from these names + to the unit file name. Note that this + is different from the + Names= option from + the [Unit] section mentioned above: + The names from + Names= apply + unconditionally if the unit is + loaded. The names from + Alias= apply only + if the unit has actually been + installed with the + systemctl enable + command. Also, if systemd searches for a + unit, it will discover symlinked alias + names as configured with + Alias=, but not + names configured with + Names= only. It is + a common pattern to list a name in + both options. In this case, a unit + will be active under all names if + installed, but also if not installed + but requested explicitly under its + main name. + + + + WantedBy= + + Installs a symlink in + the .wants/ + subdirectory for a unit. This has the + effect that when the listed unit name + is activated the unit listing it is + activated + too. WantedBy=foo.service + in a service + bar.service is + mostly equivalent to + Alias=foo.service.wants/bar.service + in the same file. + + + + Also= + + Additional units to + install when this unit is + installed. If the user requests + installation of a unit with this + option configured, + systemctl enable + will automatically install units + listed in this option as + well. + + + + + + + See Also + + systemd1, + systemctl8, + systemd.special7, + systemd.service5, + systemd.socket5, + systemd.device5, + systemd.mount5, + systemd.automount5, + systemd.swap5, + systemd.target5, + systemd.path5, + systemd.timer5, + systemd.snapshot5, + capabilities7 + + + +
diff --git a/man/systemd.xml b/man/systemd.xml new file mode 100644 index 0000000..f0bc552 --- /dev/null +++ b/man/systemd.xml @@ -0,0 +1,1158 @@ + + + + + + + + + systemd + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + systemd + 1 + + + + systemd + init + systemd System and Service Manager + + + + + systemd OPTIONS + + + init OPTIONS COMMAND + + + + + Description + + systemd is a system and service manager for + Linux operating systems. When run as first process on + boot (as PID 1), it acts as init system that brings + up and maintains userspace services. + + For compatibility with SysV, if systemd is called + as init and a PID that is not + 1, it will execute telinit and pass + all command line arguments unmodified. That means + init and telinit + are mostly equivalent when invoked from normal login sessions. See + telinit8 + for more information. + + When run as system instance, systemd interprets + the configuration file + system.conf, otherwise + user.conf. See + systemd.conf5 + for more information. + + + + Options + + The following options are understood: + + + + + + + Prints a short help + text and exits. + + + + + Determine startup + sequence, dump it and exit. This is an + option useful for debugging + only. + + + + + Dump understood unit + configuration items. This outputs a + terse but complete list of + configuration items understood in unit + definition files. + + + + + Extract D-Bus + interface introspection data. This is + mostly useful at install time + to generate data suitable for the + D-Bus interfaces + repository. Optionally the interface + name for the introspection data may be + specified. If omitted, the + introspection data for all interfaces + is dumped. + + + + + Set default unit to + activate on startup. If not specified + defaults to + default.target. + + + + + + Tell systemd to run a + system instance (resp. user + instance), even if the process ID is + not 1 (resp. is 1), i.e. systemd is + not (resp. is) run as init process. + Normally it should not be necessary to + pass these options, as systemd + automatically detects the mode it is + started in. These options are hence of + little use except for debugging. Note + that it is not supported booting and + maintaining a full system with systemd + running in + mode, but PID not 1. In practice, + passing explicitly is + only useful in conjunction with + . + + + + + Dump core on + crash. This switch has no effect when + run as user + instance. + + + + + Run shell on + crash. This switch has no effect when + run as user + instance. + + + + + Ask for confirmation + when spawning processes. This switch + has no effect when run as user + instance. + + + + + Show terse service + status information while booting. This + switch has no effect when run as user + instance. Takes a boolean argument + which may be omitted which is + interpreted as + . + + + + + Controls whether + output of SysV init scripts will be + directed to the console. This switch + has no effect when run as user + instance. Takes a boolean argument + which may be omitted which is + interpreted as + . + + + + + Set log + target. Argument must be one of + , + , + , + , + , + , + . + + + + + Set log level. As + argument this accepts a numerical log + level or the well-known syslog3 + symbolic names (lowercase): + , + , + , + , + , + , + , + . + + + + + Highlight important + log messages. Argument is a boolean + value. If the argument is omitted it + defaults to + . + + + + + Include code location + in log messages. This is mostly + relevant for debugging + purposes. Argument is a boolean + value. If the argument is omitted + it defaults to + . + + + + + + Sets the default + output resp. error output for all + services and sockets, i.e. controls + the default for + + resp. + (see + systemd.exec5 + for details). Takes one of + , + , + , + , + , + , + , + , + . If the + argument is omitted + + defaults to + and + + to + . + + + + + + Concepts + + systemd provides a dependency system between + various entities called "units". Units encapsulate + various objects that are relevant for system boot-up + and maintenance. The majority of units are configured + in unit configuration files, whose syntax and basic + set of options is described in + systemd.unit5, + however some are created automatically from other + configuration or dynamically from system state. Units + may be 'active' (meaning started, bound, plugged in, + ... depending on the unit type, see below), or + 'inactive' (meaning stopped, unbound, unplugged, ...), + as well as in the process of being activated or + deactivated, i.e. between the two states (these states + are called 'activating', 'deactivating'). A special + 'failed' state is available as well which is very + similar to 'inactive' and is entered when the service + failed in some way (process returned error code on + exit, or crashed, or an operation timed out). If this + state is entered the cause will be logged, for later + reference. Note that the various unit types may have a + number of additional substates, which are mapped to + the five generalized unit states described + here. + + The following unit types are available: + + + Service units, which control + daemons and the processes they consist of. For + details see + systemd.service5. + + Socket units, which + encapsulate local IPC or network sockets in + the system, useful for socket-based + activation. For details about socket units see + systemd.socket5, + for details on socket-based activation and + other forms of activation, see + daemon7. + + Target units are useful to + group units, or provide well-known + synchronization points during boot-up, see + systemd.target5. + + Device units expose kernel + devices in systemd and may be used to + implement device-based activation. For details + see + systemd.device5. + + Mount units control mount + points in the file system, for details see + systemd.mount5. + + Automount units provide + automount capabilities, for on-demand mounting + of file systems as well as parallelized + boot-up. See + systemd.automount5. + + Snapshot units can be used to + temporarily save the state of the set of + systemd units, which later may be restored by + activating the saved snapshot unit. For more + information see + systemd.snapshot5. + + Timer units are useful for + triggering activation of other units based on + timers. You may find details in + systemd.timer5. + + Swap units are very similar to + mount units and encapsulate memory swap + partitions or files of the operating + system. They are described in systemd.swap5. + + Path units may be used + to activate other services when file system + objects change or are modified. See + systemd.path5. + + + + Units are named as their configuration + files. Some units have special semantics. A detailed + list is available in + systemd.special7. + + systemd knows various kinds of dependencies, + including positive and negative requirement + dependencies (i.e. Requires= and + Conflicts=) as well as ordering + dependencies (After= and + Before=). NB: ordering and + requirement dependencies are orthogonal. If only a + requirement dependency exists between two units + (e.g. foo.service requires + bar.service), but no ordering + dependency (e.g. foo.service + after bar.service) and both are + requested to start, they will be started in + parallel. It is a common pattern that both requirement + and ordering dependencies are placed between two + units. Also note that the majority of dependencies are + implicitly created and maintained by systemd. In most + cases it should be unnecessary to declare additional + dependencies manually, however it is possible to do + this. + + Application programs and units (via + dependencies) may request state changes of units. In + systemd, these requests are encapsulated as 'jobs' and + maintained in a job queue. Jobs may succeed or can + fail, their execution is ordered based on the ordering + dependencies of the units they have been scheduled + for. + + On boot systemd activates the target unit + default.target whose job is to + activate on-boot services and other on-boot units by + pulling them in via dependencies. Usually the unit + name is just an alias (symlink) for either + graphical.target (for + fully-featured boots into the UI) or + multi-user.target (for limited + console-only boots for use in embedded or server + environments, or similar; a subset of + graphical.target). However it is at the discretion of + the administrator to configure it as an alias to any + other target unit. See + systemd.special7 + for details about these target units. + + Processes systemd spawns are placed in + individual Linux control groups named after the unit + which they belong to in the private systemd + hierarchy. (see cgroups.txt + for more information about control groups, or short + "cgroups"). systemd uses this to effectively keep + track of processes. Control group information is + maintained in the kernel, and is accessible via the + file system hierarchy (beneath + /sys/fs/cgroup/systemd/), or in tools + such as + ps1 + (ps xawf -eo pid,user,cgroup,args + is particularly useful to list all processes and the + systemd units they belong to.). + + systemd is compatible with the SysV init system + to a large degree: SysV init scripts are supported and + simply read as an alternative (though limited) + configuration file format. The SysV + /dev/initctl interface is + provided, and compatibility implementations of the + various SysV client tools are available. In addition to + that, various established Unix functionality such as + /etc/fstab or the + utmp database are + supported. + + systemd has a minimal transaction system: if a + unit is requested to start up or shut down it will add + it and all its dependencies to a temporary + transaction. Then, it will verify if the transaction + is consistent (i.e. whether the ordering of all units + is cycle-free). If it is not, systemd will try to fix + it up, and removes non-essential jobs from the + transaction that might remove the loop. Also, systemd + tries to suppress non-essential jobs in the + transaction that would stop a running service. Finally + it is checked whether the jobs of the transaction + contradict jobs that have already been queued, and + optionally the transaction is aborted then. If all + worked out and the transaction is consistent and + minimized in its impact it is merged with all already + outstanding jobs and added to the run + queue. Effectively this means that before executing a + requested operation, systemd will verify that it makes + sense, fixing it if possible, and only failing if it + really cannot work. + + Systemd contains native implementations of + various tasks that need to be executed as part of the + boot process. For example, it sets the host name or + configures the loopback network device. It also sets + up and mounts various API file systems, such as + /sys or + /proc. + + For more information about the concepts and + ideas behind systemd please refer to the Original + Design Document. + + Note that some but not all interfaces provided + by systemd are covered by the Interface + Stability Promise. + + + + Directories + + + + System unit directories + + The systemd system + manager reads unit configuration from + various directories. Packages that + want to install unit files shall place + them in the directory returned by + pkg-config systemd + --variable=systemdsystemunitdir. Other + directories checked are + /usr/local/lib/systemd/system + and + /usr/lib/systemd/system. User + configuration always takes + precedence. pkg-config + systemd + --variable=systemdsystemconfdir + returns the path of the system + configuration directory. Packages + should alter the content of these + directories only with the + enable and + disable commands of + the + systemctl1 + tool. + + + + + + User unit directories + + Similar rules apply + for the user unit + directories. However, here the XDG + Base Directory specification + is followed to find + units. Applications should place their + unit files in the directory returned + by pkg-config systemd + --variable=systemduserunitdir. Global + configuration is done in the directory + reported by pkg-config + systemd + --variable=systemduserconfdir. The + enable and + disable commands of + the + systemctl1 + tool can handle both global (i.e. for + all users) and private (for one user) + enabling/disabling of + units. + + + + + + SysV init scripts directory + + The location of the + SysV init script directory varies + between distributions. If systemd + cannot find a native unit file for a + requested service, it will look for a + SysV init script of the same name + (with the + .service suffix + removed). + + + + + + SysV runlevel link farm directory + + The location of the + SysV runlevel link farm directory + varies between distributions. systemd + will take the link farm into account + when figuring out whether a service + shall be enabled. Note that a service + unit with a native unit configuration + file cannot be started by activating it + in the SysV runlevel link + farm. + + + + + + Signals + + + + SIGTERM + + Upon receiving this + signal the systemd system manager + serializes its state, reexecutes + itself and deserializes the saved + state again. This is mostly equivalent + to systemctl + daemon-reexec. + + systemd user managers will + start the + exit.target unit + when this signal is received. This is + mostly equivalent to + systemctl --user start + exit.target. + + + + SIGINT + + Upon receiving this + signal the systemd system manager will + start the + ctrl-alt-del.target unit. This + is mostly equivalent to + systemctl start + ctl-alt-del.target. + + systemd user managers + treat this signal the same way as + SIGTERM. + + + + SIGWINCH + + When this signal is + received the systemd system manager + will start the + kbrequest.target + unit. This is mostly equivalent to + systemctl start + kbrequest.target. + + This signal is ignored by + systemd user + managers. + + + + SIGPWR + + When this signal is + received the systemd manager + will start the + sigpwr.target + unit. This is mostly equivalent to + systemctl start + sigpwr.target. + + + + SIGUSR1 + + When this signal is + received the systemd manager will try + to reconnect to the D-Bus + bus. + + + + SIGUSR2 + + When this signal is + received the systemd manager will log + its complete state in human readable + form. The data logged is the same as + printed by systemctl + dump. + + + + SIGHUP + + Reloads the complete + daemon configuration. This is mostly + equivalent to systemctl + daemon-reload. + + + + SIGRTMIN+0 + + Enters default mode, starts the + default.target + unit. This is mostly equivalent to + systemctl start + default.target. + + + + SIGRTMIN+1 + + Enters rescue mode, + starts the + rescue.target + unit. This is mostly equivalent to + systemctl isolate + rescue.target. + + + + SIGRTMIN+2 + + Enters emergency mode, + starts the + emergency.service + unit. This is mostly equivalent to + systemctl isolate + emergency.service. + + + + SIGRTMIN+3 + + Halts the machine, + starts the + halt.target + unit. This is mostly equivalent to + systemctl start + halt.target. + + + + SIGRTMIN+4 + + Powers off the machine, + starts the + poweroff.target + unit. This is mostly equivalent to + systemctl start + poweroff.target. + + + + SIGRTMIN+5 + + Reboots the machine, + starts the + reboot.target + unit. This is mostly equivalent to + systemctl start + reboot.target. + + + + SIGRTMIN+6 + + Reboots the machine via kexec, + starts the + kexec.target + unit. This is mostly equivalent to + systemctl start + kexec.target. + + + + SIGRTMIN+13 + + Immediately halts the machine. + + + + SIGRTMIN+14 + + Immediately powers off the machine. + + + + SIGRTMIN+15 + + Immediately reboots the machine. + + + + SIGRTMIN+16 + + Immediately reboots the machine with kexec. + + + + SIGRTMIN+20 + + Enables display of + status messages on the console, as + controlled via + systemd.show_status=1 + on the kernel command + line. + + + + SIGRTMIN+21 + + Disables display of + status messages on the console, as + controlled via + systemd.show_status=0 + on the kernel command + line. + + + + SIGRTMIN+22 + SIGRTMIN+23 + + Sets the log level to + debug + (resp. info on + SIGRTMIN+23), as + controlled via + systemd.log_level=debug + (resp. systemd.log_level=info + on SIGRTMIN+23) on + the kernel command + line. + + + + SIGRTMIN+26 + SIGRTMIN+27 + SIGRTMIN+28 + SIGRTMIN+29 + + Sets the log level to + journal-or-kmsg + (resp. console on + SIGRTMIN+27; + resp. kmsg on + SIGRTMIN+28; + resp. syslog-or-kmsg + on SIGRTMIN+29), as + controlled via + systemd.log_target=journal-or-kmsg + (resp. systemd.log_target=console + on SIGRTMIN+27; + resp. systemd.log_target=kmsg + on SIGRTMIN+28; + resp + systemd.log_target=syslog-or-kmsg + on SIGRTMIN+29) on + the kernel command + line. + + + + + + Environment + + + + $SYSTEMD_LOG_LEVEL + systemd reads the + log level from this environment + variable. This can be overridden with + . + + + + $SYSTEMD_LOG_TARGET + systemd reads the + log target from this environment + variable. This can be overridden with + . + + + + $SYSTEMD_LOG_COLOR + Controls whether + systemd highlights important log + messages. This can be overridden with + . + + + + $SYSTEMD_LOG_LOCATION + Controls whether + systemd prints the code location along + with log messages. This can be + overridden with + . + + + + $XDG_CONFIG_HOME + $XDG_CONFIG_DIRS + $XDG_DATA_HOME + $XDG_DATA_DIRS + + The systemd user + manager uses these variables in + accordance to the XDG + Base Directory specification + to find its configuration. + + + + $SYSTEMD_UNIT_PATH + + Controls where systemd + looks for unit + files. + + + + $SYSTEMD_SYSVINIT_PATH + + Controls where systemd + looks for SysV init scripts. + + + + $SYSTEMD_SYSVRCND_PATH + + Controls where systemd + looks for SysV init script runlevel link + farms. + + + + $LISTEN_PID + $LISTEN_FDS + + Set by systemd for + supervised processes during + socket-based activation. See + sd_listen_fds3 + for more information. + + + + + $NOTIFY_SOCKET + + Set by systemd for + supervised processes for status and + start-up completion notification. See + sd_notify3 + for more information. + + + + + + + Kernel Command Line + + When run as system instance systemd parses a few kernel command line arguments: + + + + systemd.unit= + + Overrides the unit to + activate on boot. Defaults to + default.target. This + may be used to temporarily boot into a + different boot unit, for example + rescue.target or + emergency.service. See + systemd.special7 + for details about these + units. + + + + systemd.dump_core= + + Takes a boolean + argument. If + systemd dumps core when it + crashes. Otherwise no core dump is + created. Defaults to + . + + + + systemd.crash_shell= + + Takes a boolean + argument. If + systemd spawns a shell when it + crashes. Otherwise no shell is + spawned. Defaults to + , for security + reasons, as the shell is not protected + by any password + authentication. + + + + systemd.crash_chvt= + + Takes an integer + argument. If positive systemd + activates the specified virtual + terminal when it crashes. Defaults to + -1. + + + + systemd.confirm_spawn= + + Takes a boolean + argument. If + asks for confirmation when spawning + processes. Defaults to + . + + + + systemd.show_status= + + Takes a boolean + argument. If + shows terse service status updates on + the console during bootup. Defaults to + . + + + + systemd.sysv_console= + + Takes a boolean + argument. If + output of SysV init scripts will be + directed to the console. Defaults to + , unless + is passed as + kernel command line option in which + case it defaults to + . + + + + systemd.log_target= + systemd.log_level= + systemd.log_color= + systemd.log_location= + + Controls log output, + with the same effect as the + $SYSTEMD_LOG_TARGET, $SYSTEMD_LOG_LEVEL, $SYSTEMD_LOG_COLOR, $SYSTEMD_LOG_LOCATION + environment variables described above. + + + + systemd.default_standard_output= + systemd.default_standard_error= + Controls default + standard output/error output for + services, with the same effect as the + + resp. + command line arguments described + above. + + + + systemd.setenv= + + Takes a string + argument in the form + VARIABLE=VALUE. May be used to set + environment variables for the init + process and all its children at boot + time. May be used more than once to + set multiple variables. If the equal + sign and variable are missing unsets + an environment variable which might be + passed in from the initial ram + disk. + + + + + + + Sockets and FIFOs + + + + /run/systemd/notify + + Daemon status + notification socket. This is an + AF_UNIX datagram socket and is used to + implement the daemon notification + logic as implemented by + sd_notify3. + + + + + /run/systemd/shutdownd + + Used internally by the + shutdown8 + tool to implement delayed + shutdowns. This is an AF_UNIX datagram + socket. + + + + /run/systemd/private + + Used internally as + communication channel between + systemctl1 + and the systemd process. This is an + AF_UNIX stream socket. This interface + is private to systemd and should not + be used in external + projects. + + + + /dev/initctl + + Limited compatibility + support for the SysV client interface, + as implemented by the + systemd-initctl.service + unit. This is a named pipe in the file + system. This interface is obsolete and + should not be used in new + applications. + + + + + + See Also + + systemctl1, + systemadm1, + systemd-notify1, + daemon7, + sd-daemon7, + systemd.unit5, + systemd.special5, + pkg-config1 + + + + diff --git a/man/telinit.8 b/man/telinit.8 new file mode 100644 index 0000000..4db6958 --- /dev/null +++ b/man/telinit.8 @@ -0,0 +1,116 @@ +'\" t +.\" Title: telinit +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: telinit +.\" Source: systemd +.\" Language: English +.\" +.TH "TELINIT" "8" "02/15/2012" "systemd" "telinit" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +telinit \- Change SysV runlevel +.SH "SYNOPSIS" +.HP \w'\fBtelinit\ \fR\fB[OPTIONS...]\fR\fB\ \fR\fB{COMMAND}\fR\ 'u +\fBtelinit \fR\fB[OPTIONS...]\fR\fB \fR\fB{COMMAND}\fR +.SH "DESCRIPTION" +.PP +\fBtelinit\fR +may be used to change the SysV system runlevel\&. Since the concept of SysV runlevels is obsolete the runlevel requests will be transparently translated into systemd unit activation requests\&. +.SH "OPTIONS" +.PP +The following options are understood: +.PP +\fB\-\-help\fR +.RS 4 +Prints a short help text and exits\&. +.RE +.PP +\fB\-\-no\-wall\fR +.RS 4 +Don\*(Aqt send wall message before reboot/halt/power\-off\&. +.RE +.PP +The following commands are understood: +.PP +\fB0\fR +.RS 4 +Power\-off the machine\&. This is translated into an activation request for +poweroff\&.target +and is equivalent to +\fBsystemctl poweroff\fR\&. +.RE +.PP +\fB6\fR +.RS 4 +Reboot the machine\&. This is translated into an activation request for +reboot\&.target +and is equivalent to +\fBsystemctl reboot\fR\&. +.RE +.PP +\fB2\fR, \fB3\fR, \fB4\fR, \fB5\fR +.RS 4 +Change the SysV runlevel\&. This is translated into an activation request for +runlevel2\&.target, +runlevel3\&.target, \&.\&.\&. and is equivalent to +\fBsystemctl isolate runlevel2\&.target\fR, +\fBsystemctl isolate runlevel3\&.target\fR, \&.\&.\&. +.RE +.PP +\fB1\fR, \fBs\fR, \fBS\fR +.RS 4 +Change into system rescue mode\&. This is translated into an activation request for +rescue\&.target +and is equivalent to +\fBsystemctl rescue\fR\&. +.RE +.PP +\fBq\fR, \fBQ\fR +.RS 4 +Reload daemon configuration\&. This is equivalent to +\fBsystemctl daemon\-reload\fR\&. +.RE +.PP +\fBu\fR, \fBU\fR +.RS 4 +Serialize state, reexecute daemon and deserialize state again\&. This is equivalent to +\fBsystemctl daemon\-reexec\fR\&. +.RE +.SH "EXIT STATUS" +.PP +On success 0 is returned, a non\-zero failure code otherwise\&. +.SH "NOTES" +.PP +This is a legacy command available for compatibility only\&. It should not be used anymore, as the concept of runlevels is obsolete\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemctl\fR(1), +\fBwall\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/telinit.xml b/man/telinit.xml new file mode 100644 index 0000000..fec059a --- /dev/null +++ b/man/telinit.xml @@ -0,0 +1,195 @@ + + + + + + + + + telinit + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + telinit + 8 + + + + telinit + Change SysV runlevel + + + + + telinit OPTIONS COMMAND + + + + + Description + + telinit may be used to change + the SysV system runlevel. Since the concept of SysV + runlevels is obsolete the runlevel requests + will be transparently translated into systemd unit + activation requests. + + + + + Options + + The following options are understood: + + + + + + Prints a short help + text and exits. + + + + + + Don't send wall + message before + reboot/halt/power-off. + + + + The following commands are understood: + + + + 0 + + Power-off the + machine. This is translated into an + activation request for + poweroff.target + and is equivalent to + systemctl + poweroff. + + + + 6 + + Reboot the + machine. This is translated into an + activation request for + reboot.target and + is equivalent to systemctl + reboot. + + + + 2 + 3 + 4 + 5 + + Change the SysV + runlevel. This is translated into an + activation request for + runlevel2.target, + runlevel3.target, + ... and is equivalent to + systemctl isolate + runlevel2.target, + systemctl isolate + runlevel3.target, + ... + + + + 1 + s + S + + Change into system + rescue mode. This is translated into + an activation request for + rescue.target and + is equivalent to systemctl + rescue. + + + + q + Q + + Reload daemon + configuration. This is equivalent to + systemctl + daemon-reload. + + + + u + U + + Serialize state, + reexecute daemon and deserialize state + again. This is equivalent to + systemctl + daemon-reexec. + + + + + + + Exit status + + On success 0 is returned, a non-zero failure + code otherwise. + + + + Notes + + This is a legacy command available for compatibility + only. It should not be used anymore, as the concept of + runlevels is obsolete. + + + + See Also + + systemd1, + systemctl1, + wall1 + + + + diff --git a/man/timezone.5 b/man/timezone.5 new file mode 100644 index 0000000..5ff661d --- /dev/null +++ b/man/timezone.5 @@ -0,0 +1,62 @@ +'\" t +.\" Title: timezone +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: /etc/timezone +.\" Source: systemd +.\" Language: English +.\" +.TH "TIMEZONE" "5" "02/15/2012" "systemd" "/etc/timezone" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +timezone \- Local time zone configuration file +.SH "SYNOPSIS" +.PP +/etc/timezone +.SH "DESCRIPTION" +.PP +The +/etc/timezone +file configures the system\-wide time zone of the local system that is used by applications for presentation to the user\&. It should contain a single newline\-terminated line consisting of a time zone identifier such as +Europe/Berlin\&. The file +/etc/localtime +corresponds with +/etc/timezone +and contains the binary time zone data for the time zone\&. These files should always be changed simultaneously and kept in sync\&. +.PP +The time zone may be overridden for individual programs by using the TZ environment variable\&. See +\fBenviron\fR(7)\&. +.SH "HISTORY" +.PP +The simple configuration file format of +/etc/timezone +originates from Debian GNU/Linux\&. +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/timezone.xml b/man/timezone.xml new file mode 100644 index 0000000..4e33279 --- /dev/null +++ b/man/timezone.xml @@ -0,0 +1,90 @@ + + + + + + + + + /etc/timezone + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + timezone + 5 + + + + timezone + Local time zone configuration file + + + + /etc/timezone + + + + Description + + The /etc/timezone file + configures the system-wide time zone of the local + system that is used by applications for presentation + to the user. It should contain a single + newline-terminated line consisting of a time zone + identifier such as + Europe/Berlin. The file + /etc/localtime corresponds with + /etc/timezone and contains the + binary time zone data for the time zone. These files + should always be changed simultaneously and kept in + sync. + + The time zone may be overridden for individual + programs by using the TZ environment variable. See + environ7. + + + + History + + The simple configuration file format of + /etc/timezone originates from + Debian GNU/Linux. + + + + See Also + + systemd1 + + + + diff --git a/man/tmpfiles.d.5 b/man/tmpfiles.d.5 new file mode 100644 index 0000000..447a5d8 --- /dev/null +++ b/man/tmpfiles.d.5 @@ -0,0 +1,193 @@ +'\" t +.\" Title: tmpfiles.d +.\" Author: Brandon Philips +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: tmpfiles.d +.\" Source: systemd +.\" Language: English +.\" +.TH "TMPFILES\&.D" "5" "02/15/2012" "systemd" "tmpfiles.d" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +tmpfiles.d \- Configuration for creation, deletion and cleaning of volatile and temporary files +.SH "SYNOPSIS" +.PP +/usr/lib/tmpfiles\&.d/*\&.conf +.PP +/etc/tmpfiles\&.d/*\&.conf +.PP +/run/tmpfiles\&.d/*\&.conf +.SH "DESCRIPTION" +.PP +\fBsystemd\-tmpfiles\fR +uses the configuration files from the above directories to describe the creation, cleaning and removal of volatile and temporary files and directories which usually reside in directories such as +/run +or +/tmp\&. +.SH "CONFIGURATION FORMAT" +.PP +Each configuration file is named in the style of +\&.conf\&. Files in +/etc/ +override files with the same name in +/usr/lib/\&. Files in +/run +override files with the same name in +/etc/ +and +/usr/lib/\&. Packages should install their configuration files in +/usr/lib/, files in +/etc/ +are reserved for the local administrator, who may choose to override the configurations installed from packages\&. The list of configuration files are sorted by their filename in alphabetical order, regardless in which of the directories they reside, to guarantee that a configuration file takes precedence over another configuration file with an alphabetically later name\&. +.PP +The configuration format is one line per path containing action, path, mode, ownership, age and argument fields: +.sp +.if n \{\ +.RS 4 +.\} +.nf +Type Path Mode UID GID Age Argument +d /run/user 0755 root root 10d \- +L /tmp/foobar \- \- \- \- /dev/null +.fi +.if n \{\ +.RE +.\} +.SS "Type" +.PP +\fIf\fR +.RS 4 +Create a file if it doesn\*(Aqt exist yet (optionally writing a short string into it, if the argument parameter is passed) +.RE +.PP +\fIF\fR +.RS 4 +Create or truncate a file (optionally writing a short string into it, if the argument parameter is passed) +.RE +.PP +\fIw\fR +.RS 4 +Write the argument parameter to a file, if it exists\&. +.RE +.PP +\fId\fR +.RS 4 +Create a directory if it doesn\*(Aqt exist yet +.RE +.PP +\fID\fR +.RS 4 +Create or empty a directory +.RE +.PP +\fIp\fR +.RS 4 +Create a named pipe (FIFO) if it doesn\*(Aqt exist yet +.RE +.PP +\fIL\fR +.RS 4 +Create a symlink if it doesn\*(Aqt exist yet +.RE +.PP +\fIc\fR +.RS 4 +Create a character device node if it doesn\*(Aqt exist yet +.RE +.PP +\fIb\fR +.RS 4 +Create a block device node if it doesn\*(Aqt exist yet +.RE +.PP +\fIx\fR +.RS 4 +Ignore a path during cleaning\&. Use this type to exclude paths from clean\-up as controlled with the Age parameter\&. Note that lines of this type do not influence the effect of r or R lines\&. Lines of this type accept shell\-style globs in place of of normal path names\&. +.RE +.PP +\fIr\fR +.RS 4 +Remove a file or directory if it exists\&. This may not be used to remove non\-empty directories, use R for that\&. Lines of this type accept shell\-style globs in place of normal path names\&. +.RE +.PP +\fIR\fR +.RS 4 +Recursively remove a path and all its subdirectories (if it is a directory)\&. Lines of this type accept shell\-style globs in place of normal path names\&. +.RE +.PP +\fIz\fR +.RS 4 +Set ownership, access mode and relabel security context of a file or directory if it exists\&. Lines of this type accept shell\-style globs in place of normal path names\&. +.RE +.PP +\fIZ\fR +.RS 4 +Recursively set ownership, access mode and relabel security context of a path and all its subdirectories (if it is a directory)\&. Lines of this type accept shell\-style globs in place of normal path names\&. +.RE +.SS "Mode" +.PP +The file access mode to use when creating this file or directory\&. If omitted or when set to \- the default is used: 0755 for directories, 0644 for all other file objects\&. For z, Z lines if omitted or when set to \- the file access mode will not be modified\&. This parameter is ignored for x, r, R, L lines\&. +.SS "UID, GID" +.PP +The user and group to use for this file or directory\&. This may either be a numeric user/group ID or a user or group name\&. If omitted or when set to \- the default 0 (root) is used\&. For z, Z lines when omitted or when set to \- the file ownership will not be modified\&. These parameters are ignored for x, r, R, L lines\&. +.SS "Age" +.PP +The date field, when set, is used to decide what files to delete when cleaning\&. If a file or directory is older than the current time minus the age field it is deleted\&. The field format is a series of integers each followed by one of the following postfixes for the respective time units: +.PP +\fIs\fR, \fImin\fR, \fIh\fR, \fId\fR, \fIw\fR, \fIms\fR, \fIm\fR, \fIus\fR +.RS 4 +.RE +.PP +If multiple integers and units are specified the time values are summed up\&. +.PP +The age field only applies to lines starting with d, D and x\&. If omitted or set to \- no automatic clean\-up is done\&. +.SS "Argument" +.PP +For L lines determines the destination path of the symlink\&. For c, b determines the major/minor of the device node, with major and minor formatted as integers, separated by :, e\&.g\&. "1:3"\&. For f, F, w may be used to specify a short string that is written to the file, suffixed by a newline\&. Ignored for all other lines\&. +.SH "EXAMPLE" +.PP +\fBExample\ \&1.\ \&/etc/tmpfiles.d/screen.conf example\fR +.PP +\fBscreen\fR +needs two directories created at boot with specific modes and ownership\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf +d /var/run/screens 1777 root root 10d +d /var/run/uscreens 0755 root root 10d12h +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBsystemd-tmpfiles\fR(8) +.SH "AUTHOR" +.PP +\fBBrandon Philips\fR <\&brandon@ifup\&.org\&> +.RS 4 +Documentation +.RE diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml new file mode 100644 index 0000000..25a7c9b --- /dev/null +++ b/man/tmpfiles.d.xml @@ -0,0 +1,295 @@ + + + + + + + + tmpfiles.d + systemd + + + + Documentation + Brandon + Philips + brandon@ifup.org + + + + + + tmpfiles.d + 5 + + + + tmpfiles.d + Configuration for creation, deletion and + cleaning of volatile and temporary files + + + + /usr/lib/tmpfiles.d/*.conf + /etc/tmpfiles.d/*.conf + /run/tmpfiles.d/*.conf + + + + Description + + systemd-tmpfiles uses the + configuration files from the above directories to describe the + creation, cleaning and removal of volatile and + temporary files and directories which usually reside + in directories such as /run + or /tmp. + + + + Configuration Format + + Each configuration file is named in the style of + <program>.conf. Files in + /etc/ override files with the + same name in /usr/lib/. Files in + /run override files with the same + name in /etc/ and + /usr/lib/. Packages should + install their configuration files in + /usr/lib/, files in + /etc/ are reserved for the local + administrator, who may choose to override the + configurations installed from packages. The list of + configuration files are sorted by their filename in + alphabetical order, regardless in which of the + directories they reside, to guarantee that a + configuration file takes precedence over another + configuration file with an alphabetically later + name. + + The configuration format is one line per path + containing action, path, mode, ownership, age and argument + fields: + + Type Path Mode UID GID Age Argument +d /run/user 0755 root root 10d - +L /tmp/foobar - - - - /dev/null + + + Type + + + f + Create a file if it doesn't exist yet (optionally writing a short string into it, if the argument parameter is passed) + + + + F + Create or truncate a file (optionally writing a short string into it, if the argument parameter is passed) + + + + w + Write the argument parameter to a file, if it exists. + + + + d + Create a directory if it doesn't exist yet + + + + D + Create or empty a directory + + + + p + Create a named pipe (FIFO) if it doesn't exist yet + + + + L + Create a symlink if it doesn't exist yet + + + + c + Create a character device node if it doesn't exist yet + + + + b + Create a block device node if it doesn't exist yet + + + + x + Ignore a path + during cleaning. Use this type + to exclude paths from clean-up + as controlled with the Age + parameter. Note that lines of + this type do not influence the + effect of r or R lines. Lines + of this type accept + shell-style globs in place of + of normal path + names. + + + + r + Remove a file + or directory if it + exists. This may not be used + to remove non-empty + directories, use R for + that. Lines of this type + accept shell-style globs in + place of normal path + names. + + + + R + Recursively + remove a path and all its + subdirectories (if it is a + directory). Lines of this type + accept shell-style globs in + place of normal path + names. + + + + z + Set ownership, access + mode and relabel security context of + a file or directory if it exists. + Lines of this type accept shell-style + globs in place of normal path names. + + + + + Z + Recursively set + ownership, access mode and relabel + security context of a path and + all its subdirectories (if it is a + directory). Lines of this type accept + shell-style globs in place of normal + path names. + + + + + + Mode + + The file access mode to use when + creating this file or directory. If omitted or + when set to - the default is used: 0755 for + directories, 0644 for all other file + objects. For z, Z lines if omitted or when set + to - the file access mode will not be + modified. This parameter is ignored for x, r, + R, L lines. + + + + UID, GID + + The user and group to use for this file + or directory. This may either be a numeric + user/group ID or a user or group name. If + omitted or when set to - the default 0 (root) + is used. For z, Z lines when omitted or when set to - + the file ownership will not be modified. + These parameters are ignored for x, r, R, L lines. + + + + Age + The date field, when set, is used to + decide what files to delete when cleaning. If + a file or directory is older than the current + time minus the age field it is deleted. The + field format is a series of integers each + followed by one of the following + postfixes for the respective time units: + + + + s + min + h + d + w + ms + m + us + + + If multiple integers and units are specified the time + values are summed up. + + The age field only applies to lines starting with + d, D and x. If omitted or set to - no automatic clean-up + is done. + + + + Argument + + For L lines determines the destination + path of the symlink. For c, b determines the + major/minor of the device node, with major and + minor formatted as integers, separated by :, + e.g. "1:3". For f, F, w may be used to specify + a short string that is written to the file, + suffixed by a newline. Ignored for all other + lines. + + + + + + Example + + /etc/tmpfiles.d/screen.conf example + screen needs two directories created at boot with specific modes and ownership. + + d /var/run/screens 1777 root root 10d +d /var/run/uscreens 0755 root root 10d12h + + + + + See Also + + systemd1, + systemd-tmpfiles8 + + + + diff --git a/man/vconsole.conf.5 b/man/vconsole.conf.5 new file mode 100644 index 0000000..ea766d2 --- /dev/null +++ b/man/vconsole.conf.5 @@ -0,0 +1,104 @@ +'\" t +.\" Title: vconsole.conf +.\" Author: Lennart Poettering +.\" Generator: DocBook XSL Stylesheets v1.76.1 +.\" Date: 02/15/2012 +.\" Manual: vconsole.conf +.\" Source: systemd +.\" Language: English +.\" +.TH "VCONSOLE\&.CONF" "5" "02/15/2012" "systemd" "vconsole.conf" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +vconsole.conf \- configuration file for the virtual console +.SH "SYNOPSIS" +.PP +/etc/vconsole\&.conf +.SH "DESCRIPTION" +.PP +The +/etc/vconsole\&.conf +file configures the virtual console, i\&.e\&. keyboard mapping and console font\&. +.PP +The basic file format of the +vconsole\&.conf +is a newline\-separated list environment\-like shell\-compatible variable assignments\&. It is possible to source the configuration from shell scripts, however, beyond mere variable assignments no shell features are supported, allowing applications to read the file without implementing a shell compatible execution engine\&. +.PP +Note that the kernel command line options +\fIvconsole\&.keymap=\fR, +\fIvconsole\&.keymap\&.toggle=\fR, +\fIvconsole\&.font=\fR, +\fIvconsole\&.font\&.map=\fR, +\fIvconsole\&.font\&.unimap=\fR +may be used to override the console settings at boot\&. +.PP +Depending on the operating system other configuration files might be checked for configuration of the virtual console as well, however only as fallback\&. +.SH "OPTIONS" +.PP +The following options are understood: +.PP +\fIKEYMAP=\fR, \fIKEYMAP_TOGGLE=\fR +.RS 4 +Configures the key mapping table of for they keyboard\&. +\fIKEYMAP=\fR +defaults to +us +if not set\&. The +\fIKEYMAP_TOGGLE=\fR +can be used to configured a second toggle keymap and is by default unset\&. +.RE +.PP +\fIFONT=\fR, \fIFONT_MAP=\fR, \fIFONT_UNIMAP=\fR +.RS 4 +Configures the console font, the console map and the unicode font map\&. +\fIFONT=\fR +defaults to +latarcyrheb\-sun16\&. +.RE +.SH "EXAMPLE" +.PP +\fBExample\ \&1.\ \&German keyboard and console\fR +.PP +/etc/vconsole\&.conf: +.sp +.if n \{\ +.RS 4 +.\} +.nf +KEYMAP=de\-latin1 +FONT=latarcyrheb\-sun16 +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.PP + +\fBsystemd\fR(1), +\fBloadkeys\fR(1), +\fBsetfont\fR(8), +\fBlocale.conf\fR(5) +.SH "AUTHOR" +.PP +\fBLennart Poettering\fR <\&lennart@poettering\&.net\&> +.RS 4 +Developer +.RE diff --git a/man/vconsole.conf.xml b/man/vconsole.conf.xml new file mode 100644 index 0000000..a73db00 --- /dev/null +++ b/man/vconsole.conf.xml @@ -0,0 +1,146 @@ + + + + + + + + + vconsole.conf + systemd + + + + Developer + Lennart + Poettering + lennart@poettering.net + + + + + + vconsole.conf + 5 + + + + vconsole.conf + configuration file for the virtual console + + + + /etc/vconsole.conf + + + + Description + + The /etc/vconsole.conf file + configures the virtual console, i.e. keyboard mapping + and console font. + + The basic file format of the + vconsole.conf is a + newline-separated list environment-like + shell-compatible variable assignments. It is possible + to source the configuration from shell scripts, + however, beyond mere variable assignments no shell + features are supported, allowing applications to read + the file without implementing a shell compatible + execution engine. + + Note that the kernel command line options + vconsole.keymap=, + vconsole.keymap.toggle=, + vconsole.font=, + vconsole.font.map=, + vconsole.font.unimap= may be used + to override the console settings at boot. + + Depending on the operating system other + configuration files might be checked for configuration + of the virtual console as well, however only as + fallback. + + + + Options + + The following options are understood: + + + + + KEYMAP= + KEYMAP_TOGGLE= + + Configures the key + mapping table of for they + keyboard. KEYMAP= + defaults to us if + not set. The + KEYMAP_TOGGLE= can + be used to configured a second toggle + keymap and is by default + unset. + + + + FONT= + FONT_MAP= + FONT_UNIMAP= + + Configures the console + font, the console map and the unicode + font map. FONT= + defaults to + latarcyrheb-sun16. + + + + + + + Example + + + German keyboard and console + + /etc/vconsole.conf: + + KEYMAP=de-latin1 +FONT=latarcyrheb-sun16 + + + + + + See Also + + systemd1, + loadkeys1, + setfont8, + locale.conf5 + + + + diff --git a/missing b/missing new file mode 100755 index 0000000..86a8fc3 --- /dev/null +++ b/missing @@ -0,0 +1,331 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2012-01-06.13; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/packaging/0002-systemd-fsck-disable-l-until-linux.patch b/packaging/0002-systemd-fsck-disable-l-until-linux.patch new file mode 100644 index 0000000..e7b50c5 --- /dev/null +++ b/packaging/0002-systemd-fsck-disable-l-until-linux.patch @@ -0,0 +1,25 @@ +From 69e7f67292ce52bf123958f392084ddae90a2ec1 Mon Sep 17 00:00:00 2001 +From: Chris E Ferron +Date: Fri, 20 Jan 2012 11:27:56 -0800 +Subject: [PATCH 2/2] systemd fsck disable l until linux + +--- + src/fsck.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/src/fsck.c b/src/fsck.c +index c5088ad..7408654 100644 +--- a/src/fsck.c ++++ b/src/fsck.c +@@ -322,7 +322,7 @@ int main(int argc, char *argv[]) { + cmdline[i++] = "/sbin/fsck"; + cmdline[i++] = "-a"; + cmdline[i++] = "-T"; +- cmdline[i++] = "-l"; ++ /* cmdline[i++] = "-l"; */ /* not supported in meego's util-linux */ + + if (!root_directory) + cmdline[i++] = "-M"; +-- +1.7.7.5 + diff --git a/packaging/add-tmp.mount-as-tmpfs.patch b/packaging/add-tmp.mount-as-tmpfs.patch new file mode 100644 index 0000000..a37f174 --- /dev/null +++ b/packaging/add-tmp.mount-as-tmpfs.patch @@ -0,0 +1,55 @@ +From 8598715564c7c8d7b7ed75e98bd57cc44b16b318 Mon Sep 17 00:00:00 2001 +From: William Douglas +Date: Fri, 20 Apr 2012 14:20:14 -0700 +Subject: [PATCH 1/3] add tmp.mount to mount /tmp as tmpfs + +--- + Makefile.am | 7 +++++++ + units/tizen/tmp.mount | 10 ++++++++++ + 2 files changed, 17 insertions(+) + create mode 100644 units/tizen/tmp.mount + +diff --git a/Makefile.am b/Makefile.am +index 9762da1..d24649e 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -380,6 +380,11 @@ systemgenerator_PROGRAMS += \ + systemd-rc-local-generator + endif + ++if TARGET_MEEGO ++dist_systemunit_DATA += \ ++ units/tizen/tmp.mount ++endif ++ + if TARGET_MANDRIVA + dist_systemunit_DATA += \ + units/mandriva/prefdm.service \ +@@ -2433,6 +2438,8 @@ if TARGET_MEEGO + rm -f * ) + ( cd $(DESTDIR)$(pkgsysconfdir)/system/local-fs.target.wants && \ + rm -f * ) ++ ( cd $(DESTDIR)$(systemunitdir)/local-fs.target.wants && \ ++ $(LN_S) $(systemunitdir)/tmp.mount tmp.mount ) + ( cd $(DESTDIR)$(pkgsysconfdir)/system/multi-user.target.wants && \ + rm -f * ) + ( cd $(DESTDIR)$(pkgsysconfdir)/system/getty.target.wants && \ +diff --git a/units/tizen/tmp.mount b/units/tizen/tmp.mount +new file mode 100644 +index 0000000..7c3e98c +--- /dev/null ++++ b/units/tizen/tmp.mount +@@ -0,0 +1,10 @@ ++ ++[Unit] ++Description=Runtime Directory ++Before=local-fs.target ++ ++[Mount] ++What=tmpfs ++Where=/tmp ++Type=tmpfs ++Options=relatime,nodev,nosuid,noexec,size=128M +-- +1.7.10 + diff --git a/packaging/pamconsole-tmp.conf b/packaging/pamconsole-tmp.conf new file mode 100644 index 0000000..e57aa60 --- /dev/null +++ b/packaging/pamconsole-tmp.conf @@ -0,0 +1 @@ +d /var/run/console 0755 root root - diff --git a/packaging/systemd.changes b/packaging/systemd.changes new file mode 100644 index 0000000..ba6d1da --- /dev/null +++ b/packaging/systemd.changes @@ -0,0 +1,2 @@ +* Wed Jun 13 2012 William Douglas - 43 +- Add systemd 43 diff --git a/packaging/systemd.manifest b/packaging/systemd.manifest new file mode 100644 index 0000000..4ef1828 --- /dev/null +++ b/packaging/systemd.manifest @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/packaging/systemd.spec b/packaging/systemd.spec new file mode 100644 index 0000000..0fde879 --- /dev/null +++ b/packaging/systemd.spec @@ -0,0 +1,342 @@ +%define _sbindir /sbin +Name: systemd +Summary: System and Session Manager +Version: 43 +Release: 1 +Group: System/System Control +License: GPLv2 +URL: http://www.freedesktop.org/wiki/Software/systemd +Source0: http://www.freedesktop.org/software/systemd/%{name}-%{version}.tar.xz +Source1: packaging/pamconsole-tmp.conf +Source1001: packaging/systemd.manifest +Patch1: packaging/0002-systemd-fsck-disable-l-until-linux.patch +Patch2: packaging/add-tmp.mount-as-tmpfs.patch +Patch3: packaging/tizen-login-location.patch +Patch4: packaging/tizen-service-file-workaround.patch + +BuildRequires: pkgconfig(dbus-1) >= 1.4.0 +BuildRequires: pkgconfig(dbus-glib-1) +BuildRequires: pkgconfig(gio-unix-2.0) +BuildRequires: pkgconfig(libudev) >= 174 +BuildRequires: libcap-devel +BuildRequires: gperf +BuildRequires: libxslt +BuildRequires: docbook-dtds +BuildRequires: docbook-xsl +BuildRequires: pam-devel +BuildRequires: intltool >= 0.40.0 +BuildRequires: libacl-devel +BuildRequires: fdupes +BuildRequires: pkgconfig(libkmod) +Requires(post): %{_sbindir}/ldconfig +Requires(postun): %{_sbindir}/ldconfig + +%description +system and session manager for Linux, compatible with SysV and +LSB init scripts. systemd provides aggressive parallelization +capabilities, uses socket and D-Bus activation for starting +services, offers on-demand starting of daemons, keeps track of +processes using Linux cgroups, supports snapshotting and restoring +of the system state, maintains mount and automount points and +implements an elaborate transactional dependency-based service +control logic. It can work as a drop-in replacement for sysvinit. + +%package tools +Summary: Analyze systemd startup timing +Group: Development/Tools +Requires: pycairo +Requires: python-xml +Requires: %{name} = %{version}-%{release} + +%description tools +This package installs the systemd-analyze tool, which allows one to +inspect and graph service startup timing in table or graph format. + +%package devel +Summary: Development tools for systemd +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +Requires(post): %{_sbindir}/ldconfig +Requires(postun): %{_sbindir}/ldconfig + +%description devel +This package includes the libraries and header files you will need +to compile applications for systemd. + +%package console-ttyS0 +Summary: Systemd console ttyS0 +Group: System/System Control +Requires: %{name} + +%description console-ttyS0 +This package will setup a serial getty for ttyS0 is desired. + + +%package console-ttyS1 +Summary: Systemd console ttyS1 +Group: System/System Control +Requires: %{name} + +%description console-ttyS1 +This package will setup a serial getty for ttyS1 is desired. + + +%package console-tty01 +Summary: Systemd console tty01 +Group: System/System Control +Requires: %{name} + +%description console-tty01 +This package will setup a serial getty for tty01 is desired. + + +%package console-ttyO2 +Summary: Systemd console ttyO2 +Group: System/System Control +Requires: %{name} + +%description console-ttyO2 +This package will setup a serial getty for ttyO2 is desired. + +%package console-ttyMFD2 +Summary: Systemd console ttyMFD2 +Group: System/System Control +Requires: %{name} + +%description console-ttyMFD2 +This package will setup a serial getty for ttyMFD2 is desired. + +%package docs +Summary: System and session manager man pages +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description docs +This package includes the man pages for systemd. + + +%package sysv-docs +Summary: System and session manager man pages - SysV links +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description sysv-docs +This package provides the manual pages needed for systemd +to replace sysvinit. + +%package sysv +Summary: System and session manager - SysV links +Group: System/Startup Services +Requires: %{name} = %{version}-%{release} + +%description sysv +Systemd is a replacement for sysvinit. It is dependency-based and +able to read the LSB init script headers in addition to parsing rcN.d +links as hints. + +It also provides process supervision using cgroups and the ability to +not only depend on other init script being started, but also +availability of a given mount point or dbus service. + +This package provides the links needed for systemd +to replace sysvinit. + + +%prep +%setup -q -n %{name}-%{version} +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 + +%build +cp %{SOURCE1001} . +%configure --disable-static \ + --with-rootdir="" \ + --with-distro=meego \ + --disable-gtk \ + --disable-selinux \ + --disable-tcpwrap \ + --enable-manpages \ + --with-pamlibdir="/%{_libdir}/security" \ + --with-udevrulesdir="%{_libdir}/udev/rules.d" + +make %{?_smp_mflags} + +%install +%make_install + +# Create SysV compatibility symlinks. systemctl/systemd are smart +# enough to detect in which way they are called. +install -d %{buildroot}%{_sbindir}/ +ln -s ..%{_libdir}/systemd/systemd %{buildroot}%{_sbindir}/init +ln -s ..%{_bindir}/systemctl %{buildroot}%{_sbindir}/halt +ln -s ..%{_bindir}/systemctl %{buildroot}%{_sbindir}/poweroff +ln -s ..%{_bindir}/systemctl %{buildroot}%{_sbindir}/reboot +ln -s ..%{_bindir}/systemctl %{buildroot}%{_sbindir}/runlevel +ln -s ..%{_bindir}/systemctl %{buildroot}%{_sbindir}/shutdown +ln -s ..%{_bindir}/systemctl %{buildroot}%{_sbindir}/telinit + +# /usr compat - delete when no longer needed +install -d %{buildroot}/bin/ +ln -s ..%{_bindir}/systemctl %{buildroot}/bin/systemctl + +mkdir %{buildroot}/run + +# Make sure these directories are properly owned +mkdir -p %{buildroot}%{_libdir}/systemd/system/basic.target.wants +mkdir -p %{buildroot}%{_libdir}/systemd/system/dbus.target.wants + +# enable readahead by default +ln -s ../systemd-readahead-collect.service %{buildroot}%{_libdir}/systemd/system/sysinit.target.wants/systemd-readahead-collect.service +ln -s ../systemd-readahead-replay.service %{buildroot}%{_libdir}/systemd/system/sysinit.target.wants/systemd-readahead-replay.service + +# Don't ship documentation in the wrong place +rm %{buildroot}/%{_docdir}/systemd/* + +mkdir -p %{buildroot}/etc/systemd/system/basic.target.wants + +#console-ttyMFD2 +ln -s ../serial-getty@.service %{buildroot}%{_libdir}/systemd/system/sysinit.target.wants/serial-getty@ttyMFD2.service + +#console-ttyS0 +ln -s ../serial-getty@.service %{buildroot}%{_libdir}/systemd/system/sysinit.target.wants/serial-getty@ttyS0.service + +#console-ttyS1 +ln -s ../serial-getty@.service %{buildroot}%{_libdir}/systemd/system/sysinit.target.wants/serial-getty@ttyS1.service + +#console-tty01 +ln -s ../serial-getty@.service %{buildroot}%{_libdir}/systemd/system/sysinit.target.wants/serial-getty@tty01.service + +#console-ttyO2 +ln -s ../serial-getty@.service %{buildroot}%{_libdir}/systemd/system/sysinit.target.wants/serial-getty@ttyO2.service + +%fdupes %{buildroot}/%{_datadir}/man/ + +%post +if [ "`readlink /etc/mtab`" != "/proc/self/mounts" ]; then + rm -f /etc/mtab + ln -s /proc/self/mounts /etc/mtab +fi + +/usr/bin/systemd-machine-id-setup >/dev/null 2>&1 || : + +%{_sbindir}/ldconfig + +%postun -p %{_sbindir}/ldconfig +%post devel -p %{_sbindir}/ldconfig +%postun devel -p %{_sbindir}/ldconfig + + +%files +%defattr(-,root,root,-) +%manifest systemd.manifest +/bin/systemctl +%{_bindir}/* +/run +%config %{_libdir}/sysctl.d/coredump.conf +%config %{_sysconfdir}/dbus-1/system.d/org.freedesktop.systemd1.conf +%config %{_sysconfdir}/dbus-1/system.d/org.freedesktop.hostname1.conf +%config %{_sysconfdir}/dbus-1/system.d/org.freedesktop.locale1.conf +%config %{_sysconfdir}/dbus-1/system.d/org.freedesktop.login1.conf +%config %{_sysconfdir}/dbus-1/system.d/org.freedesktop.timedate1.conf +%attr(0644,root,root) %{_libdir}/udev/rules.d/70-uaccess.rules +%attr(0644,root,root) %{_libdir}/udev/rules.d/71-seat.rules +%attr(0644,root,root) %{_libdir}/udev/rules.d/73-seat-late.rules +%config %{_sysconfdir}/systemd +%config %{_sysconfdir}/xdg/systemd/user +%config %{_sysconfdir}/bash_completion.d/systemd-bash-completion.sh +%{_prefix}/%{_lib}/tmpfiles.d/* +%{_libdir}/systemd +/%{_libdir}/security/pam_systemd.so +%{_libdir}/udev/rules.d/99-systemd.rules +%{_libdir}/libsystemd-daemon.so.0 +%{_libdir}/libsystemd-daemon.so.0.0.1 +%{_libdir}/libsystemd-login.so.0 +%{_libdir}/libsystemd-login.so.0.2.0 +%{_libdir}/libsystemd-id128.so.0 +%{_libdir}/libsystemd-id128.so.0.0.2 +%{_libdir}/libsystemd-journal.so.0 +%{_libdir}/libsystemd-journal.so.0.0.2 +%{_datadir}/dbus-1/*/org.freedesktop.systemd1.* +%{_defaultdocdir}/systemd +%{_datadir}/polkit-1/actions/org.freedesktop.systemd1.policy +%{_datadir}/polkit-1/actions/org.freedesktop.locale1.policy +%{_datadir}/polkit-1/actions/org.freedesktop.login1.policy +%{_datadir}/polkit-1/actions/org.freedesktop.timedate1.policy +%{_datadir}/polkit-1/actions/org.freedesktop.hostname1.policy +%{_datadir}/dbus-1/system-services/org.freedesktop.hostname1.service +%{_datadir}/dbus-1/system-services/org.freedesktop.locale1.service +%{_datadir}/dbus-1/system-services/org.freedesktop.login1.service +%{_datadir}/dbus-1/system-services/org.freedesktop.timedate1.service +%{_datadir}/dbus-1/interfaces/org.freedesktop.hostname1.xml +%{_datadir}/dbus-1/interfaces/org.freedesktop.locale1.xml +%{_datadir}/dbus-1/interfaces/org.freedesktop.timedate1.xml +%{_mandir}/man1/* +%{_mandir}/man3/* +%{_mandir}/man5/* +%{_mandir}/man7/* +%{_mandir}/man8/* +%exclude %{_libdir}/systemd/system/sysinit.target.wants/serial-getty@tty01.service +%exclude %{_libdir}/systemd/system/sysinit.target.wants/serial-getty@ttyMFD2.service +%exclude %{_libdir}/systemd/system/sysinit.target.wants/serial-getty@ttyO2.service +%exclude %{_libdir}/systemd/system/sysinit.target.wants/serial-getty@ttyS0.service +%exclude %{_libdir}/systemd/system/sysinit.target.wants/serial-getty@ttyS1.service +%exclude %{_libdir}/systemd/system/sysinit.target.wants/systemd-vconsole-setup.service +%exclude %{_libdir}/systemd/user/default.target + +%files console-ttyMFD2 +%defattr(-,root,root,-) +%{_libdir}/systemd/system/sysinit.target.wants/serial-getty@ttyMFD2.service + +%files console-ttyS0 +%defattr(-,root,root,-) +%{_libdir}/systemd/system/sysinit.target.wants/serial-getty@ttyS0.service + +%files console-ttyS1 +%defattr(-,root,root,-) +%{_libdir}/systemd/system/sysinit.target.wants/serial-getty@ttyS1.service + +%files console-tty01 +%defattr(-,root,root,-) +%{_libdir}/systemd/system/sysinit.target.wants/serial-getty@tty01.service + +%files console-ttyO2 +%defattr(-,root,root,-) +%{_libdir}/systemd/system/sysinit.target.wants/serial-getty@ttyO2.service + + +%files tools +%defattr(-,root,root,-) +%manifest systemd.manifest +%{_bindir}/systemd-analyze + +%files devel +%defattr(-,root,root,-) +%manifest systemd.manifest +%{_datadir}/pkgconfig/systemd.pc +%{_includedir}/systemd/sd-daemon.h +%{_includedir}/systemd/sd-login.h +%{_includedir}/systemd/sd-id128.h +%{_includedir}/systemd/sd-journal.h +%{_includedir}/systemd/sd-messages.h +%{_libdir}/libsystemd-daemon.so +%{_libdir}/libsystemd-login.so +%{_libdir}/libsystemd-journal.so +%{_libdir}/libsystemd-id128.so +%{_libdir}/pkgconfig/libsystemd-daemon.pc +%{_libdir}/pkgconfig/libsystemd-login.pc +%{_libdir}/pkgconfig/libsystemd-id128.pc +%{_libdir}/pkgconfig/libsystemd-journal.pc +%{_datadir}/systemd/kbd-model-map + +%files sysv +%defattr(-,root,root,-) +%doc LICENSE +%{_sbindir}/halt +%{_sbindir}/init +%{_sbindir}/poweroff +%{_sbindir}/reboot +%{_sbindir}/runlevel +%{_sbindir}/shutdown +%{_sbindir}/telinit diff --git a/packaging/tizen-login-location.patch b/packaging/tizen-login-location.patch new file mode 100644 index 0000000..4befbdf --- /dev/null +++ b/packaging/tizen-login-location.patch @@ -0,0 +1,39 @@ +From 17860355fe8401140c15bfe207c3f925eb88db6c Mon Sep 17 00:00:00 2001 +From: William Douglas +Date: Fri, 20 Apr 2012 14:25:58 -0700 +Subject: [PATCH 2/3] update login path for emergency in tizen distro + +--- + units/emergency.service | 2 +- + units/rescue.service.m4 | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/units/emergency.service b/units/emergency.service +index 234bafc..b1afa68 100644 +--- a/units/emergency.service ++++ b/units/emergency.service +@@ -18,7 +18,7 @@ Environment=HOME=/root + WorkingDirectory=/root + ExecStartPre=-/bin/plymouth quit + ExecStartPre=-/bin/echo 'Welcome to emergency mode. Use "systemctl default" or ^D to activate default mode.' +-ExecStart=-/sbin/sulogin ++ExecStart=-/bin/login + ExecStopPost=/bin/systemctl --fail --no-block default + StandardInput=tty-force + StandardOutput=inherit +diff --git a/units/rescue.service.m4 b/units/rescue.service.m4 +index 7dd8a22..7f60aca 100644 +--- a/units/rescue.service.m4 ++++ b/units/rescue.service.m4 +@@ -31,7 +31,7 @@ ExecStart=-/bin/bash -c "exec ${SINGLE}"', + m4_ifdef(`TARGET_MEEGO', + `EnvironmentFile=/etc/sysconfig/init + ExecStart=-/bin/bash -c "exec ${SINGLE}"', +-`ExecStart=-/sbin/sulogin')))) ++`ExecStart=-/bin/login')))) + ExecStopPost=-/bin/systemctl --fail --no-block default + StandardInput=tty-force + StandardOutput=inherit +-- +1.7.10 + diff --git a/packaging/tizen-service-file-workaround.patch b/packaging/tizen-service-file-workaround.patch new file mode 100644 index 0000000..0703bcd --- /dev/null +++ b/packaging/tizen-service-file-workaround.patch @@ -0,0 +1,65 @@ +From 3a1ebb879b113370519e657aff3275c48ac50e7f Mon Sep 17 00:00:00 2001 +From: William Douglas +Date: Fri, 20 Apr 2012 14:28:58 -0700 +Subject: [PATCH 3/3] update random-seed-load and tmpfile-setup services + +--- + Makefile.am | 2 ++ + units/systemd-random-seed-load.service.in | 2 +- + units/systemd-tmpfiles-clean.service.in | 2 +- + units/systemd-tmpfiles-setup.service.in | 2 +- + 4 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index d24649e..045dbd9 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -2433,6 +2433,8 @@ if TARGET_MEEGO + $(MKDIR_P) -m 0755 $(DESTDIR)$(systemunitdir)/final.target.wants + ( cd $(DESTDIR)$(systemunitdir)/multi-user.target.wants && \ + rm -f network.target && \ ++ $(LN_S) $(systemunitdir)/systemd-random-seed-load.service systemd-random-seed-load.service && \ ++ $(LN_S) $(systemunitdir)/systemd-tmpfiles-setup.service systemd-tmpfiles-setup.service && \ + $(LN_S) $(systemunitdir)/network.target network.target ) + ( cd $(DESTDIR)$(pkgsysconfdir)/system/sysinit.target.wants && \ + rm -f * ) +diff --git a/units/systemd-random-seed-load.service.in b/units/systemd-random-seed-load.service.in +index a2b6a55..867fcd1 100644 +--- a/units/systemd-random-seed-load.service.in ++++ b/units/systemd-random-seed-load.service.in +@@ -11,7 +11,7 @@ DefaultDependencies=no + Wants=local-fs.target + Conflicts=shutdown.target + After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target +-Before=sysinit.target shutdown.target ++##Before=sysinit.target shutdown.target + + [Service] + Type=oneshot +diff --git a/units/systemd-tmpfiles-clean.service.in b/units/systemd-tmpfiles-clean.service.in +index 3c8e72e..14cd18a 100644 +--- a/units/systemd-tmpfiles-clean.service.in ++++ b/units/systemd-tmpfiles-clean.service.in +@@ -18,5 +18,5 @@ ConditionDirectoryNotEmpty=|/run/tmpfiles.d + + [Service] + Type=oneshot +-ExecStart=@rootbindir@/systemd-tmpfiles --clean ++ExecStart=@rootbindir@/systemd-tmpfiles --clean --remove + IOSchedulingClass=idle +diff --git a/units/systemd-tmpfiles-setup.service.in b/units/systemd-tmpfiles-setup.service.in +index f90121e..dec3f6d 100644 +--- a/units/systemd-tmpfiles-setup.service.in ++++ b/units/systemd-tmpfiles-setup.service.in +@@ -10,7 +10,7 @@ Description=Recreate Volatile Files and Directories + DefaultDependencies=no + Wants=local-fs.target + After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target +-Before=sysinit.target shutdown.target ++##Before=sysinit.target shutdown.target + ConditionDirectoryNotEmpty=|/usr/lib/tmpfiles.d + ConditionDirectoryNotEmpty=|/usr/local/lib/tmpfiles.d + ConditionDirectoryNotEmpty=|/etc/tmpfiles.d +-- +1.7.10 + diff --git a/pam_systemd_la_vala.stamp b/pam_systemd_la_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/pam_systemd_la_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/po/Makefile.in.in b/po/Makefile.in.in new file mode 100644 index 0000000..5eb4fe8 --- /dev/null +++ b/po/Makefile.in.in @@ -0,0 +1,217 @@ +# Makefile for program source directory in GNU NLS utilities package. +# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper +# Copyright (C) 2004-2008 Rodney Dawes +# +# This file may be copied and used freely without restrictions. It may +# be used in projects which are not available under a GNU Public License, +# but which still want to provide support for the GNU gettext functionality. +# +# - Modified by Owen Taylor to use GETTEXT_PACKAGE +# instead of PACKAGE and to look for po2tbl in ./ not in intl/ +# +# - Modified by jacob berkman to install +# Makefile.in.in and po2tbl.sed.in for use with glib-gettextize +# +# - Modified by Rodney Dawes for use with intltool +# +# We have the following line for use by intltoolize: +# INTLTOOL_MAKEFILE + +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datadir = @datadir@ +datarootdir = @datarootdir@ +libdir = @libdir@ +DATADIRNAME = @DATADIRNAME@ +itlocaledir = $(prefix)/$(DATADIRNAME)/locale +subdir = po +install_sh = @install_sh@ +# Automake >= 1.8 provides @mkdir_p@. +# Until it can be supposed, use the safe fallback: +mkdir_p = $(install_sh) -d + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +GMSGFMT = @GMSGFMT@ +MSGFMT = @MSGFMT@ +XGETTEXT = @XGETTEXT@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +MSGMERGE = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) XGETTEXT=$(XGETTEXT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist +GENPOT = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) XGETTEXT=$(XGETTEXT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot + +ALL_LINGUAS = @ALL_LINGUAS@ + +PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; else echo "$(ALL_LINGUAS)"; fi) + +USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep \^$$lang$$ $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep \^$$lang$$`"; then printf "$$lang "; fi; done; fi) + +USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)" -o -n "$(LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done) + +POFILES=$(shell LINGUAS="$(PO_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.po "; done) + +DISTFILES = Makefile.in.in POTFILES.in $(POFILES) +EXTRA_DISTFILES = ChangeLog POTFILES.skip Makevars LINGUAS + +POTFILES = \ +# This comment gets stripped out + +CATALOGS=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.gmo "; done) + +.SUFFIXES: +.SUFFIXES: .po .pox .gmo .mo .msg .cat + +.po.pox: + $(MAKE) $(GETTEXT_PACKAGE).pot + $(MSGMERGE) $< $(GETTEXT_PACKAGE).pot -o $*.pox + +.po.mo: + $(MSGFMT) -o $@ $< + +.po.gmo: + file=`echo $* | sed 's,.*/,,'`.gmo \ + && rm -f $$file && $(GMSGFMT) -o $$file $< + +.po.cat: + sed -f ../intl/po2msg.sed < $< > $*.msg \ + && rm -f $@ && gencat $@ $*.msg + + +all: all-@USE_NLS@ + +all-yes: $(CATALOGS) +all-no: + +$(GETTEXT_PACKAGE).pot: $(POTFILES) + $(GENPOT) + +install: install-data +install-data: install-data-@USE_NLS@ +install-data-no: all +install-data-yes: all + linguas="$(USE_LINGUAS)"; \ + for lang in $$linguas; do \ + dir=$(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $$dir; \ + if test -r $$lang.gmo; then \ + $(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ + echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \ + else \ + $(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \ + echo "installing $(srcdir)/$$lang.gmo as" \ + "$$dir/$(GETTEXT_PACKAGE).mo"; \ + fi; \ + if test -r $$lang.gmo.m; then \ + $(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \ + echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \ + else \ + if test -r $(srcdir)/$$lang.gmo.m ; then \ + $(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \ + $$dir/$(GETTEXT_PACKAGE).mo.m; \ + echo "installing $(srcdir)/$$lang.gmo.m as" \ + "$$dir/$(GETTEXT_PACKAGE).mo.m"; \ + else \ + true; \ + fi; \ + fi; \ + done + +# Empty stubs to satisfy archaic automake needs +dvi info ctags tags CTAGS TAGS ID: + +# Define this as empty until I found a useful application. +install-exec installcheck: + +uninstall: + linguas="$(USE_LINGUAS)"; \ + for lang in $$linguas; do \ + rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \ + rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \ + done + +check: all $(GETTEXT_PACKAGE).pot + rm -f missing notexist + srcdir=$(srcdir) $(INTLTOOL_UPDATE) -m + if [ -r missing -o -r notexist ]; then \ + exit 1; \ + fi + +mostlyclean: + rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp + rm -f .intltool-merge-cache + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES stamp-it + rm -f *.mo *.msg *.cat *.cat.m *.gmo + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f Makefile.in.in + +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: $(DISTFILES) + dists="$(DISTFILES)"; \ + extra_dists="$(EXTRA_DISTFILES)"; \ + for file in $$extra_dists; do \ + test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \ + done; \ + for file in $$dists; do \ + test -f $$file || file="$(srcdir)/$$file"; \ + ln $$file $(distdir) 2> /dev/null \ + || cp -p $$file $(distdir); \ + done + +update-po: Makefile + $(MAKE) $(GETTEXT_PACKAGE).pot + tmpdir=`pwd`; \ + linguas="$(USE_LINGUAS)"; \ + for lang in $$linguas; do \ + echo "$$lang:"; \ + result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \ + if $$result; then \ + if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "msgmerge for $$lang.gmo failed!"; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi; \ + done + +Makefile POTFILES: stamp-it + @if test ! -f $@; then \ + rm -f stamp-it; \ + $(MAKE) stamp-it; \ + fi + +stamp-it: Makefile.in.in $(top_builddir)/config.status POTFILES.in + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \ + $(SHELL) ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..ed2c308 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,4 @@ +src/hostname/org.freedesktop.hostname1.policy.in +src/locale/org.freedesktop.locale1.policy.in +src/login/org.freedesktop.login1.policy.in +src/timedate/org.freedesktop.timedate1.policy.in diff --git a/po/POTFILES.skip b/po/POTFILES.skip new file mode 100644 index 0000000..5a5d027 --- /dev/null +++ b/po/POTFILES.skip @@ -0,0 +1,19 @@ +src/dbus-automount.c +src/dbus-device.c +src/dbus-job.c +src/dbus-manager.c +src/dbus-mount.c +src/dbus-path.c +src/dbus-service.c +src/dbus-snapshot.c +src/dbus-socket.c +src/dbus-swap.c +src/dbus-target.c +src/dbus-timer.c +src/dbus-unit.c +src/hostname/hostnamed.c +src/locale/localed.c +src/org.freedesktop.systemd1.policy.in.in +src/timedate/timedated.c +units/systemd-readahead-done.service.in +units/user@.service.in diff --git a/src/99-systemd.rules.in b/src/99-systemd.rules.in new file mode 100644 index 0000000..d306f71 --- /dev/null +++ b/src/99-systemd.rules.in @@ -0,0 +1,55 @@ +# This file is part of systemd. +# +# systemd 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. + +ACTION=="remove", GOTO="systemd_end" + +SUBSYSTEM=="tty", KERNEL=="tty[0-9]|tty1[0-2]", TAG+="systemd" +SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*", TAG+="systemd" + +KERNEL=="vport*", TAG+="systemd" + +SUBSYSTEM=="block", KERNEL!="ram*|loop*", TAG+="systemd" +SUBSYSTEM=="block", KERNEL!="ram*|loop*", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", ENV{SYSTEMD_READY}="0" + +# Ignore encrypted devices with no identified superblock on it, since +# we are probably still calling mke2fs or mkswap on it. + +SUBSYSTEM=="block", KERNEL!="ram*|loop*", ENV{DM_UUID}=="CRYPT-*", ENV{ID_PART_TABLE_TYPE}=="", ENV{ID_FS_USAGE}=="", ENV{SYSTEMD_READY}="0" + +# We need a hardware independent way to identify network devices. We +# use the /sys/subsystem path for this. Current vanilla kernels don't +# actually support that hierarchy right now, however upcoming kernels +# will. HAL and udev internally support /sys/subsystem already, hence +# it should be safe to use this here, too. This is mostly just an +# identification string for systemd, so whether the path actually is +# accessible or not does not matter as long as it is unique and in the +# filesystem namespace. +# +# http://git.kernel.org/?p=linux/hotplug/udev.git;a=blob;f=libudev/libudev-enumerate.c;h=da831449dcaf5e936a14409e8e68ab12d30a98e2;hb=HEAD#l742 + +SUBSYSTEM=="net", KERNEL!="lo", TAG+="systemd", ENV{SYSTEMD_ALIAS}="/sys/subsystem/net/devices/$name" +SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_ALIAS}="/sys/subsystem/bluetooth/devices/%k" + +SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_WANTS}="bluetooth.target" +ENV{ID_SMARTCARD_READER}=="*?", TAG+="systemd", ENV{SYSTEMD_WANTS}="smartcard.target" +SUBSYSTEM=="sound", KERNEL=="card*", TAG+="systemd", ENV{SYSTEMD_WANTS}="sound.target" + +SUBSYSTEM=="printer", TAG+="systemd", ENV{SYSTEMD_WANTS}="printer.target" +SUBSYSTEM=="usb", KERNEL=="lp*", TAG+="systemd", ENV{SYSTEMD_WANTS}="printer.target" +SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:*", TAG+="systemd", ENV{SYSTEMD_WANTS}="printer.target" + +# Apply sysctl variables to network devices (and only to those) as they appear. + +SUBSYSTEM=="net", KERNEL!="lo", RUN+="@rootlibexecdir@/systemd-sysctl --prefix=/proc/sys/net/ipv4/conf/$name --prefix=/proc/sys/net/ipv4/neigh/$name --prefix=/proc/sys/net/ipv6/conf/$name --prefix=/proc/sys/net/ipv6/neigh/$name" + +# Asynchronously mount file systems implemented by these modules as +# soon as they are loaded. + +SUBSYSTEM=="module", KERNEL=="fuse", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}="sys-fs-fuse-connections.mount" +SUBSYSTEM=="module", KERNEL=="configfs", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}="sys-kernel-config.mount" + +LABEL="systemd_end" diff --git a/src/ac-power.c b/src/ac-power.c new file mode 100644 index 0000000..24a68e7 --- /dev/null +++ b/src/ac-power.c @@ -0,0 +1,111 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "util.h" + +static int on_ac_power(void) { + int r; + + struct udev *udev; + struct udev_enumerate *e = NULL; + struct udev_list_entry *item = NULL, *first = NULL; + bool found_offline = false, found_online = false; + + if (!(udev = udev_new())) { + r = -ENOMEM; + goto finish; + } + + if (!(e = udev_enumerate_new(udev))) { + r = -ENOMEM; + goto finish; + } + + if (udev_enumerate_add_match_subsystem(e, "power_supply") < 0) { + r = -EIO; + goto finish; + } + + if (udev_enumerate_scan_devices(e) < 0) { + r = -EIO; + goto finish; + } + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + struct udev_device *d; + const char *type, *online; + + if (!(d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)))) { + r = -ENOMEM; + goto finish; + } + + if (!(type = udev_device_get_sysattr_value(d, "type"))) + goto next; + + if (!streq(type, "Mains")) + goto next; + + if (!(online = udev_device_get_sysattr_value(d, "online"))) + goto next; + + if (streq(online, "1")) { + found_online = true; + break; + } else if (streq(online, "0")) + found_offline = true; + + next: + udev_device_unref(d); + } + + r = found_online || !found_offline; + +finish: + if (e) + udev_enumerate_unref(e); + + if (udev) + udev_unref(udev); + + return r; +} + +int main(int argc, char *argv[]) { + int r; + + /* This is mostly intended to be used for scripts which want + * to detect whether AC power is plugged in or not. */ + + if ((r = on_ac_power()) < 0) { + log_error("Failed to read AC status: %s", strerror(-r)); + return EXIT_FAILURE; + } + + return r == 0; +} diff --git a/src/acl-util.c b/src/acl-util.c new file mode 100644 index 0000000..a2a9f9a --- /dev/null +++ b/src/acl-util.c @@ -0,0 +1,68 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "acl-util.h" + +int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) { + acl_entry_t i; + int found; + + assert(acl); + assert(entry); + + for (found = acl_get_entry(acl, ACL_FIRST_ENTRY, &i); + found > 0; + found = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) { + + acl_tag_t tag; + uid_t *u; + bool b; + + if (acl_get_tag_type(i, &tag) < 0) + return -errno; + + if (tag != ACL_USER) + continue; + + u = acl_get_qualifier(i); + if (!u) + return -errno; + + b = *u == uid; + acl_free(u); + + if (b) { + *entry = i; + return 1; + } + } + + if (found < 0) + return -errno; + + return 0; +} diff --git a/src/acl-util.h b/src/acl-util.h new file mode 100644 index 0000000..798ce43 --- /dev/null +++ b/src/acl-util.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooaclutilhfoo +#define fooaclutilhfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry); + +#endif diff --git a/src/ask-password-api.c b/src/ask-password-api.c new file mode 100644 index 0000000..ce2f3cb --- /dev/null +++ b/src/ask-password-api.c @@ -0,0 +1,576 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "strv.h" + +#include "ask-password-api.h" + +static void backspace_chars(int ttyfd, size_t p) { + + if (ttyfd < 0) + return; + + while (p > 0) { + p--; + + loop_write(ttyfd, "\b \b", 3, false); + } +} + +int ask_password_tty( + const char *message, + usec_t until, + const char *flag_file, + char **_passphrase) { + + struct termios old_termios, new_termios; + char passphrase[LINE_MAX]; + size_t p = 0; + int r, ttyfd = -1, notify = -1; + struct pollfd pollfd[2]; + bool reset_tty = false; + bool silent_mode = false; + bool dirty = false; + enum { + POLL_TTY, + POLL_INOTIFY + }; + + assert(message); + assert(_passphrase); + + if (flag_file) { + if ((notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) { + r = -errno; + goto finish; + } + + if (inotify_add_watch(notify, flag_file, IN_ATTRIB /* for the link count */) < 0) { + r = -errno; + goto finish; + } + } + + if ((ttyfd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC)) >= 0) { + + if (tcgetattr(ttyfd, &old_termios) < 0) { + r = -errno; + goto finish; + } + + loop_write(ttyfd, ANSI_HIGHLIGHT_ON, sizeof(ANSI_HIGHLIGHT_ON)-1, false); + loop_write(ttyfd, message, strlen(message), false); + loop_write(ttyfd, " ", 1, false); + loop_write(ttyfd, ANSI_HIGHLIGHT_OFF, sizeof(ANSI_HIGHLIGHT_OFF)-1, false); + + new_termios = old_termios; + new_termios.c_lflag &= ~(ICANON|ECHO); + new_termios.c_cc[VMIN] = 1; + new_termios.c_cc[VTIME] = 0; + + if (tcsetattr(ttyfd, TCSADRAIN, &new_termios) < 0) { + r = -errno; + goto finish; + } + + reset_tty = true; + } + + zero(pollfd); + + pollfd[POLL_TTY].fd = ttyfd >= 0 ? ttyfd : STDIN_FILENO; + pollfd[POLL_TTY].events = POLLIN; + pollfd[POLL_INOTIFY].fd = notify; + pollfd[POLL_INOTIFY].events = POLLIN; + + for (;;) { + char c; + int sleep_for = -1, k; + ssize_t n; + + if (until > 0) { + usec_t y; + + y = now(CLOCK_MONOTONIC); + + if (y > until) { + r = -ETIME; + goto finish; + } + + sleep_for = (int) ((until - y) / USEC_PER_MSEC); + } + + if (flag_file) + if (access(flag_file, F_OK) < 0) { + r = -errno; + goto finish; + } + + if ((k = poll(pollfd, notify > 0 ? 2 : 1, sleep_for)) < 0) { + + if (errno == EINTR) + continue; + + r = -errno; + goto finish; + } else if (k == 0) { + r = -ETIME; + goto finish; + } + + if (notify > 0 && pollfd[POLL_INOTIFY].revents != 0) + flush_fd(notify); + + if (pollfd[POLL_TTY].revents == 0) + continue; + + if ((n = read(ttyfd >= 0 ? ttyfd : STDIN_FILENO, &c, 1)) < 0) { + + if (errno == EINTR || errno == EAGAIN) + continue; + + r = -errno; + goto finish; + + } else if (n == 0) + break; + + if (c == '\n') + break; + else if (c == 21) { /* C-u */ + + if (!silent_mode) + backspace_chars(ttyfd, p); + p = 0; + + } else if (c == '\b' || c == 127) { + + if (p > 0) { + + if (!silent_mode) + backspace_chars(ttyfd, 1); + + p--; + } else if (!dirty && !silent_mode) { + + silent_mode = true; + + /* There are two ways to enter silent + * mode. Either by pressing backspace + * as first key (and only as first key), + * or ... */ + if (ttyfd >= 0) + loop_write(ttyfd, "(no echo) ", 10, false); + + } else if (ttyfd >= 0) + loop_write(ttyfd, "\a", 1, false); + + } else if (c == '\t' && !silent_mode) { + + backspace_chars(ttyfd, p); + silent_mode = true; + + /* ... or by pressing TAB at any time. */ + + if (ttyfd >= 0) + loop_write(ttyfd, "(no echo) ", 10, false); + } else { + passphrase[p++] = c; + + if (!silent_mode && ttyfd >= 0) + loop_write(ttyfd, "*", 1, false); + + dirty = true; + } + } + + passphrase[p] = 0; + + if (!(*_passphrase = strdup(passphrase))) { + r = -ENOMEM; + goto finish; + } + + r = 0; + +finish: + if (notify >= 0) + close_nointr_nofail(notify); + + if (ttyfd >= 0) { + + if (reset_tty) { + loop_write(ttyfd, "\n", 1, false); + tcsetattr(ttyfd, TCSADRAIN, &old_termios); + } + + close_nointr_nofail(ttyfd); + } + + return r; +} + +static int create_socket(char **name) { + int fd; + union { + struct sockaddr sa; + struct sockaddr_un un; + } sa; + int one = 1, r; + char *c; + mode_t u; + + assert(name); + + if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) { + log_error("socket() failed: %m"); + return -errno; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + snprintf(sa.un.sun_path, sizeof(sa.un.sun_path)-1, "/run/systemd/ask-password/sck.%llu", random_ull()); + + u = umask(0177); + r = bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)); + umask(u); + + if (r < 0) { + r = -errno; + log_error("bind() failed: %m"); + goto fail; + } + + if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) { + r = -errno; + log_error("SO_PASSCRED failed: %m"); + goto fail; + } + + if (!(c = strdup(sa.un.sun_path))) { + r = -ENOMEM; + log_error("Out of memory"); + goto fail; + } + + *name = c; + return fd; + +fail: + close_nointr_nofail(fd); + + return r; +} + +int ask_password_agent( + const char *message, + const char *icon, + usec_t until, + bool accept_cached, + char ***_passphrases) { + + enum { + FD_SOCKET, + FD_SIGNAL, + _FD_MAX + }; + + char temp[] = "/run/systemd/ask-password/tmp.XXXXXX"; + char final[sizeof(temp)] = ""; + int fd = -1, r; + FILE *f = NULL; + char *socket_name = NULL; + int socket_fd = -1, signal_fd = -1; + sigset_t mask, oldmask; + struct pollfd pollfd[_FD_MAX]; + mode_t u; + + assert(_passphrases); + + assert_se(sigemptyset(&mask) == 0); + sigset_add_many(&mask, SIGINT, SIGTERM, -1); + assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0); + + mkdir_p("/run/systemd/ask-password", 0755); + + u = umask(0022); + fd = mkostemp(temp, O_CLOEXEC|O_CREAT|O_WRONLY); + umask(u); + + if (fd < 0) { + log_error("Failed to create password file: %m"); + r = -errno; + goto finish; + } + + fchmod(fd, 0644); + + if (!(f = fdopen(fd, "w"))) { + log_error("Failed to allocate FILE: %m"); + r = -errno; + goto finish; + } + + fd = -1; + + if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) { + log_error("signalfd(): %m"); + r = -errno; + goto finish; + } + + if ((socket_fd = create_socket(&socket_name)) < 0) { + r = socket_fd; + goto finish; + } + + fprintf(f, + "[Ask]\n" + "PID=%lu\n" + "Socket=%s\n" + "AcceptCached=%i\n" + "NotAfter=%llu\n", + (unsigned long) getpid(), + socket_name, + accept_cached ? 1 : 0, + (unsigned long long) until); + + if (message) + fprintf(f, "Message=%s\n", message); + + if (icon) + fprintf(f, "Icon=%s\n", icon); + + fflush(f); + + if (ferror(f)) { + log_error("Failed to write query file: %m"); + r = -errno; + goto finish; + } + + memcpy(final, temp, sizeof(temp)); + + final[sizeof(final)-11] = 'a'; + final[sizeof(final)-10] = 's'; + final[sizeof(final)-9] = 'k'; + + if (rename(temp, final) < 0) { + log_error("Failed to rename query file: %m"); + r = -errno; + goto finish; + } + + zero(pollfd); + pollfd[FD_SOCKET].fd = socket_fd; + pollfd[FD_SOCKET].events = POLLIN; + pollfd[FD_SIGNAL].fd = signal_fd; + pollfd[FD_SIGNAL].events = POLLIN; + + for (;;) { + char passphrase[LINE_MAX+1]; + struct msghdr msghdr; + struct iovec iovec; + struct ucred *ucred; + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; + } control; + ssize_t n; + int k; + usec_t t; + + t = now(CLOCK_MONOTONIC); + + if (until > 0 && until <= t) { + log_notice("Timed out"); + r = -ETIME; + goto finish; + } + + if ((k = poll(pollfd, _FD_MAX, until > 0 ? (int) ((until-t)/USEC_PER_MSEC) : -1)) < 0) { + + if (errno == EINTR) + continue; + + log_error("poll() failed: %m"); + r = -errno; + goto finish; + } + + if (k <= 0) { + log_notice("Timed out"); + r = -ETIME; + goto finish; + } + + if (pollfd[FD_SIGNAL].revents & POLLIN) { + r = -EINTR; + goto finish; + } + + if (pollfd[FD_SOCKET].revents != POLLIN) { + log_error("Unexpected poll() event."); + r = -EIO; + goto finish; + } + + zero(iovec); + iovec.iov_base = passphrase; + iovec.iov_len = sizeof(passphrase); + + zero(control); + zero(msghdr); + msghdr.msg_iov = &iovec; + msghdr.msg_iovlen = 1; + msghdr.msg_control = &control; + msghdr.msg_controllen = sizeof(control); + + if ((n = recvmsg(socket_fd, &msghdr, 0)) < 0) { + + if (errno == EAGAIN || + errno == EINTR) + continue; + + log_error("recvmsg() failed: %m"); + r = -errno; + goto finish; + } + + if (n <= 0) { + log_error("Message too short"); + continue; + } + + if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) || + control.cmsghdr.cmsg_level != SOL_SOCKET || + control.cmsghdr.cmsg_type != SCM_CREDENTIALS || + control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) { + log_warning("Received message without credentials. Ignoring."); + continue; + } + + ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr); + if (ucred->uid != 0) { + log_warning("Got request from unprivileged user. Ignoring."); + continue; + } + + if (passphrase[0] == '+') { + char **l; + + if (n == 1) + l = strv_new("", NULL); + else + l = strv_parse_nulstr(passphrase+1, n-1); + /* An empty message refers to the empty password */ + + if (!l) { + r = -ENOMEM; + goto finish; + } + + if (strv_length(l) <= 0) { + strv_free(l); + log_error("Invalid packet"); + continue; + } + + *_passphrases = l; + + } else if (passphrase[0] == '-') { + r = -ECANCELED; + goto finish; + } else { + log_error("Invalid packet"); + continue; + } + + break; + } + + r = 0; + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + if (socket_name) { + unlink(socket_name); + free(socket_name); + } + + if (socket_fd >= 0) + close_nointr_nofail(socket_fd); + + if (signal_fd >= 0) + close_nointr_nofail(signal_fd); + + if (f) + fclose(f); + + unlink(temp); + + if (final[0]) + unlink(final); + + assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) == 0); + + return r; +} + +int ask_password_auto(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases) { + assert(message); + assert(_passphrases); + + if (isatty(STDIN_FILENO)) { + int r; + char *s = NULL, **l = NULL; + + if ((r = ask_password_tty(message, until, NULL, &s)) < 0) + return r; + + l = strv_new(s, NULL); + free(s); + + if (!l) + return -ENOMEM; + + *_passphrases = l; + return r; + + } else + return ask_password_agent(message, icon, until, accept_cached, _passphrases); +} diff --git a/src/ask-password-api.h b/src/ask-password-api.h new file mode 100644 index 0000000..fec8625 --- /dev/null +++ b/src/ask-password-api.h @@ -0,0 +1,33 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooaskpasswordapihfoo +#define fooaskpasswordapihfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "util.h" + +int ask_password_tty(const char *message, usec_t until, const char *flag_file, char **_passphrase); + +int ask_password_agent(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases); + +int ask_password_auto(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases); + +#endif diff --git a/src/ask-password.c b/src/ask-password.c new file mode 100644 index 0000000..5162f62 --- /dev/null +++ b/src/ask-password.c @@ -0,0 +1,184 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "macro.h" +#include "util.h" +#include "strv.h" +#include "ask-password-api.h" +#include "def.h" + +static const char *arg_icon = NULL; +static const char *arg_message = NULL; +static bool arg_use_tty = true; +static usec_t arg_timeout = DEFAULT_TIMEOUT_USEC; +static bool arg_accept_cached = false; +static bool arg_multiple = false; + +static int help(void) { + + printf("%s [OPTIONS...] MESSAGE\n\n" + "Query the user for a system passphrase, via the TTY or an UI agent.\n\n" + " -h --help Show this help\n" + " --icon=NAME Icon name\n" + " --timeout=SEC Timeout in sec\n" + " --no-tty Ask question via agent even on TTY\n" + " --accept-cached Accept cached passwords\n" + " --multiple List multiple passwords if available\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_ICON = 0x100, + ARG_TIMEOUT, + ARG_NO_TTY, + ARG_ACCEPT_CACHED, + ARG_MULTIPLE + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "icon", required_argument, NULL, ARG_ICON }, + { "timeout", required_argument, NULL, ARG_TIMEOUT }, + { "no-tty", no_argument, NULL, ARG_NO_TTY }, + { "accept-cached", no_argument, NULL, ARG_ACCEPT_CACHED }, + { "multiple", no_argument, NULL, ARG_MULTIPLE }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_ICON: + arg_icon = optarg; + break; + + case ARG_TIMEOUT: + if (parse_usec(optarg, &arg_timeout) < 0) { + log_error("Failed to parse --timeout parameter %s", optarg); + return -EINVAL; + } + break; + + case ARG_NO_TTY: + arg_use_tty = false; + break; + + case ARG_ACCEPT_CACHED: + arg_accept_cached = true; + break; + + case ARG_MULTIPLE: + arg_multiple = true; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind != argc-1) { + help(); + return -EINVAL; + } + + arg_message = argv[optind]; + return 1; +} + +int main(int argc, char *argv[]) { + int r; + usec_t timeout; + + log_parse_environment(); + log_open(); + + if ((r = parse_argv(argc, argv)) <= 0) + goto finish; + + if (arg_timeout > 0) + timeout = now(CLOCK_MONOTONIC) + arg_timeout; + else + timeout = 0; + + if (arg_use_tty && isatty(STDIN_FILENO)) { + char *password = NULL; + + if ((r = ask_password_tty(arg_message, timeout, NULL, &password)) >= 0) { + puts(password); + free(password); + } + + } else { + char **l; + + if ((r = ask_password_agent(arg_message, arg_icon, timeout, arg_accept_cached, &l)) >= 0) { + char **p; + + STRV_FOREACH(p, l) { + puts(*p); + + if (!arg_multiple) + break; + } + + strv_free(l); + } + } + +finish: + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/automount.c b/src/automount.c new file mode 100644 index 0000000..cf2fb60 --- /dev/null +++ b/src/automount.c @@ -0,0 +1,887 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "unit.h" +#include "automount.h" +#include "load-fragment.h" +#include "load-dropin.h" +#include "unit-name.h" +#include "dbus-automount.h" +#include "bus-errors.h" +#include "special.h" +#include "label.h" + +static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = { + [AUTOMOUNT_DEAD] = UNIT_INACTIVE, + [AUTOMOUNT_WAITING] = UNIT_ACTIVE, + [AUTOMOUNT_RUNNING] = UNIT_ACTIVE, + [AUTOMOUNT_FAILED] = UNIT_FAILED +}; + +static int open_dev_autofs(Manager *m); + +static void automount_init(Unit *u) { + Automount *a = AUTOMOUNT(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + a->pipe_watch.fd = a->pipe_fd = -1; + a->pipe_watch.type = WATCH_INVALID; + + a->directory_mode = 0755; + + UNIT(a)->ignore_on_isolate = true; +} + +static void repeat_unmout(const char *path) { + assert(path); + + for (;;) { + /* If there are multiple mounts on a mount point, this + * removes them all */ + + if (umount2(path, MNT_DETACH) >= 0) + continue; + + if (errno != EINVAL) + log_error("Failed to unmount: %m"); + + break; + } +} + +static void unmount_autofs(Automount *a) { + assert(a); + + if (a->pipe_fd < 0) + return; + + automount_send_ready(a, -EHOSTDOWN); + + unit_unwatch_fd(UNIT(a), &a->pipe_watch); + close_nointr_nofail(a->pipe_fd); + a->pipe_fd = -1; + + /* If we reload/reexecute things we keep the mount point + * around */ + if (a->where && + (UNIT(a)->manager->exit_code != MANAGER_RELOAD && + UNIT(a)->manager->exit_code != MANAGER_REEXECUTE)) + repeat_unmout(a->where); +} + +static void automount_done(Unit *u) { + Automount *a = AUTOMOUNT(u); + + assert(a); + + unmount_autofs(a); + unit_ref_unset(&a->mount); + + free(a->where); + a->where = NULL; + + set_free(a->tokens); + a->tokens = NULL; +} + +int automount_add_one_mount_link(Automount *a, Mount *m) { + int r; + + assert(a); + assert(m); + + if (UNIT(a)->load_state != UNIT_LOADED || + UNIT(m)->load_state != UNIT_LOADED) + return 0; + + if (!path_startswith(a->where, m->where)) + return 0; + + if (path_equal(a->where, m->where)) + return 0; + + if ((r = unit_add_two_dependencies(UNIT(a), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0) + return r; + + return 0; +} + +static int automount_add_mount_links(Automount *a) { + Unit *other; + int r; + + assert(a); + + LIST_FOREACH(units_by_type, other, UNIT(a)->manager->units_by_type[UNIT_MOUNT]) + if ((r = automount_add_one_mount_link(a, MOUNT(other))) < 0) + return r; + + return 0; +} + +static int automount_add_default_dependencies(Automount *a) { + int r; + + assert(a); + + if (UNIT(a)->manager->running_as == MANAGER_SYSTEM) { + + if ((r = unit_add_dependency_by_name(UNIT(a), UNIT_BEFORE, SPECIAL_BASIC_TARGET, NULL, true)) < 0) + return r; + + if ((r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0) + return r; + } + + return 0; +} + +static int automount_verify(Automount *a) { + bool b; + char *e; + assert(a); + + if (UNIT(a)->load_state != UNIT_LOADED) + return 0; + + if (path_equal(a->where, "/")) { + log_error("Cannot have an automount unit for the root directory. Refusing."); + return -EINVAL; + } + + if (!(e = unit_name_from_path(a->where, ".automount"))) + return -ENOMEM; + + b = unit_has_name(UNIT(a), e); + free(e); + + if (!b) { + log_error("%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id); + return -EINVAL; + } + + return 0; +} + +static int automount_load(Unit *u) { + int r; + Automount *a = AUTOMOUNT(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + /* Load a .automount file */ + if ((r = unit_load_fragment_and_dropin_optional(u)) < 0) + return r; + + if (u->load_state == UNIT_LOADED) { + Unit *x; + + if (!a->where) + if (!(a->where = unit_name_to_path(u->id))) + return -ENOMEM; + + path_kill_slashes(a->where); + + if ((r = automount_add_mount_links(a)) < 0) + return r; + + r = unit_load_related_unit(u, ".mount", &x); + if (r < 0) + return r; + + unit_ref_set(&a->mount, x); + + r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(a->mount), true); + if (r < 0) + return r; + + if (UNIT(a)->default_dependencies) + if ((r = automount_add_default_dependencies(a)) < 0) + return r; + } + + return automount_verify(a); +} + +static void automount_set_state(Automount *a, AutomountState state) { + AutomountState old_state; + assert(a); + + old_state = a->state; + a->state = state; + + if (state != AUTOMOUNT_WAITING && + state != AUTOMOUNT_RUNNING) + unmount_autofs(a); + + if (state != old_state) + log_debug("%s changed %s -> %s", + UNIT(a)->id, + automount_state_to_string(old_state), + automount_state_to_string(state)); + + unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true); +} + +static int automount_coldplug(Unit *u) { + Automount *a = AUTOMOUNT(u); + int r; + + assert(a); + assert(a->state == AUTOMOUNT_DEAD); + + if (a->deserialized_state != a->state) { + + if ((r = open_dev_autofs(u->manager)) < 0) + return r; + + if (a->deserialized_state == AUTOMOUNT_WAITING || + a->deserialized_state == AUTOMOUNT_RUNNING) { + + assert(a->pipe_fd >= 0); + + if ((r = unit_watch_fd(UNIT(a), a->pipe_fd, EPOLLIN, &a->pipe_watch)) < 0) + return r; + } + + automount_set_state(a, a->deserialized_state); + } + + return 0; +} + +static void automount_dump(Unit *u, FILE *f, const char *prefix) { + Automount *a = AUTOMOUNT(u); + + assert(a); + + fprintf(f, + "%sAutomount State: %s\n" + "%sResult: %s\n" + "%sWhere: %s\n" + "%sDirectoryMode: %04o\n", + prefix, automount_state_to_string(a->state), + prefix, automount_result_to_string(a->result), + prefix, a->where, + prefix, a->directory_mode); +} + +static void automount_enter_dead(Automount *a, AutomountResult f) { + assert(a); + + if (f != AUTOMOUNT_SUCCESS) + a->result = f; + + automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD); +} + +static int open_dev_autofs(Manager *m) { + struct autofs_dev_ioctl param; + + assert(m); + + if (m->dev_autofs_fd >= 0) + return m->dev_autofs_fd; + + label_fix("/dev/autofs", false); + + if ((m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY)) < 0) { + log_error("Failed to open /dev/autofs: %s", strerror(errno)); + return -errno; + } + + init_autofs_dev_ioctl(¶m); + if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, ¶m) < 0) { + close_nointr_nofail(m->dev_autofs_fd); + m->dev_autofs_fd = -1; + return -errno; + } + + log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor); + + return m->dev_autofs_fd; +} + +static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) { + struct autofs_dev_ioctl *param; + size_t l; + int r; + + assert(dev_autofs_fd >= 0); + assert(where); + + l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1; + + if (!(param = malloc(l))) + return -ENOMEM; + + init_autofs_dev_ioctl(param); + param->size = l; + param->ioctlfd = -1; + param->openmount.devid = devid; + strcpy(param->path, where); + + if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0) { + r = -errno; + goto finish; + } + + if (param->ioctlfd < 0) { + r = -EIO; + goto finish; + } + + fd_cloexec(param->ioctlfd, true); + r = param->ioctlfd; + +finish: + free(param); + return r; +} + +static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) { + uint32_t major, minor; + struct autofs_dev_ioctl param; + + assert(dev_autofs_fd >= 0); + assert(ioctl_fd >= 0); + + init_autofs_dev_ioctl(¶m); + param.ioctlfd = ioctl_fd; + + if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, ¶m) < 0) + return -errno; + + major = param.protover.version; + + init_autofs_dev_ioctl(¶m); + param.ioctlfd = ioctl_fd; + + if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, ¶m) < 0) + return -errno; + + minor = param.protosubver.sub_version; + + log_debug("Autofs protocol version %i.%i", major, minor); + return 0; +} + +static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) { + struct autofs_dev_ioctl param; + + assert(dev_autofs_fd >= 0); + assert(ioctl_fd >= 0); + + init_autofs_dev_ioctl(¶m); + param.ioctlfd = ioctl_fd; + param.timeout.timeout = sec; + + if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) < 0) + return -errno; + + return 0; +} + +static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) { + struct autofs_dev_ioctl param; + + assert(dev_autofs_fd >= 0); + assert(ioctl_fd >= 0); + + init_autofs_dev_ioctl(¶m); + param.ioctlfd = ioctl_fd; + + if (status) { + param.fail.token = token; + param.fail.status = status; + } else + param.ready.token = token; + + if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, ¶m) < 0) + return -errno; + + return 0; +} + +int automount_send_ready(Automount *a, int status) { + int ioctl_fd, r; + unsigned token; + + assert(a); + assert(status <= 0); + + if (set_isempty(a->tokens)) + return 0; + + if ((ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id)) < 0) { + r = ioctl_fd; + goto fail; + } + + if (status) + log_debug("Sending failure: %s", strerror(-status)); + else + log_debug("Sending success."); + + r = 0; + + /* Autofs thankfully does not hand out 0 as a token */ + while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) { + int k; + + /* Autofs fun fact II: + * + * if you pass a positive status code here, the kernel will + * freeze! Yay! */ + + if ((k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd, + ioctl_fd, + token, + status)) < 0) + r = k; + } + +fail: + if (ioctl_fd >= 0) + close_nointr_nofail(ioctl_fd); + + return r; +} + +static void automount_enter_waiting(Automount *a) { + int p[2] = { -1, -1 }; + char name[32], options[128]; + bool mounted = false; + int r, ioctl_fd = -1, dev_autofs_fd; + struct stat st; + + assert(a); + assert(a->pipe_fd < 0); + assert(a->where); + + if (a->tokens) + set_clear(a->tokens); + + if ((dev_autofs_fd = open_dev_autofs(UNIT(a)->manager)) < 0) { + r = dev_autofs_fd; + goto fail; + } + + /* We knowingly ignore the results of this call */ + mkdir_p(a->where, 0555); + + if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) { + r = -errno; + goto fail; + } + + snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp()); + char_array_0(options); + + snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid()); + char_array_0(name); + + if (mount(name, a->where, "autofs", 0, options) < 0) { + r = -errno; + goto fail; + } + + mounted = true; + + close_nointr_nofail(p[1]); + p[1] = -1; + + if (stat(a->where, &st) < 0) { + r = -errno; + goto fail; + } + + if ((ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev)) < 0) { + r = ioctl_fd; + goto fail; + } + + if ((r = autofs_protocol(dev_autofs_fd, ioctl_fd)) < 0) + goto fail; + + if ((r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300)) < 0) + goto fail; + + /* Autofs fun fact: + * + * Unless we close the ioctl fd here, for some weird reason + * the direct mount will not receive events from the + * kernel. */ + + close_nointr_nofail(ioctl_fd); + ioctl_fd = -1; + + if ((r = unit_watch_fd(UNIT(a), p[0], EPOLLIN, &a->pipe_watch)) < 0) + goto fail; + + a->pipe_fd = p[0]; + a->dev_id = st.st_dev; + + automount_set_state(a, AUTOMOUNT_WAITING); + + return; + +fail: + assert_se(close_pipe(p) == 0); + + if (ioctl_fd >= 0) + close_nointr_nofail(ioctl_fd); + + if (mounted) + repeat_unmout(a->where); + + log_error("Failed to initialize automounter: %s", strerror(-r)); + automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES); +} + +static void automount_enter_runnning(Automount *a) { + int r; + struct stat st; + DBusError error; + + assert(a); + assert(UNIT_DEREF(a->mount)); + + dbus_error_init(&error); + + /* We don't take mount requests anymore if we are supposed to + * shut down anyway */ + if (unit_pending_inactive(UNIT(a))) { + log_debug("Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id); + automount_send_ready(a, -EHOSTDOWN); + return; + } + + mkdir_p(a->where, a->directory_mode); + + /* Before we do anything, let's see if somebody is playing games with us? */ + if (lstat(a->where, &st) < 0) { + log_warning("%s failed to stat automount point: %m", UNIT(a)->id); + goto fail; + } + + if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id) + log_info("%s's automount point already active?", UNIT(a)->id); + else if ((r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_DEREF(a->mount), JOB_REPLACE, true, &error, NULL)) < 0) { + log_warning("%s failed to queue mount startup job: %s", UNIT(a)->id, bus_error(&error, r)); + goto fail; + } + + automount_set_state(a, AUTOMOUNT_RUNNING); + return; + +fail: + automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES); + dbus_error_free(&error); +} + +static int automount_start(Unit *u) { + Automount *a = AUTOMOUNT(u); + + assert(a); + + assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED); + + if (path_is_mount_point(a->where, false)) { + log_error("Path %s is already a mount point, refusing start for %s", a->where, u->id); + return -EEXIST; + } + + if (UNIT_DEREF(a->mount)->load_state != UNIT_LOADED) + return -ENOENT; + + a->result = AUTOMOUNT_SUCCESS; + automount_enter_waiting(a); + return 0; +} + +static int automount_stop(Unit *u) { + Automount *a = AUTOMOUNT(u); + + assert(a); + + assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING); + + automount_enter_dead(a, AUTOMOUNT_SUCCESS); + return 0; +} + +static int automount_serialize(Unit *u, FILE *f, FDSet *fds) { + Automount *a = AUTOMOUNT(u); + void *p; + Iterator i; + + assert(a); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", automount_state_to_string(a->state)); + unit_serialize_item(u, f, "result", automount_result_to_string(a->result)); + unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id); + + SET_FOREACH(p, a->tokens, i) + unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p)); + + if (a->pipe_fd >= 0) { + int copy; + + if ((copy = fdset_put_dup(fds, a->pipe_fd)) < 0) + return copy; + + unit_serialize_item_format(u, f, "pipe-fd", "%i", copy); + } + + return 0; +} + +static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Automount *a = AUTOMOUNT(u); + int r; + + assert(a); + assert(fds); + + if (streq(key, "state")) { + AutomountState state; + + if ((state = automount_state_from_string(value)) < 0) + log_debug("Failed to parse state value %s", value); + else + a->deserialized_state = state; + } else if (streq(key, "result")) { + AutomountResult f; + + f = automount_result_from_string(value); + if (f < 0) + log_debug("Failed to parse result value %s", value); + else if (f != AUTOMOUNT_SUCCESS) + a->result = f; + + } else if (streq(key, "dev-id")) { + unsigned d; + + if (safe_atou(value, &d) < 0) + log_debug("Failed to parse dev-id value %s", value); + else + a->dev_id = (unsigned) d; + } else if (streq(key, "token")) { + unsigned token; + + if (safe_atou(value, &token) < 0) + log_debug("Failed to parse token value %s", value); + else { + if (!a->tokens) + if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + if ((r = set_put(a->tokens, UINT_TO_PTR(token))) < 0) + return r; + } + } else if (streq(key, "pipe-fd")) { + int fd; + + if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd)) + log_debug("Failed to parse pipe-fd value %s", value); + else { + if (a->pipe_fd >= 0) + close_nointr_nofail(a->pipe_fd); + + a->pipe_fd = fdset_remove(fds, fd); + } + } else + log_debug("Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState automount_active_state(Unit *u) { + assert(u); + + return state_translation_table[AUTOMOUNT(u)->state]; +} + +static const char *automount_sub_state_to_string(Unit *u) { + assert(u); + + return automount_state_to_string(AUTOMOUNT(u)->state); +} + +static bool automount_check_gc(Unit *u) { + Automount *a = AUTOMOUNT(u); + + assert(a); + + if (!UNIT_DEREF(a->mount)) + return false; + + return UNIT_VTABLE(UNIT_DEREF(a->mount))->check_gc(UNIT_DEREF(a->mount)); +} + +static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { + Automount *a = AUTOMOUNT(u); + union autofs_v5_packet_union packet; + ssize_t l; + int r; + + assert(a); + assert(fd == a->pipe_fd); + + if (events != EPOLLIN) { + log_error("Got invalid poll event on pipe."); + goto fail; + } + + if ((l = loop_read(a->pipe_fd, &packet, sizeof(packet), true)) != sizeof(packet)) { + log_error("Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read"); + goto fail; + } + + switch (packet.hdr.type) { + + case autofs_ptype_missing_direct: + + if (packet.v5_packet.pid > 0) { + char *p = NULL; + + get_process_comm(packet.v5_packet.pid, &p); + log_debug("Got direct mount request for %s, triggered by %lu (%s)", packet.v5_packet.name, (unsigned long) packet.v5_packet.pid, strna(p)); + free(p); + + } else + log_debug("Got direct mount request for %s", packet.v5_packet.name); + + if (!a->tokens) + if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func))) { + log_error("Failed to allocate token set."); + goto fail; + } + + if ((r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token))) < 0) { + log_error("Failed to remember token: %s", strerror(-r)); + goto fail; + } + + automount_enter_runnning(a); + break; + + default: + log_error("Received unknown automount request %i", packet.hdr.type); + break; + } + + return; + +fail: + automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES); +} + +static void automount_shutdown(Manager *m) { + assert(m); + + if (m->dev_autofs_fd >= 0) + close_nointr_nofail(m->dev_autofs_fd); +} + +static void automount_reset_failed(Unit *u) { + Automount *a = AUTOMOUNT(u); + + assert(a); + + if (a->state == AUTOMOUNT_FAILED) + automount_set_state(a, AUTOMOUNT_DEAD); + + a->result = AUTOMOUNT_SUCCESS; +} + +static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = { + [AUTOMOUNT_DEAD] = "dead", + [AUTOMOUNT_WAITING] = "waiting", + [AUTOMOUNT_RUNNING] = "running", + [AUTOMOUNT_FAILED] = "failed" +}; + +DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState); + +static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = { + [AUTOMOUNT_SUCCESS] = "success", + [AUTOMOUNT_FAILURE_RESOURCES] = "resources" +}; + +DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult); + +const UnitVTable automount_vtable = { + .suffix = ".automount", + .object_size = sizeof(Automount), + .sections = + "Unit\0" + "Automount\0" + "Install\0", + + .no_alias = true, + .no_instances = true, + + .init = automount_init, + .load = automount_load, + .done = automount_done, + + .coldplug = automount_coldplug, + + .dump = automount_dump, + + .start = automount_start, + .stop = automount_stop, + + .serialize = automount_serialize, + .deserialize_item = automount_deserialize_item, + + .active_state = automount_active_state, + .sub_state_to_string = automount_sub_state_to_string, + + .check_gc = automount_check_gc, + + .fd_event = automount_fd_event, + + .reset_failed = automount_reset_failed, + + .bus_interface = "org.freedesktop.systemd1.Automount", + .bus_message_handler = bus_automount_message_handler, + .bus_invalidating_properties = bus_automount_invalidating_properties, + + .shutdown = automount_shutdown +}; diff --git a/src/automount.h b/src/automount.h new file mode 100644 index 0000000..19baee2 --- /dev/null +++ b/src/automount.h @@ -0,0 +1,76 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooautomounthfoo +#define fooautomounthfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct Automount Automount; + +#include "unit.h" + +typedef enum AutomountState { + AUTOMOUNT_DEAD, + AUTOMOUNT_WAITING, + AUTOMOUNT_RUNNING, + AUTOMOUNT_FAILED, + _AUTOMOUNT_STATE_MAX, + _AUTOMOUNT_STATE_INVALID = -1 +} AutomountState; + +typedef enum AutomountResult { + AUTOMOUNT_SUCCESS, + AUTOMOUNT_FAILURE_RESOURCES, + _AUTOMOUNT_RESULT_MAX, + _AUTOMOUNT_RESULT_INVALID = -1 +} AutomountResult; + +struct Automount { + Unit meta; + + AutomountState state, deserialized_state; + + char *where; + + UnitRef mount; + + int pipe_fd; + mode_t directory_mode; + Watch pipe_watch; + dev_t dev_id; + + Set *tokens; + + AutomountResult result; +}; + +extern const UnitVTable automount_vtable; + +int automount_send_ready(Automount *a, int status); + +int automount_add_one_mount_link(Automount *a, Mount *m); + +const char* automount_state_to_string(AutomountState i); +AutomountState automount_state_from_string(const char *s); + +const char* automount_result_to_string(AutomountResult i); +AutomountResult automount_result_from_string(const char *s); + +#endif diff --git a/src/binfmt/binfmt.c b/src/binfmt/binfmt.c new file mode 100644 index 0000000..e8d6524 --- /dev/null +++ b/src/binfmt/binfmt.c @@ -0,0 +1,164 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "hashmap.h" +#include "strv.h" +#include "util.h" + +static int delete_rule(const char *rule) { + char *x, *fn = NULL, *e; + int r; + + assert(rule[0]); + + if (!(x = strdup(rule))) + return -ENOMEM; + + e = strchrnul(x+1, x[0]); + *e = 0; + + asprintf(&fn, "/proc/sys/fs/binfmt_misc/%s", x+1); + free(x); + + if (!fn) + return -ENOMEM; + + r = write_one_line_file(fn, "-1"); + free(fn); + + return r; +} + +static int apply_rule(const char *rule) { + int r; + + delete_rule(rule); + + if ((r = write_one_line_file("/proc/sys/fs/binfmt_misc/register", rule)) < 0) { + log_error("Failed to add binary format: %s", strerror(-r)); + return r; + } + + return 0; +} + +static int apply_file(const char *path, bool ignore_enoent) { + FILE *f; + int r = 0; + + assert(path); + + if (!(f = fopen(path, "re"))) { + if (ignore_enoent && errno == ENOENT) + return 0; + + log_error("Failed to open file '%s', ignoring: %m", path); + return -errno; + } + + log_debug("apply: %s\n", path); + while (!feof(f)) { + char l[LINE_MAX], *p; + int k; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + log_error("Failed to read file '%s', ignoring: %m", path); + r = -errno; + goto finish; + } + + p = strstrip(l); + + if (!*p) + continue; + + if (strchr(COMMENTS, *p)) + continue; + + if ((k = apply_rule(p)) < 0 && r == 0) + r = k; + } + +finish: + fclose(f); + + return r; +} + +int main(int argc, char *argv[]) { + int r = 0; + + if (argc > 2) { + log_error("This program expects one or no arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc > 1) { + r = apply_file(argv[1], false); + } else { + char **files, **f; + + /* Flush out all rules */ + write_one_line_file("/proc/sys/fs/binfmt_misc/status", "-1"); + + r = conf_files_list(&files, ".conf", + "/run/binfmt.d", + "/etc/binfmt.d", + "/usr/local/lib/binfmt.d", + "/usr/lib/binfmt.d", + NULL); + + if (r < 0) { + log_error("Failed to enumerate binfmt.d files: %s", strerror(-r)); + goto finish; + } + + STRV_FOREACH(f, files) { + int k; + + k = apply_file(*f, true); + if (k < 0 && r == 0) + r = k; + } + + strv_free(files); + } +finish: + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/bridge.c b/src/bridge.c new file mode 100644 index 0000000..1f7cf3a --- /dev/null +++ b/src/bridge.c @@ -0,0 +1,367 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "socket-util.h" + +#define BUFFER_SIZE (64*1024) +#define EXTRA_SIZE 16 + +static bool initial_nul = false; +static bool auth_over = false; + +static void format_uid(char *buf, size_t l) { + char text[20 + 1]; /* enough space for a 64bit integer plus NUL */ + unsigned j; + + assert(l > 0); + + snprintf(text, sizeof(text)-1, "%llu", (unsigned long long) geteuid()); + text[sizeof(text)-1] = 0; + + memset(buf, 0, l); + + for (j = 0; text[j] && j*2+2 < l; j++) { + buf[j*2] = hexchar(text[j] >> 4); + buf[j*2+1] = hexchar(text[j] & 0xF); + } + + buf[j*2] = 0; +} + +static size_t patch_in_line(char *line, size_t l, size_t left) { + size_t r; + + if (line[0] == 0 && !initial_nul) { + initial_nul = true; + line += 1; + l -= 1; + r = 1; + } else + r = 0; + + if (l == 5 && strncmp(line, "BEGIN", 5) == 0) { + r += l; + auth_over = true; + + } else if (l == 17 && strncmp(line, "NEGOTIATE_UNIX_FD", 17) == 0) { + memmove(line + 13, line + 17, left); + memcpy(line, "NEGOTIATE_NOP", 13); + r += 13; + + } else if (l >= 14 && strncmp(line, "AUTH EXTERNAL ", 14) == 0) { + char uid[20*2 + 1]; + size_t len; + + format_uid(uid, sizeof(uid)); + len = strlen(uid); + assert(len <= EXTRA_SIZE); + + memmove(line + 14 + len, line + l, left); + memcpy(line + 14, uid, len); + + r += 14 + len; + } else + r += l; + + return r; +} + +static size_t patch_in_buffer(char* in_buffer, size_t *in_buffer_full) { + size_t i, good = 0; + + if (*in_buffer_full <= 0) + return *in_buffer_full; + + /* If authentication is done, we don't touch anything anymore */ + if (auth_over) + return *in_buffer_full; + + if (*in_buffer_full < 2) + return 0; + + for (i = 0; i <= *in_buffer_full - 2; i ++) { + + /* Fully lines can be send on */ + if (in_buffer[i] == '\r' && in_buffer[i+1] == '\n') { + if (i > good) { + size_t old_length, new_length; + + old_length = i - good; + new_length = patch_in_line(in_buffer+good, old_length, *in_buffer_full - i); + *in_buffer_full = *in_buffer_full + new_length - old_length; + + good += new_length + 2; + + } else + good = i+2; + } + + if (auth_over) + break; + } + + return good; +} + +int main(int argc, char *argv[]) { + int r = EXIT_FAILURE, fd = -1, ep = -1; + union sockaddr_union sa; + char in_buffer[BUFFER_SIZE+EXTRA_SIZE], out_buffer[BUFFER_SIZE+EXTRA_SIZE]; + size_t in_buffer_full = 0, out_buffer_full = 0; + struct epoll_event stdin_ev, stdout_ev, fd_ev; + bool stdin_readable = false, stdout_writable = false, fd_readable = false, fd_writable = false; + bool stdin_rhup = false, stdout_whup = false, fd_rhup = false, fd_whup = false; + + if (argc > 1) { + log_error("This program takes no argument."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); + log_parse_environment(); + log_open(); + + if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) { + log_error("Failed to create socket: %s", strerror(errno)); + goto finish; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/run/dbus/system_bus_socket", sizeof(sa.un.sun_path)); + + if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) { + log_error("Failed to connect: %m"); + goto finish; + } + + fd_nonblock(STDIN_FILENO, 1); + fd_nonblock(STDOUT_FILENO, 1); + + if ((ep = epoll_create1(EPOLL_CLOEXEC)) < 0) { + log_error("Failed to create epoll: %m"); + goto finish; + } + + zero(stdin_ev); + stdin_ev.events = EPOLLIN|EPOLLET; + stdin_ev.data.fd = STDIN_FILENO; + + zero(stdout_ev); + stdout_ev.events = EPOLLOUT|EPOLLET; + stdout_ev.data.fd = STDOUT_FILENO; + + zero(fd_ev); + fd_ev.events = EPOLLIN|EPOLLOUT|EPOLLET; + fd_ev.data.fd = fd; + + if (epoll_ctl(ep, EPOLL_CTL_ADD, STDIN_FILENO, &stdin_ev) < 0 || + epoll_ctl(ep, EPOLL_CTL_ADD, STDOUT_FILENO, &stdout_ev) < 0 || + epoll_ctl(ep, EPOLL_CTL_ADD, fd, &fd_ev) < 0) { + log_error("Failed to regiser fds in epoll: %m"); + goto finish; + } + + do { + struct epoll_event ev[16]; + ssize_t k; + int i, nfds; + + if ((nfds = epoll_wait(ep, ev, ELEMENTSOF(ev), -1)) < 0) { + + if (errno == EINTR || errno == EAGAIN) + continue; + + log_error("epoll_wait(): %m"); + goto finish; + } + + assert(nfds >= 1); + + for (i = 0; i < nfds; i++) { + if (ev[i].data.fd == STDIN_FILENO) { + + if (!stdin_rhup && (ev[i].events & (EPOLLHUP|EPOLLIN))) + stdin_readable = true; + + } else if (ev[i].data.fd == STDOUT_FILENO) { + + if (ev[i].events & EPOLLHUP) { + stdout_writable = false; + stdout_whup = true; + } + + if (!stdout_whup && (ev[i].events & EPOLLOUT)) + stdout_writable = true; + + } else if (ev[i].data.fd == fd) { + + if (ev[i].events & EPOLLHUP) { + fd_writable = false; + fd_whup = true; + } + + if (!fd_rhup && (ev[i].events & (EPOLLHUP|EPOLLIN))) + fd_readable = true; + + if (!fd_whup && (ev[i].events & EPOLLOUT)) + fd_writable = true; + } + } + + while ((stdin_readable && in_buffer_full <= 0) || + (fd_writable && patch_in_buffer(in_buffer, &in_buffer_full) > 0) || + (fd_readable && out_buffer_full <= 0) || + (stdout_writable && out_buffer_full > 0)) { + + size_t in_buffer_good = 0; + + if (stdin_readable && in_buffer_full < BUFFER_SIZE) { + + if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, BUFFER_SIZE - in_buffer_full)) < 0) { + + if (errno == EAGAIN) + stdin_readable = false; + else if (errno == EPIPE || errno == ECONNRESET) + k = 0; + else { + log_error("read(): %m"); + goto finish; + } + } else + in_buffer_full += (size_t) k; + + if (k == 0) { + stdin_rhup = true; + stdin_readable = false; + shutdown(STDIN_FILENO, SHUT_RD); + close_nointr_nofail(STDIN_FILENO); + } + } + + in_buffer_good = patch_in_buffer(in_buffer, &in_buffer_full); + + if (fd_writable && in_buffer_good > 0) { + + if ((k = write(fd, in_buffer, in_buffer_good)) < 0) { + + if (errno == EAGAIN) + fd_writable = false; + else if (errno == EPIPE || errno == ECONNRESET) { + fd_whup = true; + fd_writable = false; + shutdown(fd, SHUT_WR); + } else { + log_error("write(): %m"); + goto finish; + } + + } else { + assert(in_buffer_full >= (size_t) k); + memmove(in_buffer, in_buffer + k, in_buffer_full - k); + in_buffer_full -= k; + } + } + + if (fd_readable && out_buffer_full < BUFFER_SIZE) { + + if ((k = read(fd, out_buffer + out_buffer_full, BUFFER_SIZE - out_buffer_full)) < 0) { + + if (errno == EAGAIN) + fd_readable = false; + else if (errno == EPIPE || errno == ECONNRESET) + k = 0; + else { + log_error("read(): %m"); + goto finish; + } + } else + out_buffer_full += (size_t) k; + + if (k == 0) { + fd_rhup = true; + fd_readable = false; + shutdown(fd, SHUT_RD); + } + } + + if (stdout_writable && out_buffer_full > 0) { + + if ((k = write(STDOUT_FILENO, out_buffer, out_buffer_full)) < 0) { + + if (errno == EAGAIN) + stdout_writable = false; + else if (errno == EPIPE || errno == ECONNRESET) { + stdout_whup = true; + stdout_writable = false; + shutdown(STDOUT_FILENO, SHUT_WR); + close_nointr(STDOUT_FILENO); + } else { + log_error("write(): %m"); + goto finish; + } + + } else { + assert(out_buffer_full >= (size_t) k); + memmove(out_buffer, out_buffer + k, out_buffer_full - k); + out_buffer_full -= k; + } + } + } + + if (stdin_rhup && in_buffer_full <= 0 && !fd_whup) { + fd_whup = true; + fd_writable = false; + shutdown(fd, SHUT_WR); + } + + if (fd_rhup && out_buffer_full <= 0 && !stdout_whup) { + stdout_whup = true; + stdout_writable = false; + shutdown(STDOUT_FILENO, SHUT_WR); + close_nointr(STDOUT_FILENO); + } + + } while (!stdout_whup || !fd_whup); + + r = EXIT_SUCCESS; + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + if (ep >= 0) + close_nointr_nofail(ep); + + return r; +} diff --git a/src/build.h b/src/build.h new file mode 100644 index 0000000..50cd79d --- /dev/null +++ b/src/build.h @@ -0,0 +1,63 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foobuildhfoo +#define foobuildhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#ifdef HAVE_PAM +#define _PAM_FEATURE_ "+PAM" +#else +#define _PAM_FEATURE_ "-PAM" +#endif + +#ifdef HAVE_LIBWRAP +#define _LIBWRAP_FEATURE_ "+LIBWRAP" +#else +#define _LIBWRAP_FEATURE_ "-LIBWRAP" +#endif + +#ifdef HAVE_AUDIT +#define _AUDIT_FEATURE_ "+AUDIT" +#else +#define _AUDIT_FEATURE_ "-AUDIT" +#endif + +#ifdef HAVE_SELINUX +#define _SELINUX_FEATURE_ "+SELINUX" +#else +#define _SELINUX_FEATURE_ "-SELINUX" +#endif + +#ifdef HAVE_SYSV_COMPAT +#define _SYSVINIT_FEATURE_ "+SYSVINIT" +#else +#define _SYSVINIT_FEATURE_ "-SYSVINIT" +#endif + +#ifdef HAVE_LIBCRYPTSETUP +#define _LIBCRYPTSETUP_FEATURE_ "+LIBCRYPTSETUP" +#else +#define _LIBCRYPTSETUP_FEATURE_ "-LIBCRYPTSETUP" +#endif + +#define SYSTEMD_FEATURES _PAM_FEATURE_ " " _LIBWRAP_FEATURE_ " " _AUDIT_FEATURE_ " " _SELINUX_FEATURE_ " " _SYSVINIT_FEATURE_ " " _LIBCRYPTSETUP_FEATURE_ + +#endif diff --git a/src/bus-errors.h b/src/bus-errors.h new file mode 100644 index 0000000..82d4e99 --- /dev/null +++ b/src/bus-errors.h @@ -0,0 +1,58 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foobuserrorshfoo +#define foobuserrorshfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#define BUS_ERROR_NO_SUCH_UNIT "org.freedesktop.systemd1.NoSuchUnit" +#define BUS_ERROR_NO_SUCH_JOB "org.freedesktop.systemd1.NoSuchJob" +#define BUS_ERROR_NOT_SUBSCRIBED "org.freedesktop.systemd1.NotSubscribed" +#define BUS_ERROR_INVALID_PATH "org.freedesktop.systemd1.InvalidPath" +#define BUS_ERROR_INVALID_NAME "org.freedesktop.systemd1.InvalidName" +#define BUS_ERROR_UNIT_TYPE_MISMATCH "org.freedesktop.systemd1.UnitTypeMismatch" +#define BUS_ERROR_UNIT_EXISTS "org.freedesktop.systemd1.UnitExists" +#define BUS_ERROR_NOT_SUPPORTED "org.freedesktop.systemd1.NotSupported" +#define BUS_ERROR_INVALID_JOB_MODE "org.freedesktop.systemd1.InvalidJobMode" +#define BUS_ERROR_ONLY_BY_DEPENDENCY "org.freedesktop.systemd1.OnlyByDependency" +#define BUS_ERROR_NO_ISOLATION "org.freedesktop.systemd1.NoIsolation" +#define BUS_ERROR_LOAD_FAILED "org.freedesktop.systemd1.LoadFailed" +#define BUS_ERROR_MASKED "org.freedesktop.systemd1.Masked" +#define BUS_ERROR_JOB_TYPE_NOT_APPLICABLE "org.freedesktop.systemd1.JobTypeNotApplicable" +#define BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE "org.freedesktop.systemd1.TransactionIsDestructive" +#define BUS_ERROR_TRANSACTION_JOBS_CONFLICTING "org.freedesktop.systemd1.TransactionJobsConflicting" +#define BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC "org.freedesktop.systemd1.TransactionOrderIsCyclic" +#define BUS_ERROR_SHUTTING_DOWN "org.freedesktop.systemd1.ShuttingDown" +#define BUS_ERROR_NO_SUCH_PROCESS "org.freedesktop.systemd1.NoSuchProcess" + +static inline const char *bus_error(const DBusError *e, int r) { + if (e && e->message) + return e->message; + + if (r >= 0) + return strerror(r); + + return strerror(-r); +} + +#endif diff --git a/src/cgls.c b/src/cgls.c new file mode 100644 index 0000000..d5417f9 --- /dev/null +++ b/src/cgls.c @@ -0,0 +1,164 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include + +#include "cgroup-show.h" +#include "cgroup-util.h" +#include "log.h" +#include "util.h" +#include "pager.h" + +static bool arg_no_pager = false; +static bool arg_kernel_threads = false; + +static void help(void) { + + printf("%s [OPTIONS...] [CGROUP...]\n\n" + "Recursively show control group contents.\n\n" + " -h --help Show this help\n" + " --no-pager Do not pipe output into a pager\n" + " -k Include kernel threads in output\n", + program_invocation_short_name); +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_NO_PAGER = 0x100 + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 1); + assert(argv); + + while ((c = getopt_long(argc, argv, "hk", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_NO_PAGER: + arg_no_pager = true; + break; + + case 'k': + arg_kernel_threads = true; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +int main(int argc, char *argv[]) { + int r = 0, retval = EXIT_FAILURE; + + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r < 0) + goto finish; + else if (r == 0) { + retval = EXIT_SUCCESS; + goto finish; + } + + if (!arg_no_pager) + pager_open(); + + if (optind < argc) { + unsigned i; + + for (i = (unsigned) optind; i < (unsigned) argc; i++) { + int q; + printf("%s:\n", argv[i]); + + q = show_cgroup_by_path(argv[i], NULL, 0, arg_kernel_threads); + if (q < 0) + r = q; + } + + } else { + char *p; + + p = get_current_dir_name(); + if (!p) { + log_error("Cannot determine current working directory: %m"); + goto finish; + } + + if (path_startswith(p, "/sys/fs/cgroup")) { + printf("Working Directory %s:\n", p); + r = show_cgroup_by_path(p, NULL, 0, arg_kernel_threads); + } else { + char *root = NULL; + const char *t = NULL; + + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &root); + if (r < 0) + t = "/"; + else { + if (endswith(root, "/system")) + root[strlen(root)-7] = 0; + + t = root[0] ? root : "/"; + } + + r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, t, NULL, 0, arg_kernel_threads); + free(root); + } + + free(p); + } + + if (r < 0) + log_error("Failed to list cgroup tree: %s", strerror(-r)); + + retval = EXIT_SUCCESS; + +finish: + pager_close(); + + return retval; +} diff --git a/src/cgroup-attr.c b/src/cgroup-attr.c new file mode 100644 index 0000000..474a686 --- /dev/null +++ b/src/cgroup-attr.c @@ -0,0 +1,102 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "cgroup-attr.h" +#include "cgroup-util.h" +#include "list.h" + +int cgroup_attribute_apply(CGroupAttribute *a, CGroupBonding *b) { + int r; + char *path = NULL; + char *v = NULL; + + assert(a); + + b = cgroup_bonding_find_list(b, a->controller); + if (!b) + return 0; + + if (a->map_callback) { + r = a->map_callback(a->controller, a->name, a->value, &v); + if (r < 0) + return r; + } + + r = cg_get_path(a->controller, b->path, a->name, &path); + if (r < 0) { + free(v); + return r; + } + + r = write_one_line_file(path, v ? v : a->value); + if (r < 0) + log_warning("Failed to write '%s' to %s: %s", v ? v : a->value, path, strerror(-r)); + + free(path); + free(v); + + return r; +} + +int cgroup_attribute_apply_list(CGroupAttribute *first, CGroupBonding *b) { + CGroupAttribute *a; + int r = 0; + + LIST_FOREACH(by_unit, a, first) { + int k; + + k = cgroup_attribute_apply(a, b); + if (r == 0) + r = k; + } + + return r; +} + +CGroupAttribute *cgroup_attribute_find_list(CGroupAttribute *first, const char *controller, const char *name) { + CGroupAttribute *a; + + assert(controller); + assert(name); + + LIST_FOREACH(by_unit, a, first) + if (streq(a->controller, controller) && + streq(a->name, name)) + return a; + + return NULL; +} + +static void cgroup_attribute_free(CGroupAttribute *a) { + assert(a); + + free(a->controller); + free(a->name); + free(a->value); + free(a); +} + +void cgroup_attribute_free_list(CGroupAttribute *first) { + CGroupAttribute *a, *n; + + LIST_FOREACH_SAFE(by_unit, a, n, first) + cgroup_attribute_free(a); +} diff --git a/src/cgroup-attr.h b/src/cgroup-attr.h new file mode 100644 index 0000000..63a73b8 --- /dev/null +++ b/src/cgroup-attr.h @@ -0,0 +1,49 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foocgroupattrhfoo +#define foocgroupattrhfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct CGroupAttribute CGroupAttribute; + +typedef int (*CGroupAttributeMapCallback)(const char *controller, const char*name, const char *value, char **ret); + +#include "unit.h" +#include "cgroup.h" + +struct CGroupAttribute { + char *controller; + char *name; + char *value; + + CGroupAttributeMapCallback map_callback; + + LIST_FIELDS(CGroupAttribute, by_unit); +}; + +int cgroup_attribute_apply(CGroupAttribute *a, CGroupBonding *b); +int cgroup_attribute_apply_list(CGroupAttribute *first, CGroupBonding *b); + +CGroupAttribute *cgroup_attribute_find_list(CGroupAttribute *first, const char *controller, const char *name); + +void cgroup_attribute_free_list(CGroupAttribute *first); + +#endif diff --git a/src/cgroup-show.c b/src/cgroup-show.c new file mode 100644 index 0000000..ee2a241 --- /dev/null +++ b/src/cgroup-show.c @@ -0,0 +1,261 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "macro.h" +#include "cgroup-util.h" +#include "cgroup-show.h" + +static int compare(const void *a, const void *b) { + const pid_t *p = a, *q = b; + + if (*p < *q) + return -1; + if (*p > *q) + return 1; + return 0; +} + +static unsigned ilog10(unsigned long ul) { + int n = 0; + + while (ul > 0) { + n++; + ul /= 10; + } + + return n; +} + +static int show_cgroup_one_by_path(const char *path, const char *prefix, unsigned n_columns, bool more, bool kernel_threads) { + char *fn; + FILE *f; + size_t n = 0, n_allocated = 0; + pid_t *pids = NULL; + char *p; + pid_t pid, biggest = 0; + int r; + + if (n_columns <= 0) + n_columns = columns(); + + if (!prefix) + prefix = ""; + + if ((r = cg_fix_path(path, &p)) < 0) + return r; + + r = asprintf(&fn, "%s/cgroup.procs", p); + free(p); + + if (r < 0) + return -ENOMEM; + + f = fopen(fn, "re"); + free(fn); + + if (!f) + return -errno; + + while ((r = cg_read_pid(f, &pid)) > 0) { + + if (!kernel_threads && is_kernel_thread(pid) > 0) + continue; + + if (n >= n_allocated) { + pid_t *npids; + + n_allocated = MAX(16U, n*2U); + + if (!(npids = realloc(pids, sizeof(pid_t) * n_allocated))) { + r = -ENOMEM; + goto finish; + } + + pids = npids; + } + + assert(n < n_allocated); + pids[n++] = pid; + + if (pid > biggest) + biggest = pid; + } + + if (r < 0) + goto finish; + + if (n > 0) { + unsigned i, m; + + /* Filter duplicates */ + m = 0; + for (i = 0; i < n; i++) { + unsigned j; + + for (j = i+1; j < n; j++) + if (pids[i] == pids[j]) + break; + + if (j >= n) + pids[m++] = pids[i]; + } + n = m; + + /* And sort */ + qsort(pids, n, sizeof(pid_t), compare); + + if (n_columns > 8) + n_columns -= 8; + else + n_columns = 20; + + for (i = 0; i < n; i++) { + char *t = NULL; + + get_process_cmdline(pids[i], n_columns, true, &t); + + printf("%s%s %*lu %s\n", + prefix, + (more || i < n-1) ? "\342\224\234" : "\342\224\224", + (int) ilog10(biggest), + (unsigned long) pids[i], + strna(t)); + + free(t); + } + } + + r = 0; + +finish: + free(pids); + + if (f) + fclose(f); + + return r; +} + +int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns, bool kernel_threads) { + DIR *d; + char *last = NULL; + char *p1 = NULL, *p2 = NULL, *fn = NULL, *gn = NULL; + bool shown_pids = false; + int r; + + if (n_columns <= 0) + n_columns = columns(); + + if (!prefix) + prefix = ""; + + if ((r = cg_fix_path(path, &fn)) < 0) + return r; + + if (!(d = opendir(fn))) { + free(fn); + return -errno; + } + + while ((r = cg_read_subgroup(d, &gn)) > 0) { + + if (!shown_pids) { + show_cgroup_one_by_path(path, prefix, n_columns, true, kernel_threads); + shown_pids = true; + } + + if (last) { + printf("%s\342\224\234 %s\n", prefix, file_name_from_path(last)); + + if (!p1) + if (!(p1 = strappend(prefix, "\342\224\202 "))) { + r = -ENOMEM; + goto finish; + } + + show_cgroup_by_path(last, p1, n_columns-2, kernel_threads); + + free(last); + last = NULL; + } + + r = asprintf(&last, "%s/%s", fn, gn); + free(gn); + + if (r < 0) { + r = -ENOMEM; + goto finish; + } + } + + if (r < 0) + goto finish; + + if (!shown_pids) + show_cgroup_one_by_path(path, prefix, n_columns, !!last, kernel_threads); + + if (last) { + printf("%s\342\224\224 %s\n", prefix, file_name_from_path(last)); + + if (!p2) + if (!(p2 = strappend(prefix, " "))) { + r = -ENOMEM; + goto finish; + } + + show_cgroup_by_path(last, p2, n_columns-2, kernel_threads); + } + + r = 0; + +finish: + free(p1); + free(p2); + free(last); + free(fn); + + closedir(d); + + return r; +} + +int show_cgroup(const char *controller, const char *path, const char *prefix, unsigned n_columns, bool kernel_threads) { + char *p; + int r; + + assert(controller); + assert(path); + + r = cg_get_path(controller, path, NULL, &p); + if (r < 0) + return r; + + r = show_cgroup_by_path(p, prefix, n_columns, kernel_threads); + free(p); + + return r; +} diff --git a/src/cgroup-show.h b/src/cgroup-show.h new file mode 100644 index 0000000..992e17b --- /dev/null +++ b/src/cgroup-show.h @@ -0,0 +1,30 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foocgroupshowhfoo +#define foocgroupshowhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +int show_cgroup_by_path(const char *path, const char *prefix, unsigned columns, bool kernel_threads); +int show_cgroup(const char *controller, const char *path, const char *prefix, unsigned columns, bool kernel_threads); + +#endif diff --git a/src/cgroup-util.c b/src/cgroup-util.c new file mode 100644 index 0000000..904d300 --- /dev/null +++ b/src/cgroup-util.c @@ -0,0 +1,1111 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cgroup-util.h" +#include "log.h" +#include "set.h" +#include "macro.h" +#include "util.h" + +int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) { + char *fs; + int r; + FILE *f; + + assert(controller); + assert(path); + assert(_f); + + if ((r = cg_get_path(controller, path, "cgroup.procs", &fs)) < 0) + return r; + + f = fopen(fs, "re"); + free(fs); + + if (!f) + return -errno; + + *_f = f; + return 0; +} + +int cg_enumerate_tasks(const char *controller, const char *path, FILE **_f) { + char *fs; + int r; + FILE *f; + + assert(controller); + assert(path); + assert(_f); + + if ((r = cg_get_path(controller, path, "tasks", &fs)) < 0) + return r; + + f = fopen(fs, "re"); + free(fs); + + if (!f) + return -errno; + + *_f = f; + return 0; +} + +int cg_read_pid(FILE *f, pid_t *_pid) { + unsigned long ul; + + /* Note that the cgroup.procs might contain duplicates! See + * cgroups.txt for details. */ + + errno = 0; + if (fscanf(f, "%lu", &ul) != 1) { + + if (feof(f)) + return 0; + + return errno ? -errno : -EIO; + } + + if (ul <= 0) + return -EIO; + + *_pid = (pid_t) ul; + return 1; +} + +int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d) { + char *fs; + int r; + DIR *d; + + assert(controller); + assert(path); + assert(_d); + + /* This is not recursive! */ + + if ((r = cg_get_path(controller, path, NULL, &fs)) < 0) + return r; + + d = opendir(fs); + free(fs); + + if (!d) + return -errno; + + *_d = d; + return 0; +} + +int cg_read_subgroup(DIR *d, char **fn) { + struct dirent *de; + + assert(d); + + errno = 0; + while ((de = readdir(d))) { + char *b; + + if (de->d_type != DT_DIR) + continue; + + if (streq(de->d_name, ".") || + streq(de->d_name, "..")) + continue; + + if (!(b = strdup(de->d_name))) + return -ENOMEM; + + *fn = b; + return 1; + } + + if (errno) + return -errno; + + return 0; +} + +int cg_rmdir(const char *controller, const char *path, bool honour_sticky) { + char *p; + int r; + + r = cg_get_path(controller, path, NULL, &p); + if (r < 0) + return r; + + if (honour_sticky) { + char *tasks; + + /* If the sticky bit is set don't remove the directory */ + + tasks = strappend(p, "/tasks"); + if (!tasks) { + free(p); + return -ENOMEM; + } + + r = file_is_priv_sticky(tasks); + free(tasks); + + if (r > 0) { + free(p); + return 0; + } + } + + r = rmdir(p); + free(p); + + return (r < 0 && errno != ENOENT) ? -errno : 0; +} + +int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s) { + bool done = false; + int r, ret = 0; + pid_t my_pid; + FILE *f = NULL; + Set *allocated_set = NULL; + + assert(controller); + assert(path); + assert(sig >= 0); + + /* This goes through the tasks list and kills them all. This + * is repeated until no further processes are added to the + * tasks list, to properly handle forking processes */ + + if (!s) + if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + my_pid = getpid(); + + do { + pid_t pid = 0; + done = true; + + if ((r = cg_enumerate_processes(controller, path, &f)) < 0) { + if (ret >= 0 && r != -ENOENT) + ret = r; + + goto finish; + } + + while ((r = cg_read_pid(f, &pid)) > 0) { + + if (pid == my_pid && ignore_self) + continue; + + if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid)) + continue; + + /* If we haven't killed this process yet, kill + * it */ + if (kill(pid, sig) < 0) { + if (ret >= 0 && errno != ESRCH) + ret = -errno; + } else if (ret == 0) { + + if (sigcont) + kill(pid, SIGCONT); + + ret = 1; + } + + done = false; + + if ((r = set_put(s, LONG_TO_PTR(pid))) < 0) { + if (ret >= 0) + ret = r; + + goto finish; + } + } + + if (r < 0) { + if (ret >= 0) + ret = r; + + goto finish; + } + + fclose(f); + f = NULL; + + /* To avoid racing against processes which fork + * quicker than we can kill them we repeat this until + * no new pids need to be killed. */ + + } while (!done); + +finish: + if (allocated_set) + set_free(allocated_set); + + if (f) + fclose(f); + + return ret; +} + +int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool rem, Set *s) { + int r, ret = 0; + DIR *d = NULL; + char *fn; + Set *allocated_set = NULL; + + assert(path); + assert(controller); + assert(sig >= 0); + + if (!s) + if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + ret = cg_kill(controller, path, sig, sigcont, ignore_self, s); + + if ((r = cg_enumerate_subgroups(controller, path, &d)) < 0) { + if (ret >= 0 && r != -ENOENT) + ret = r; + + goto finish; + } + + while ((r = cg_read_subgroup(d, &fn)) > 0) { + char *p = NULL; + + r = asprintf(&p, "%s/%s", path, fn); + free(fn); + + if (r < 0) { + if (ret >= 0) + ret = -ENOMEM; + + goto finish; + } + + r = cg_kill_recursive(controller, p, sig, sigcont, ignore_self, rem, s); + free(p); + + if (r != 0 && ret >= 0) + ret = r; + } + + if (r < 0 && ret >= 0) + ret = r; + + if (rem) + if ((r = cg_rmdir(controller, path, true)) < 0) { + if (ret >= 0 && + r != -ENOENT && + r != -EBUSY) + ret = r; + } + +finish: + if (d) + closedir(d); + + if (allocated_set) + set_free(allocated_set); + + return ret; +} + +int cg_kill_recursive_and_wait(const char *controller, const char *path, bool rem) { + unsigned i; + + assert(path); + assert(controller); + + /* This safely kills all processes; first it sends a SIGTERM, + * then checks 8 times after 200ms whether the group is now + * empty, then kills everything that is left with SIGKILL and + * finally checks 5 times after 200ms each whether the group + * is finally empty. */ + + for (i = 0; i < 15; i++) { + int sig, r; + + if (i <= 0) + sig = SIGTERM; + else if (i == 9) + sig = SIGKILL; + else + sig = 0; + + if ((r = cg_kill_recursive(controller, path, sig, true, true, rem, NULL)) <= 0) + return r; + + usleep(200 * USEC_PER_MSEC); + } + + return 0; +} + +int cg_migrate(const char *controller, const char *from, const char *to, bool ignore_self) { + bool done = false; + Set *s; + int r, ret = 0; + pid_t my_pid; + FILE *f = NULL; + + assert(controller); + assert(from); + assert(to); + + if (!(s = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + my_pid = getpid(); + + do { + pid_t pid = 0; + done = true; + + if ((r = cg_enumerate_tasks(controller, from, &f)) < 0) { + if (ret >= 0 && r != -ENOENT) + ret = r; + + goto finish; + } + + while ((r = cg_read_pid(f, &pid)) > 0) { + + /* This might do weird stuff if we aren't a + * single-threaded program. However, we + * luckily know we are not */ + if (pid == my_pid && ignore_self) + continue; + + if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid)) + continue; + + if ((r = cg_attach(controller, to, pid)) < 0) { + if (ret >= 0 && r != -ESRCH) + ret = r; + } else if (ret == 0) + ret = 1; + + done = false; + + if ((r = set_put(s, LONG_TO_PTR(pid))) < 0) { + if (ret >= 0) + ret = r; + + goto finish; + } + } + + if (r < 0) { + if (ret >= 0) + ret = r; + + goto finish; + } + + fclose(f); + f = NULL; + + } while (!done); + +finish: + set_free(s); + + if (f) + fclose(f); + + return ret; +} + +int cg_migrate_recursive(const char *controller, const char *from, const char *to, bool ignore_self, bool rem) { + int r, ret = 0; + DIR *d = NULL; + char *fn; + + assert(controller); + assert(from); + assert(to); + + ret = cg_migrate(controller, from, to, ignore_self); + + if ((r = cg_enumerate_subgroups(controller, from, &d)) < 0) { + if (ret >= 0 && r != -ENOENT) + ret = r; + goto finish; + } + + while ((r = cg_read_subgroup(d, &fn)) > 0) { + char *p = NULL; + + r = asprintf(&p, "%s/%s", from, fn); + free(fn); + + if (r < 0) { + if (ret >= 0) + ret = -ENOMEM; + + goto finish; + } + + r = cg_migrate_recursive(controller, p, to, ignore_self, rem); + free(p); + + if (r != 0 && ret >= 0) + ret = r; + } + + if (r < 0 && ret >= 0) + ret = r; + + if (rem) + if ((r = cg_rmdir(controller, from, true)) < 0) { + if (ret >= 0 && + r != -ENOENT && + r != -EBUSY) + ret = r; + } + +finish: + if (d) + closedir(d); + + return ret; +} + +int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) { + const char *p; + char *t; + static __thread bool good = false; + + assert(controller); + assert(fs); + + if (_unlikely_(!good)) { + int r; + + r = path_is_mount_point("/sys/fs/cgroup", false); + if (r <= 0) + return r < 0 ? r : -ENOENT; + + /* Cache this to save a few stat()s */ + good = true; + } + + if (isempty(controller)) + return -EINVAL; + + /* This is a very minimal lookup from controller names to + * paths. Since we have mounted most hierarchies ourselves + * should be kinda safe, but eventually we might want to + * extend this to have a fallback to actually check + * /proc/mounts. Might need caching then. */ + + if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) + p = "systemd"; + else if (startswith(controller, "name=")) + p = controller + 5; + else + p = controller; + + if (path && suffix) + t = join("/sys/fs/cgroup/", p, "/", path, "/", suffix, NULL); + else if (path) + t = join("/sys/fs/cgroup/", p, "/", path, NULL); + else if (suffix) + t = join("/sys/fs/cgroup/", p, "/", suffix, NULL); + else + t = join("/sys/fs/cgroup/", p, NULL); + + if (!t) + return -ENOMEM; + + path_kill_slashes(t); + + *fs = t; + return 0; +} + +static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { + char *p; + bool is_sticky; + + if (typeflag != FTW_DP) + return 0; + + if (ftwbuf->level < 1) + return 0; + + p = strappend(path, "/tasks"); + if (!p) { + errno = ENOMEM; + return 1; + } + + is_sticky = file_is_priv_sticky(p) > 0; + free(p); + + if (is_sticky) + return 0; + + rmdir(path); + return 0; +} + +int cg_trim(const char *controller, const char *path, bool delete_root) { + char *fs; + int r = 0; + + assert(controller); + assert(path); + + r = cg_get_path(controller, path, NULL, &fs); + if (r < 0) + return r; + + errno = 0; + if (nftw(fs, trim_cb, 64, FTW_DEPTH|FTW_MOUNT|FTW_PHYS) < 0) + r = errno ? -errno : -EIO; + + if (delete_root) { + bool is_sticky; + char *p; + + p = strappend(fs, "/tasks"); + if (!p) { + free(fs); + return -ENOMEM; + } + + is_sticky = file_is_priv_sticky(p) > 0; + free(p); + + if (!is_sticky) + if (rmdir(fs) < 0 && errno != ENOENT) { + if (r == 0) + r = -errno; + } + } + + free(fs); + + return r; +} + +int cg_delete(const char *controller, const char *path) { + char *parent; + int r; + + assert(controller); + assert(path); + + if ((r = parent_of_path(path, &parent)) < 0) + return r; + + r = cg_migrate_recursive(controller, path, parent, false, true); + free(parent); + + return r == -ENOENT ? 0 : r; +} + +int cg_create(const char *controller, const char *path) { + char *fs; + int r; + + assert(controller); + assert(path); + + if ((r = cg_get_path(controller, path, NULL, &fs)) < 0) + return r; + + r = mkdir_parents(fs, 0755); + + if (r >= 0) { + if (mkdir(fs, 0755) >= 0) + r = 1; + else if (errno == EEXIST) + r = 0; + else + r = -errno; + } + + free(fs); + + return r; +} + +int cg_attach(const char *controller, const char *path, pid_t pid) { + char *fs; + int r; + char c[32]; + + assert(controller); + assert(path); + assert(pid >= 0); + + if ((r = cg_get_path(controller, path, "tasks", &fs)) < 0) + return r; + + if (pid == 0) + pid = getpid(); + + snprintf(c, sizeof(c), "%lu\n", (unsigned long) pid); + char_array_0(c); + + r = write_one_line_file(fs, c); + free(fs); + + return r; +} + +int cg_create_and_attach(const char *controller, const char *path, pid_t pid) { + int r, q; + + assert(controller); + assert(path); + assert(pid >= 0); + + if ((r = cg_create(controller, path)) < 0) + return r; + + if ((q = cg_attach(controller, path, pid)) < 0) + return q; + + /* This does not remove the cgroup on failure */ + + return r; +} + +int cg_set_group_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid) { + char *fs; + int r; + + assert(controller); + assert(path); + + if (mode != (mode_t) -1) + mode &= 0777; + + r = cg_get_path(controller, path, NULL, &fs); + if (r < 0) + return r; + + r = chmod_and_chown(fs, mode, uid, gid); + free(fs); + + return r; +} + +int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid, int sticky) { + char *fs; + int r; + + assert(controller); + assert(path); + + if (mode == (mode_t) -1 && uid == (uid_t) -1 && gid == (gid_t) -1 && sticky < 0) + return 0; + + if (mode != (mode_t) -1) + mode &= 0666; + + r = cg_get_path(controller, path, "tasks", &fs); + if (r < 0) + return r; + + if (sticky >= 0 && mode != (mode_t) -1) + /* Both mode and sticky param are passed */ + mode |= (sticky ? S_ISVTX : 0); + else if ((sticky >= 0 && mode == (mode_t) -1) || + (mode != (mode_t) -1 && sticky < 0)) { + struct stat st; + + /* Only one param is passed, hence read the current + * mode from the file itself */ + + r = lstat(fs, &st); + if (r < 0) { + free(fs); + return -errno; + } + + if (mode == (mode_t) -1) + /* No mode set, we just shall set the sticky bit */ + mode = (st.st_mode & ~S_ISVTX) | (sticky ? S_ISVTX : 0); + else + /* Only mode set, leave sticky bit untouched */ + mode = (st.st_mode & ~0777) | mode; + } + + r = chmod_and_chown(fs, mode, uid, gid); + free(fs); + + return r; +} + +int cg_get_by_pid(const char *controller, pid_t pid, char **path) { + int r; + char *p = NULL; + FILE *f; + char *fs; + size_t cs; + + assert(controller); + assert(path); + assert(pid >= 0); + + if (pid == 0) + pid = getpid(); + + if (asprintf(&fs, "/proc/%lu/cgroup", (unsigned long) pid) < 0) + return -ENOMEM; + + f = fopen(fs, "re"); + free(fs); + + if (!f) + return errno == ENOENT ? -ESRCH : -errno; + + cs = strlen(controller); + + while (!feof(f)) { + char line[LINE_MAX]; + char *l; + + errno = 0; + if (!(fgets(line, sizeof(line), f))) { + if (feof(f)) + break; + + r = errno ? -errno : -EIO; + goto finish; + } + + truncate_nl(line); + + if (!(l = strchr(line, ':'))) + continue; + + l++; + if (strncmp(l, controller, cs) != 0) + continue; + + if (l[cs] != ':') + continue; + + if (!(p = strdup(l + cs + 1))) { + r = -ENOMEM; + goto finish; + } + + *path = p; + r = 0; + goto finish; + } + + r = -ENOENT; + +finish: + fclose(f); + + return r; +} + +int cg_install_release_agent(const char *controller, const char *agent) { + char *fs = NULL, *contents = NULL, *line = NULL, *sc; + int r; + + assert(controller); + assert(agent); + + if ((r = cg_get_path(controller, NULL, "release_agent", &fs)) < 0) + return r; + + if ((r = read_one_line_file(fs, &contents)) < 0) + goto finish; + + sc = strstrip(contents); + if (sc[0] == 0) { + + if (asprintf(&line, "%s\n", agent) < 0) { + r = -ENOMEM; + goto finish; + } + + if ((r = write_one_line_file(fs, line)) < 0) + goto finish; + + } else if (!streq(sc, agent)) { + r = -EEXIST; + goto finish; + } + + free(fs); + fs = NULL; + if ((r = cg_get_path(controller, NULL, "notify_on_release", &fs)) < 0) + goto finish; + + free(contents); + contents = NULL; + if ((r = read_one_line_file(fs, &contents)) < 0) + goto finish; + + sc = strstrip(contents); + + if (streq(sc, "0")) { + if ((r = write_one_line_file(fs, "1\n")) < 0) + goto finish; + + r = 1; + } else if (!streq(sc, "1")) { + r = -EIO; + goto finish; + } else + r = 0; + +finish: + free(fs); + free(contents); + free(line); + + return r; +} + +int cg_is_empty(const char *controller, const char *path, bool ignore_self) { + pid_t pid = 0; + int r; + FILE *f = NULL; + bool found = false; + + assert(controller); + assert(path); + + if ((r = cg_enumerate_tasks(controller, path, &f)) < 0) + return r == -ENOENT ? 1 : r; + + while ((r = cg_read_pid(f, &pid)) > 0) { + + if (ignore_self && pid == getpid()) + continue; + + found = true; + break; + } + + fclose(f); + + if (r < 0) + return r; + + return !found; +} + +int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self) { + int r; + DIR *d = NULL; + char *fn; + + assert(controller); + assert(path); + + if ((r = cg_is_empty(controller, path, ignore_self)) <= 0) + return r; + + if ((r = cg_enumerate_subgroups(controller, path, &d)) < 0) + return r == -ENOENT ? 1 : r; + + while ((r = cg_read_subgroup(d, &fn)) > 0) { + char *p = NULL; + + r = asprintf(&p, "%s/%s", path, fn); + free(fn); + + if (r < 0) { + r = -ENOMEM; + goto finish; + } + + r = cg_is_empty_recursive(controller, p, ignore_self); + free(p); + + if (r <= 0) + goto finish; + } + + if (r >= 0) + r = 1; + +finish: + + if (d) + closedir(d); + + return r; +} + +int cg_split_spec(const char *spec, char **controller, char **path) { + const char *e; + char *t = NULL, *u = NULL; + + assert(spec); + assert(controller || path); + + if (*spec == '/') { + + if (path) { + if (!(t = strdup(spec))) + return -ENOMEM; + + *path = t; + } + + if (controller) + *controller = NULL; + + return 0; + } + + if (!(e = strchr(spec, ':'))) { + + if (strchr(spec, '/') || spec[0] == 0) + return -EINVAL; + + if (controller) { + if (!(t = strdup(spec))) + return -ENOMEM; + + *controller = t; + } + + if (path) + *path = NULL; + + return 0; + } + + if (e[1] != '/' || + e == spec || + memchr(spec, '/', e-spec)) + return -EINVAL; + + if (controller) + if (!(t = strndup(spec, e-spec))) + return -ENOMEM; + + if (path) + if (!(u = strdup(e+1))) { + free(t); + return -ENOMEM; + } + + if (controller) + *controller = t; + + if (path) + *path = u; + + return 0; +} + +int cg_join_spec(const char *controller, const char *path, char **spec) { + assert(controller); + assert(path); + + if (!path_is_absolute(path) || + controller[0] == 0 || + strchr(controller, ':') || + strchr(controller, '/')) + return -EINVAL; + + if (asprintf(spec, "%s:%s", controller, path) < 0) + return -ENOMEM; + + return 0; +} + +int cg_fix_path(const char *path, char **result) { + char *t, *c, *p; + int r; + + assert(path); + assert(result); + + /* First check if it already is a filesystem path */ + if (path_is_absolute(path) && + path_startswith(path, "/sys/fs/cgroup") && + access(path, F_OK) >= 0) { + + if (!(t = strdup(path))) + return -ENOMEM; + + *result = t; + return 0; + } + + /* Otherwise treat it as cg spec */ + if ((r = cg_split_spec(path, &c, &p)) < 0) + return r; + + r = cg_get_path(c ? c : SYSTEMD_CGROUP_CONTROLLER, p ? p : "/", NULL, result); + free(c); + free(p); + + return r; +} + +int cg_get_user_path(char **path) { + char *root, *p; + + assert(path); + + /* Figure out the place to put user cgroups below. We use the + * same as PID 1 has but with the "/system" suffix replaced by + * "/user" */ + + if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &root) < 0) + p = strdup("/user"); + else { + if (endswith(root, "/system")) + root[strlen(root) - 7] = 0; + else if (streq(root, "/")) + root[0] = 0; + + p = strappend(root, "/user"); + free(root); + } + + if (!p) + return -ENOMEM; + + *path = p; + return 0; +} diff --git a/src/cgroup-util.h b/src/cgroup-util.h new file mode 100644 index 0000000..37e4255 --- /dev/null +++ b/src/cgroup-util.h @@ -0,0 +1,72 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foocgrouputilhfoo +#define foocgrouputilhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "set.h" +#include "def.h" + +int cg_enumerate_processes(const char *controller, const char *path, FILE **_f); +int cg_enumerate_tasks(const char *controller, const char *path, FILE **_f); +int cg_read_pid(FILE *f, pid_t *_pid); + +int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d); +int cg_read_subgroup(DIR *d, char **fn); + +int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s); +int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool remove, Set *s); +int cg_kill_recursive_and_wait(const char *controller, const char *path, bool remove); + +int cg_migrate(const char *controller, const char *from, const char *to, bool ignore_self); +int cg_migrate_recursive(const char *controller, const char *from, const char *to, bool ignore_self, bool remove); + +int cg_split_spec(const char *spec, char **controller, char **path); +int cg_join_spec(const char *controller, const char *path, char **spec); +int cg_fix_path(const char *path, char **result); + +int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs); +int cg_get_by_pid(const char *controller, pid_t pid, char **path); + +int cg_trim(const char *controller, const char *path, bool delete_root); + +int cg_rmdir(const char *controller, const char *path, bool honour_sticky); +int cg_delete(const char *controller, const char *path); + +int cg_create(const char *controller, const char *path); +int cg_attach(const char *controller, const char *path, pid_t pid); +int cg_create_and_attach(const char *controller, const char *path, pid_t pid); + +int cg_set_group_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid); +int cg_set_task_access(const char *controller, const char *path, mode_t mode, uid_t uid, gid_t gid, int sticky); + +int cg_install_release_agent(const char *controller, const char *agent); + +int cg_is_empty(const char *controller, const char *path, bool ignore_self); +int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_self); + +int cg_get_user_path(char **path); + +#endif diff --git a/src/cgroup.c b/src/cgroup.c new file mode 100644 index 0000000..1f6139e --- /dev/null +++ b/src/cgroup.c @@ -0,0 +1,556 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "cgroup.h" +#include "cgroup-util.h" +#include "log.h" + +int cgroup_bonding_realize(CGroupBonding *b) { + int r; + + assert(b); + assert(b->path); + assert(b->controller); + + r = cg_create(b->controller, b->path); + if (r < 0) { + log_warning("Failed to create cgroup %s:%s: %s", b->controller, b->path, strerror(-r)); + return r; + } + + b->realized = true; + + return 0; +} + +int cgroup_bonding_realize_list(CGroupBonding *first) { + CGroupBonding *b; + int r; + + LIST_FOREACH(by_unit, b, first) + if ((r = cgroup_bonding_realize(b)) < 0 && b->essential) + return r; + + return 0; +} + +void cgroup_bonding_free(CGroupBonding *b, bool trim) { + assert(b); + + if (b->unit) { + CGroupBonding *f; + + LIST_REMOVE(CGroupBonding, by_unit, b->unit->cgroup_bondings, b); + + if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) { + assert_se(f = hashmap_get(b->unit->manager->cgroup_bondings, b->path)); + LIST_REMOVE(CGroupBonding, by_path, f, b); + + if (f) + hashmap_replace(b->unit->manager->cgroup_bondings, b->path, f); + else + hashmap_remove(b->unit->manager->cgroup_bondings, b->path); + } + } + + if (b->realized && b->ours && trim) + cg_trim(b->controller, b->path, false); + + free(b->controller); + free(b->path); + free(b); +} + +void cgroup_bonding_free_list(CGroupBonding *first, bool remove_or_trim) { + CGroupBonding *b, *n; + + LIST_FOREACH_SAFE(by_unit, b, n, first) + cgroup_bonding_free(b, remove_or_trim); +} + +void cgroup_bonding_trim(CGroupBonding *b, bool delete_root) { + assert(b); + + if (b->realized && b->ours) + cg_trim(b->controller, b->path, delete_root); +} + +void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root) { + CGroupBonding *b; + + LIST_FOREACH(by_unit, b, first) + cgroup_bonding_trim(b, delete_root); +} + +int cgroup_bonding_install(CGroupBonding *b, pid_t pid) { + int r; + + assert(b); + assert(pid >= 0); + + if ((r = cg_create_and_attach(b->controller, b->path, pid)) < 0) + return r; + + b->realized = true; + return 0; +} + +int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid) { + CGroupBonding *b; + int r; + + LIST_FOREACH(by_unit, b, first) + if ((r = cgroup_bonding_install(b, pid)) < 0 && b->essential) + return r; + + return 0; +} + +int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid) { + assert(b); + + if (!b->realized) + return -EINVAL; + + return cg_set_group_access(b->controller, b->path, mode, uid, gid); +} + +int cgroup_bonding_set_group_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid) { + CGroupBonding *b; + int r; + + LIST_FOREACH(by_unit, b, first) { + r = cgroup_bonding_set_group_access(b, mode, uid, gid); + if (r < 0) + return r; + } + + return 0; +} + +int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky) { + assert(b); + + if (!b->realized) + return -EINVAL; + + return cg_set_task_access(b->controller, b->path, mode, uid, gid, sticky); +} + +int cgroup_bonding_set_task_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid, int sticky) { + CGroupBonding *b; + int r; + + LIST_FOREACH(by_unit, b, first) { + r = cgroup_bonding_set_task_access(b, mode, uid, gid, sticky); + if (r < 0) + return r; + } + + return 0; +} + +int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s) { + assert(b); + assert(sig >= 0); + + /* Don't kill cgroups that aren't ours */ + if (!b->ours) + return 0; + + return cg_kill_recursive(b->controller, b->path, sig, sigcont, true, false, s); +} + +int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s) { + CGroupBonding *b; + Set *allocated_set = NULL; + int ret = -EAGAIN, r; + + if (!first) + return 0; + + if (!s) + if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + LIST_FOREACH(by_unit, b, first) { + if ((r = cgroup_bonding_kill(b, sig, sigcont, s)) < 0) { + if (r == -EAGAIN || r == -ESRCH) + continue; + + ret = r; + goto finish; + } + + if (ret < 0 || r > 0) + ret = r; + } + +finish: + if (allocated_set) + set_free(allocated_set); + + return ret; +} + +/* Returns 1 if the group is empty, 0 if it is not, -EAGAIN if we + * cannot know */ +int cgroup_bonding_is_empty(CGroupBonding *b) { + int r; + + assert(b); + + if ((r = cg_is_empty_recursive(b->controller, b->path, true)) < 0) + return r; + + /* If it is empty it is empty */ + if (r > 0) + return 1; + + /* It's not only us using this cgroup, so we just don't know */ + return b->ours ? 0 : -EAGAIN; +} + +int cgroup_bonding_is_empty_list(CGroupBonding *first) { + CGroupBonding *b; + + LIST_FOREACH(by_unit, b, first) { + int r; + + if ((r = cgroup_bonding_is_empty(b)) < 0) { + /* If this returned -EAGAIN, then we don't know if the + * group is empty, so let's see if another group can + * tell us */ + + if (r != -EAGAIN) + return r; + } else + return r; + } + + return -EAGAIN; +} + +int manager_setup_cgroup(Manager *m) { + char *current = NULL, *path = NULL; + int r; + char suffix[32]; + + assert(m); + + /* 0. Be nice to Ingo Molnar #628004 */ + if (path_is_mount_point("/sys/fs/cgroup/systemd", false) <= 0) { + log_warning("No control group support available, not creating root group."); + return 0; + } + + /* 1. Determine hierarchy */ + if ((r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, ¤t)) < 0) { + log_error("Cannot determine cgroup we are running in: %s", strerror(-r)); + goto finish; + } + + if (m->running_as == MANAGER_SYSTEM) + strcpy(suffix, "/system"); + else { + snprintf(suffix, sizeof(suffix), "/systemd-%lu", (unsigned long) getpid()); + char_array_0(suffix); + } + + free(m->cgroup_hierarchy); + if (endswith(current, suffix)) { + /* We probably got reexecuted and can continue to use our root cgroup */ + m->cgroup_hierarchy = current; + current = NULL; + + } else { + /* We need a new root cgroup */ + m->cgroup_hierarchy = NULL; + if (asprintf(&m->cgroup_hierarchy, "%s%s", streq(current, "/") ? "" : current, suffix) < 0) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + } + + /* 2. Show data */ + if ((r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, NULL, &path)) < 0) { + log_error("Cannot find cgroup mount point: %s", strerror(-r)); + goto finish; + } + + log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER ". File system hierarchy is at %s.", path); + + /* 3. Install agent */ + if ((r = cg_install_release_agent(SYSTEMD_CGROUP_CONTROLLER, SYSTEMD_CGROUP_AGENT_PATH)) < 0) + log_warning("Failed to install release agent, ignoring: %s", strerror(-r)); + else if (r > 0) + log_debug("Installed release agent."); + else + log_debug("Release agent already installed."); + + /* 4. Realize the group */ + if ((r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy, 0)) < 0) { + log_error("Failed to create root cgroup hierarchy: %s", strerror(-r)); + goto finish; + } + + /* 5. And pin it, so that it cannot be unmounted */ + if (m->pin_cgroupfs_fd >= 0) + close_nointr_nofail(m->pin_cgroupfs_fd); + + if ((m->pin_cgroupfs_fd = open(path, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK)) < 0) { + log_error("Failed to open pin file: %m"); + r = -errno; + goto finish; + } + + log_debug("Created root group."); + +finish: + free(current); + free(path); + + return r; +} + +void manager_shutdown_cgroup(Manager *m, bool delete) { + assert(m); + + if (delete && m->cgroup_hierarchy) + cg_delete(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_hierarchy); + + if (m->pin_cgroupfs_fd >= 0) { + close_nointr_nofail(m->pin_cgroupfs_fd); + m->pin_cgroupfs_fd = -1; + } + + free(m->cgroup_hierarchy); + m->cgroup_hierarchy = NULL; +} + +int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding) { + CGroupBonding *b; + char *p; + + assert(m); + assert(cgroup); + assert(bonding); + + b = hashmap_get(m->cgroup_bondings, cgroup); + if (b) { + *bonding = b; + return 1; + } + + p = strdup(cgroup); + if (!p) + return -ENOMEM; + + for (;;) { + char *e; + + e = strrchr(p, '/'); + if (!e || e == p) { + free(p); + *bonding = NULL; + return 0; + } + + *e = 0; + + b = hashmap_get(m->cgroup_bondings, p); + if (b) { + free(p); + *bonding = b; + return 1; + } + } +} + +int cgroup_notify_empty(Manager *m, const char *group) { + CGroupBonding *l, *b; + int r; + + assert(m); + assert(group); + + r = cgroup_bonding_get(m, group, &l); + if (r <= 0) + return r; + + LIST_FOREACH(by_path, b, l) { + int t; + + if (!b->unit) + continue; + + t = cgroup_bonding_is_empty_list(b); + if (t < 0) { + + /* If we don't know, we don't know */ + if (t != -EAGAIN) + log_warning("Failed to check whether cgroup is empty: %s", strerror(errno)); + + continue; + } + + if (t > 0) { + /* If it is empty, let's delete it */ + cgroup_bonding_trim_list(b->unit->cgroup_bondings, true); + + if (UNIT_VTABLE(b->unit)->cgroup_notify_empty) + UNIT_VTABLE(b->unit)->cgroup_notify_empty(b->unit); + } + } + + return 0; +} + +Unit* cgroup_unit_by_pid(Manager *m, pid_t pid) { + CGroupBonding *l, *b; + char *group = NULL; + + assert(m); + + if (pid <= 1) + return NULL; + + if (cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &group) < 0) + return NULL; + + l = hashmap_get(m->cgroup_bondings, group); + + if (!l) { + char *slash; + + while ((slash = strrchr(group, '/'))) { + if (slash == group) + break; + + *slash = 0; + + if ((l = hashmap_get(m->cgroup_bondings, group))) + break; + } + } + + free(group); + + LIST_FOREACH(by_path, b, l) { + + if (!b->unit) + continue; + + if (b->ours) + return b->unit; + } + + return NULL; +} + +CGroupBonding *cgroup_bonding_find_list(CGroupBonding *first, const char *controller) { + CGroupBonding *b; + + assert(controller); + + LIST_FOREACH(by_unit, b, first) + if (streq(b->controller, controller)) + return b; + + return NULL; +} + +char *cgroup_bonding_to_string(CGroupBonding *b) { + char *r; + + assert(b); + + if (asprintf(&r, "%s:%s", b->controller, b->path) < 0) + return NULL; + + return r; +} + +pid_t cgroup_bonding_search_main_pid(CGroupBonding *b) { + FILE *f; + pid_t pid = 0, npid, mypid; + + assert(b); + + if (!b->ours) + return 0; + + if (cg_enumerate_processes(b->controller, b->path, &f) < 0) + return 0; + + mypid = getpid(); + + while (cg_read_pid(f, &npid) > 0) { + pid_t ppid; + + if (npid == pid) + continue; + + /* Ignore processes that aren't our kids */ + if (get_parent_of_pid(npid, &ppid) >= 0 && ppid != mypid) + continue; + + if (pid != 0) { + /* Dang, there's more than one daemonized PID + in this group, so we don't know what process + is the main process. */ + pid = 0; + break; + } + + pid = npid; + } + + fclose(f); + + return pid; +} + +pid_t cgroup_bonding_search_main_pid_list(CGroupBonding *first) { + CGroupBonding *b; + pid_t pid; + + /* Try to find a main pid from this cgroup, but checking if + * there's only one PID in the cgroup and returning it. Later + * on we might want to add additional, smarter heuristics + * here. */ + + LIST_FOREACH(by_unit, b, first) + if ((pid = cgroup_bonding_search_main_pid(b)) != 0) + return pid; + + return 0; + +} diff --git a/src/cgroup.h b/src/cgroup.h new file mode 100644 index 0000000..5faa7dc --- /dev/null +++ b/src/cgroup.h @@ -0,0 +1,94 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foocgrouphfoo +#define foocgrouphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct CGroupBonding CGroupBonding; + +#include "unit.h" + +/* Binds a cgroup to a name */ +struct CGroupBonding { + char *controller; + char *path; + + Unit *unit; + + /* For the Unit::cgroup_bondings list */ + LIST_FIELDS(CGroupBonding, by_unit); + + /* For the Manager::cgroup_bondings hashmap */ + LIST_FIELDS(CGroupBonding, by_path); + + /* When shutting down, remove cgroup? Are our own tasks the + * only ones in this group?*/ + bool ours:1; + + /* If we cannot create this group, or add a process to it, is this fatal? */ + bool essential:1; + + /* This cgroup is realized */ + bool realized:1; +}; + +int cgroup_bonding_realize(CGroupBonding *b); +int cgroup_bonding_realize_list(CGroupBonding *first); + +void cgroup_bonding_free(CGroupBonding *b, bool trim); +void cgroup_bonding_free_list(CGroupBonding *first, bool trim); + +int cgroup_bonding_install(CGroupBonding *b, pid_t pid); +int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid); + +int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); +int cgroup_bonding_set_group_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); + +int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky); +int cgroup_bonding_set_task_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky); + +int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s); +int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s); + +void cgroup_bonding_trim(CGroupBonding *first, bool delete_root); +void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root); + +int cgroup_bonding_is_empty(CGroupBonding *b); +int cgroup_bonding_is_empty_list(CGroupBonding *first); + +CGroupBonding *cgroup_bonding_find_list(CGroupBonding *first, const char *controller); + +char *cgroup_bonding_to_string(CGroupBonding *b); + +pid_t cgroup_bonding_search_main_pid(CGroupBonding *b); +pid_t cgroup_bonding_search_main_pid_list(CGroupBonding *b); + +#include "manager.h" + +int manager_setup_cgroup(Manager *m); +void manager_shutdown_cgroup(Manager *m, bool delete); + +int cgroup_bonding_get(Manager *m, const char *cgroup, CGroupBonding **bonding); +int cgroup_notify_empty(Manager *m, const char *group); + +Unit* cgroup_unit_by_pid(Manager *m, pid_t pid); + +#endif diff --git a/src/cgroups-agent.c b/src/cgroups-agent.c new file mode 100644 index 0000000..1bbc882 --- /dev/null +++ b/src/cgroups-agent.c @@ -0,0 +1,101 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include + +#include "log.h" +#include "dbus-common.h" + +int main(int argc, char *argv[]) { + DBusError error; + DBusConnection *bus = NULL; + DBusMessage *m = NULL; + int r = EXIT_FAILURE; + + dbus_error_init(&error); + + if (argc != 2) { + log_error("Incorrect number of arguments."); + goto finish; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + /* We send this event to the private D-Bus socket and then the + * system instance will forward this to the system bus. We do + * this to avoid an activation loop when we start dbus when we + * are called when the dbus service is shut down. */ + + if (!(bus = dbus_connection_open_private("unix:path=/run/systemd/private", &error))) { +#ifndef LEGACY + dbus_error_free(&error); + + /* Retry with the pre v21 socket name, to ease upgrades */ + if (!(bus = dbus_connection_open_private("unix:abstract=/org/freedesktop/systemd1/private", &error))) { +#endif + log_error("Failed to get D-Bus connection: %s", bus_error_message(&error)); + goto finish; + } +#ifndef LEGACY + } +#endif + + if (bus_check_peercred(bus) < 0) { + log_error("Bus owner not root."); + goto finish; + } + + if (!(m = dbus_message_new_signal("/org/freedesktop/systemd1/agent", "org.freedesktop.systemd1.Agent", "Released"))) { + log_error("Could not allocate signal message."); + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &argv[1], + DBUS_TYPE_INVALID)) { + log_error("Could not attach group information to signal message."); + goto finish; + } + + if (!dbus_connection_send(bus, m, NULL)) { + log_error("Failed to send signal message on private connection."); + goto finish; + } + + r = EXIT_SUCCESS; + +finish: + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + if (m) + dbus_message_unref(m); + + dbus_error_free(&error); + return r; +} diff --git a/src/cgtop.c b/src/cgtop.c new file mode 100644 index 0000000..8b8617d --- /dev/null +++ b/src/cgtop.c @@ -0,0 +1,729 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "hashmap.h" +#include "cgroup-util.h" + +typedef struct Group { + char *path; + + bool n_tasks_valid:1; + bool cpu_valid:1; + bool memory_valid:1; + bool io_valid:1; + + unsigned n_tasks; + + unsigned cpu_iteration; + uint64_t cpu_usage; + struct timespec cpu_timestamp; + double cpu_fraction; + + uint64_t memory; + + unsigned io_iteration; + uint64_t io_input, io_output; + struct timespec io_timestamp; + uint64_t io_input_bps, io_output_bps; +} Group; + +static unsigned arg_depth = 2; +static usec_t arg_delay = 1*USEC_PER_SEC; + +static enum { + ORDER_PATH, + ORDER_TASKS, + ORDER_CPU, + ORDER_MEMORY, + ORDER_IO +} arg_order = ORDER_CPU; + +static void group_free(Group *g) { + assert(g); + + free(g->path); + free(g); +} + +static void group_hashmap_clear(Hashmap *h) { + Group *g; + + while ((g = hashmap_steal_first(h))) + group_free(g); +} + +static void group_hashmap_free(Hashmap *h) { + group_hashmap_clear(h); + hashmap_free(h); +} + +static int process(const char *controller, const char *path, Hashmap *a, Hashmap *b, unsigned iteration) { + Group *g; + int r; + FILE *f; + pid_t pid; + unsigned n; + + assert(controller); + assert(path); + assert(a); + + g = hashmap_get(a, path); + if (!g) { + g = hashmap_get(b, path); + if (!g) { + g = new0(Group, 1); + if (!g) + return -ENOMEM; + + g->path = strdup(path); + if (!g->path) { + group_free(g); + return -ENOMEM; + } + + r = hashmap_put(a, g->path, g); + if (r < 0) { + group_free(g); + return r; + } + } else { + assert_se(hashmap_move_one(a, b, path) == 0); + g->cpu_valid = g->memory_valid = g->io_valid = g->n_tasks_valid = false; + } + } + + /* Regardless which controller, let's find the maximum number + * of processes in any of it */ + + r = cg_enumerate_tasks(controller, path, &f); + if (r < 0) + return r; + + n = 0; + while (cg_read_pid(f, &pid) > 0) + n++; + fclose(f); + + if (n > 0) { + if (g->n_tasks_valid) + g->n_tasks = MAX(g->n_tasks, n); + else + g->n_tasks = n; + + g->n_tasks_valid = true; + } + + if (streq(controller, "cpuacct")) { + uint64_t new_usage; + char *p, *v; + struct timespec ts; + + r = cg_get_path(controller, path, "cpuacct.usage", &p); + if (r < 0) + return r; + + r = read_one_line_file(p, &v); + free(p); + if (r < 0) + return r; + + r = safe_atou64(v, &new_usage); + free(v); + if (r < 0) + return r; + + assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0); + + if (g->cpu_iteration == iteration - 1) { + uint64_t x, y; + + x = ((uint64_t) ts.tv_sec * 1000000000ULL + (uint64_t) ts.tv_nsec) - + ((uint64_t) g->cpu_timestamp.tv_sec * 1000000000ULL + (uint64_t) g->cpu_timestamp.tv_nsec); + + y = new_usage - g->cpu_usage; + + if (y > 0) { + g->cpu_fraction = (double) y / (double) x; + g->cpu_valid = true; + } + } + + g->cpu_usage = new_usage; + g->cpu_timestamp = ts; + g->cpu_iteration = iteration; + + } else if (streq(controller, "memory")) { + char *p, *v; + + r = cg_get_path(controller, path, "memory.usage_in_bytes", &p); + if (r < 0) + return r; + + r = read_one_line_file(p, &v); + free(p); + if (r < 0) + return r; + + r = safe_atou64(v, &g->memory); + free(v); + if (r < 0) + return r; + + if (g->memory > 0) + g->memory_valid = true; + + } else if (streq(controller, "blkio")) { + char *p; + uint64_t wr = 0, rd = 0; + struct timespec ts; + + r = cg_get_path(controller, path, "blkio.io_service_bytes", &p); + if (r < 0) + return r; + + f = fopen(p, "re"); + free(p); + + if (!f) + return -errno; + + for (;;) { + char line[LINE_MAX], *l; + uint64_t k, *q; + + if (!fgets(line, sizeof(line), f)) + break; + + l = strstrip(line); + l += strcspn(l, WHITESPACE); + l += strspn(l, WHITESPACE); + + if (first_word(l, "Read")) { + l += 4; + q = &rd; + } else if (first_word(l, "Write")) { + l += 5; + q = ≀ + } else + continue; + + l += strspn(l, WHITESPACE); + r = safe_atou64(l, &k); + if (r < 0) + continue; + + *q += k; + } + + fclose(f); + + assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0); + + if (g->io_iteration == iteration - 1) { + uint64_t x, yr, yw; + + x = ((uint64_t) ts.tv_sec * 1000000000ULL + (uint64_t) ts.tv_nsec) - + ((uint64_t) g->io_timestamp.tv_sec * 1000000000ULL + (uint64_t) g->io_timestamp.tv_nsec); + + yr = rd - g->io_input; + yw = wr - g->io_output; + + if (yr > 0 || yw > 0) { + g->io_input_bps = (yr * 1000000000ULL) / x; + g->io_output_bps = (yw * 1000000000ULL) / x; + g->io_valid = true; + + } + } + + g->io_input = rd; + g->io_output = wr; + g->io_timestamp = ts; + g->io_iteration = iteration; + } + + return 0; +} + +static int refresh_one( + const char *controller, + const char *path, + Hashmap *a, + Hashmap *b, + unsigned iteration, + unsigned depth) { + + DIR *d = NULL; + int r; + + assert(controller); + assert(path); + assert(a); + + if (depth > arg_depth) + return 0; + + r = process(controller, path, a, b, iteration); + if (r < 0) + return r; + + r = cg_enumerate_subgroups(controller, path, &d); + if (r < 0) { + if (r == ENOENT) + return 0; + + return r; + } + + for (;;) { + char *fn, *p; + + r = cg_read_subgroup(d, &fn); + if (r <= 0) + goto finish; + + p = join(path, "/", fn, NULL); + free(fn); + + if (!p) { + r = -ENOMEM; + goto finish; + } + + path_kill_slashes(p); + + r = refresh_one(controller, p, a, b, iteration, depth + 1); + free(p); + + if (r < 0) + goto finish; + } + +finish: + if (d) + closedir(d); + + return r; +} + +static int refresh(Hashmap *a, Hashmap *b, unsigned iteration) { + int r; + + assert(a); + + r = refresh_one("name=systemd", "/", a, b, iteration, 0); + if (r < 0) + return r; + + r = refresh_one("cpuacct", "/", a, b, iteration, 0); + if (r < 0) + return r; + + r = refresh_one("memory", "/", a, b, iteration, 0); + if (r < 0) + return r; + + return refresh_one("blkio", "/", a, b, iteration, 0); +} + +static int group_compare(const void*a, const void *b) { + const Group *x = *(Group**)a, *y = *(Group**)b; + + if (path_startswith(y->path, x->path)) + return -1; + if (path_startswith(x->path, y->path)) + return 1; + + if (arg_order == ORDER_CPU) { + if (x->cpu_valid && y->cpu_valid) { + + if (x->cpu_fraction > y->cpu_fraction) + return -1; + else if (x->cpu_fraction < y->cpu_fraction) + return 1; + } else if (x->cpu_valid) + return -1; + else if (y->cpu_valid) + return 1; + } + + if (arg_order == ORDER_TASKS) { + + if (x->n_tasks_valid && y->n_tasks_valid) { + if (x->n_tasks > y->n_tasks) + return -1; + else if (x->n_tasks < y->n_tasks) + return 1; + } else if (x->n_tasks_valid) + return -1; + else if (y->n_tasks_valid) + return 1; + } + + if (arg_order == ORDER_MEMORY) { + if (x->memory_valid && y->memory_valid) { + if (x->memory > y->memory) + return -1; + else if (x->memory < y->memory) + return 1; + } else if (x->memory_valid) + return -1; + else if (y->memory_valid) + return 1; + } + + if (arg_order == ORDER_IO) { + if (x->io_valid && y->io_valid) { + if (x->io_input_bps + x->io_output_bps > y->io_input_bps + y->io_output_bps) + return -1; + else if (x->io_input_bps + x->io_output_bps < y->io_input_bps + y->io_output_bps) + return 1; + } else if (x->io_valid) + return -1; + else if (y->io_valid) + return 1; + } + + return strcmp(x->path, y->path); +} + +static int display(Hashmap *a) { + Iterator i; + Group *g; + Group **array; + unsigned rows, n = 0, j; + + assert(a); + + /* Set cursor to top left corner and clear screen */ + fputs("\033[H" + "\033[2J", stdout); + + array = alloca(sizeof(Group*) * hashmap_size(a)); + + HASHMAP_FOREACH(g, a, i) + if (g->n_tasks_valid || g->cpu_valid || g->memory_valid || g->io_valid) + array[n++] = g; + + qsort(array, n, sizeof(Group*), group_compare); + + rows = fd_lines(STDOUT_FILENO); + if (rows <= 0) + rows = 25; + + printf("%s%-37s%s %s%7s%s %s%6s%s %s%8s%s %s%8s%s %s%8s%s\n\n", + arg_order == ORDER_PATH ? ANSI_HIGHLIGHT_ON : "", "Path", arg_order == ORDER_PATH ? ANSI_HIGHLIGHT_OFF : "", + arg_order == ORDER_TASKS ? ANSI_HIGHLIGHT_ON : "", "Tasks", arg_order == ORDER_TASKS ? ANSI_HIGHLIGHT_OFF : "", + arg_order == ORDER_CPU ? ANSI_HIGHLIGHT_ON : "", "%CPU", arg_order == ORDER_CPU ? ANSI_HIGHLIGHT_OFF : "", + arg_order == ORDER_MEMORY ? ANSI_HIGHLIGHT_ON : "", "Memory", arg_order == ORDER_MEMORY ? ANSI_HIGHLIGHT_OFF : "", + arg_order == ORDER_IO ? ANSI_HIGHLIGHT_ON : "", "Input/s", arg_order == ORDER_IO ? ANSI_HIGHLIGHT_OFF : "", + arg_order == ORDER_IO ? ANSI_HIGHLIGHT_ON : "", "Output/s", arg_order == ORDER_IO ? ANSI_HIGHLIGHT_OFF : ""); + + for (j = 0; j < n; j++) { + char *p; + char m[FORMAT_BYTES_MAX]; + + if (j + 5 > rows) + break; + + g = array[j]; + + p = ellipsize(g->path, 37, 33); + printf("%-37s", p ? p : g->path); + free(p); + + if (g->n_tasks_valid) + printf(" %7u", g->n_tasks); + else + fputs(" -", stdout); + + if (g->cpu_valid) + printf(" %6.1f", g->cpu_fraction*100); + else + fputs(" -", stdout); + + if (g->memory_valid) + printf(" %8s", format_bytes(m, sizeof(m), g->memory)); + else + fputs(" -", stdout); + + if (g->io_valid) { + printf(" %8s", + format_bytes(m, sizeof(m), g->io_input_bps)); + printf(" %8s", + format_bytes(m, sizeof(m), g->io_output_bps)); + } else + fputs(" - -", stdout); + + putchar('\n'); + } + + return 0; +} + +static void help(void) { + + printf("%s [OPTIONS...]\n\n" + "Show top control groups by their resource usage.\n\n" + " -h --help Show this help\n" + " -p Order by path\n" + " -t Order by number of tasks\n" + " -c Order by CPU load\n" + " -m Order by memory load\n" + " -i Order by IO load\n" + " -d --delay=DELAY Specify delay\n" + " --depth=DEPTH Maximum traversal depth (default: 2)\n", + program_invocation_short_name); +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_DEPTH = 0x100 + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "delay", required_argument, NULL, 'd' }, + { "depth", required_argument, NULL, ARG_DEPTH }, + { NULL, 0, NULL, 0 } + }; + + int c; + int r; + + assert(argc >= 1); + assert(argv); + + while ((c = getopt_long(argc, argv, "hptcmid:", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_DEPTH: + r = safe_atou(optarg, &arg_depth); + if (r < 0) { + log_error("Failed to parse depth parameter."); + return -EINVAL; + } + + break; + + case 'd': + r = parse_usec(optarg, &arg_delay); + if (r < 0 || arg_delay <= 0) { + log_error("Failed to parse delay parameter."); + return -EINVAL; + } + + break; + + case 'p': + arg_order = ORDER_PATH; + break; + + case 't': + arg_order = ORDER_TASKS; + break; + + case 'c': + arg_order = ORDER_CPU; + break; + + case 'm': + arg_order = ORDER_MEMORY; + break; + + case 'i': + arg_order = ORDER_IO; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind < argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + return 1; +} + +int main(int argc, char *argv[]) { + int r; + Hashmap *a = NULL, *b = NULL; + unsigned iteration = 0; + usec_t last_refresh = 0; + bool quit = false, immediate_refresh = false; + + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r <= 0) + goto finish; + + a = hashmap_new(string_hash_func, string_compare_func); + b = hashmap_new(string_hash_func, string_compare_func); + if (!a || !b) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + while (!quit) { + Hashmap *c; + usec_t t; + char key; + char h[FORMAT_TIMESPAN_MAX]; + + t = now(CLOCK_MONOTONIC); + + if (t >= last_refresh + arg_delay || immediate_refresh) { + + r = refresh(a, b, iteration++); + if (r < 0) + goto finish; + + group_hashmap_clear(b); + + c = a; + a = b; + b = c; + + last_refresh = t; + immediate_refresh = false; + } + + r = display(b); + if (r < 0) + goto finish; + + r = read_one_char(stdin, &key, last_refresh + arg_delay - t, NULL); + if (r == -ETIMEDOUT) + continue; + if (r < 0) { + log_error("Couldn't read key: %s", strerror(-r)); + goto finish; + } + + fputs("\r \r", stdout); + fflush(stdout); + + switch (key) { + + case ' ': + immediate_refresh = true; + break; + + case 'q': + quit = true; + break; + + case 'p': + arg_order = ORDER_PATH; + break; + + case 't': + arg_order = ORDER_TASKS; + break; + + case 'c': + arg_order = ORDER_CPU; + break; + + case 'm': + arg_order = ORDER_MEMORY; + break; + + case 'i': + arg_order = ORDER_IO; + break; + + case '+': + if (arg_delay < USEC_PER_SEC) + arg_delay += USEC_PER_MSEC*250; + else + arg_delay += USEC_PER_SEC; + + fprintf(stdout, "\nIncreased delay to %s.", format_timespan(h, sizeof(h), arg_delay)); + fflush(stdout); + sleep(1); + break; + + case '-': + if (arg_delay <= USEC_PER_MSEC*500) + arg_delay = USEC_PER_MSEC*250; + else if (arg_delay < USEC_PER_MSEC*1250) + arg_delay -= USEC_PER_MSEC*250; + else + arg_delay -= USEC_PER_SEC; + + fprintf(stdout, "\nDecreased delay to %s.", format_timespan(h, sizeof(h), arg_delay)); + fflush(stdout); + sleep(1); + break; + + case '?': + case 'h': + fprintf(stdout, + "\t<" ANSI_HIGHLIGHT_ON "P" ANSI_HIGHLIGHT_OFF "> By path; <" ANSI_HIGHLIGHT_ON "T" ANSI_HIGHLIGHT_OFF "> By tasks; <" ANSI_HIGHLIGHT_ON "C" ANSI_HIGHLIGHT_OFF "> By CPU; <" ANSI_HIGHLIGHT_ON "M" ANSI_HIGHLIGHT_OFF "> By memory; <" ANSI_HIGHLIGHT_ON "I" ANSI_HIGHLIGHT_OFF "> By I/O\n" + "\t<" ANSI_HIGHLIGHT_ON "Q" ANSI_HIGHLIGHT_OFF "> Quit; <" ANSI_HIGHLIGHT_ON "+" ANSI_HIGHLIGHT_OFF "> Increase delay; <" ANSI_HIGHLIGHT_ON "-" ANSI_HIGHLIGHT_OFF "> Decrease delay; <" ANSI_HIGHLIGHT_ON "SPACE" ANSI_HIGHLIGHT_OFF "> Refresh"); + fflush(stdout); + sleep(3); + break; + + default: + fprintf(stdout, "\nUnknown key '%c'. Ignoring.", key); + fflush(stdout); + sleep(1); + break; + } + } + + log_info("Exiting."); + + r = 0; + +finish: + group_hashmap_free(a); + group_hashmap_free(b); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/condition.c b/src/condition.c new file mode 100644 index 0000000..2b51a16 --- /dev/null +++ b/src/condition.c @@ -0,0 +1,323 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#ifdef HAVE_SELINUX +#include +#endif + +#include "util.h" +#include "condition.h" +#include "virt.h" + +Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate) { + Condition *c; + + assert(type < _CONDITION_TYPE_MAX); + + c = new0(Condition, 1); + if (!c) + return NULL; + + c->type = type; + c->trigger = trigger; + c->negate = negate; + + if (parameter) { + c->parameter = strdup(parameter); + if (!c->parameter) { + free(c); + return NULL; + } + } + + return c; +} + +void condition_free(Condition *c) { + assert(c); + + free(c->parameter); + free(c); +} + +void condition_free_list(Condition *first) { + Condition *c, *n; + + LIST_FOREACH_SAFE(conditions, c, n, first) + condition_free(c); +} + +static bool test_kernel_command_line(const char *parameter) { + char *line, *w, *state, *word = NULL; + bool equal; + int r; + size_t l, pl; + bool found = false; + + assert(parameter); + + if (detect_container(NULL) > 0) + return false; + + r = read_one_line_file("/proc/cmdline", &line); + if (r < 0) { + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return false; + } + + equal = !!strchr(parameter, '='); + pl = strlen(parameter); + + FOREACH_WORD_QUOTED(w, l, line, state) { + + free(word); + word = strndup(w, l); + if (!word) + break; + + if (equal) { + if (streq(word, parameter)) { + found = true; + break; + } + } else { + if (startswith(word, parameter) && (word[pl] == '=' || word[pl] == 0)) { + found = true; + break; + } + } + + } + + free(word); + free(line); + + return found; +} + +static bool test_virtualization(const char *parameter) { + int b; + Virtualization v; + const char *id; + + assert(parameter); + + v = detect_virtualization(&id); + if (v < 0) { + log_warning("Failed to detect virtualization, ignoring: %s", strerror(-v)); + return false; + } + + /* First, compare with yes/no */ + b = parse_boolean(parameter); + + if (v > 0 && b > 0) + return true; + + if (v == 0 && b == 0) + return true; + + /* Then, compare categorization */ + if (v == VIRTUALIZATION_VM && streq(parameter, "vm")) + return true; + + if (v == VIRTUALIZATION_CONTAINER && streq(parameter, "container")) + return true; + + /* Finally compare id */ + return v > 0 && streq(parameter, id); +} + +static bool test_security(const char *parameter) { +#ifdef HAVE_SELINUX + if (streq(parameter, "selinux")) + return is_selinux_enabled() > 0; +#endif + return false; +} + +static bool test_capability(const char *parameter) { + cap_value_t value; + FILE *f; + char line[LINE_MAX]; + unsigned long long capabilities = (unsigned long long) -1; + + /* If it's an invalid capability, we don't have it */ + + if (cap_from_name(parameter, &value) < 0) + return false; + + /* If it's a valid capability we default to assume + * that we have it */ + + f = fopen("/proc/self/status", "re"); + if (!f) + return true; + + while (fgets(line, sizeof(line), f)) { + truncate_nl(line); + + if (startswith(line, "CapBnd:")) { + (void) sscanf(line+7, "%llx", &capabilities); + break; + } + } + + fclose(f); + + return !!(capabilities & (1ULL << value)); +} + +bool condition_test(Condition *c) { + assert(c); + + switch(c->type) { + + case CONDITION_PATH_EXISTS: + return (access(c->parameter, F_OK) >= 0) == !c->negate; + + case CONDITION_PATH_EXISTS_GLOB: + return (glob_exists(c->parameter) > 0) == !c->negate; + + case CONDITION_PATH_IS_DIRECTORY: { + struct stat st; + + if (stat(c->parameter, &st) < 0) + return c->negate; + return S_ISDIR(st.st_mode) == !c->negate; + } + + case CONDITION_PATH_IS_SYMBOLIC_LINK: { + struct stat st; + + if (lstat(c->parameter, &st) < 0) + return c->negate; + return S_ISLNK(st.st_mode) == !c->negate; + } + + case CONDITION_PATH_IS_MOUNT_POINT: + return (path_is_mount_point(c->parameter, true) > 0) == !c->negate; + + case CONDITION_DIRECTORY_NOT_EMPTY: { + int k; + + k = dir_is_empty(c->parameter); + return !(k == -ENOENT || k > 0) == !c->negate; + } + + case CONDITION_FILE_IS_EXECUTABLE: { + struct stat st; + + if (stat(c->parameter, &st) < 0) + return c->negate; + + return (S_ISREG(st.st_mode) && (st.st_mode & 0111)) == !c->negate; + } + + case CONDITION_KERNEL_COMMAND_LINE: + return test_kernel_command_line(c->parameter) == !c->negate; + + case CONDITION_VIRTUALIZATION: + return test_virtualization(c->parameter) == !c->negate; + + case CONDITION_SECURITY: + return test_security(c->parameter) == !c->negate; + + case CONDITION_CAPABILITY: + return test_capability(c->parameter) == !c->negate; + + case CONDITION_NULL: + return !c->negate; + + default: + assert_not_reached("Invalid condition type."); + } +} + +bool condition_test_list(Condition *first) { + Condition *c; + int triggered = -1; + + /* If the condition list is empty, then it is true */ + if (!first) + return true; + + /* Otherwise, if all of the non-trigger conditions apply and + * if any of the trigger conditions apply (unless there are + * none) we return true */ + LIST_FOREACH(conditions, c, first) { + bool b; + + b = condition_test(c); + + if (!c->trigger && !b) + return false; + + if (c->trigger && triggered <= 0) + triggered = b; + } + + return triggered != 0; +} + +void condition_dump(Condition *c, FILE *f, const char *prefix) { + assert(c); + assert(f); + + if (!prefix) + prefix = ""; + + fprintf(f, + "%s\t%s: %s%s%s\n", + prefix, + condition_type_to_string(c->type), + c->trigger ? "|" : "", + c->negate ? "!" : "", + c->parameter); +} + +void condition_dump_list(Condition *first, FILE *f, const char *prefix) { + Condition *c; + + LIST_FOREACH(conditions, c, first) + condition_dump(c, f, prefix); +} + +static const char* const condition_type_table[_CONDITION_TYPE_MAX] = { + [CONDITION_PATH_EXISTS] = "ConditionPathExists", + [CONDITION_PATH_EXISTS_GLOB] = "ConditionPathExistsGlob", + [CONDITION_PATH_IS_DIRECTORY] = "ConditionPathIsDirectory", + [CONDITION_PATH_IS_SYMBOLIC_LINK] = "ConditionPathIsSymbolicLink", + [CONDITION_PATH_IS_MOUNT_POINT] = "ConditionPathIsMountPoint", + [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty", + [CONDITION_KERNEL_COMMAND_LINE] = "ConditionKernelCommandLine", + [CONDITION_VIRTUALIZATION] = "ConditionVirtualization", + [CONDITION_SECURITY] = "ConditionSecurity", + [CONDITION_NULL] = "ConditionNull" +}; + +DEFINE_STRING_TABLE_LOOKUP(condition_type, ConditionType); diff --git a/src/condition.h b/src/condition.h new file mode 100644 index 0000000..71b1c67 --- /dev/null +++ b/src/condition.h @@ -0,0 +1,69 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooconditionhfoo +#define fooconditionhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "list.h" + +typedef enum ConditionType { + CONDITION_PATH_EXISTS, + CONDITION_PATH_EXISTS_GLOB, + CONDITION_PATH_IS_DIRECTORY, + CONDITION_PATH_IS_SYMBOLIC_LINK, + CONDITION_PATH_IS_MOUNT_POINT, + CONDITION_DIRECTORY_NOT_EMPTY, + CONDITION_FILE_IS_EXECUTABLE, + CONDITION_KERNEL_COMMAND_LINE, + CONDITION_VIRTUALIZATION, + CONDITION_SECURITY, + CONDITION_CAPABILITY, + CONDITION_NULL, + _CONDITION_TYPE_MAX, + _CONDITION_TYPE_INVALID = -1 +} ConditionType; + +typedef struct Condition { + ConditionType type; + char *parameter; + + bool trigger:1; + bool negate:1; + + LIST_FIELDS(struct Condition, conditions); +} Condition; + +Condition* condition_new(ConditionType type, const char *parameter, bool trigger, bool negate); +void condition_free(Condition *c); +void condition_free_list(Condition *c); + +bool condition_test(Condition *c); +bool condition_test_list(Condition *c); + +void condition_dump(Condition *c, FILE *f, const char *prefix); +void condition_dump_list(Condition *c, FILE *f, const char *prefix); + +const char* condition_type_to_string(ConditionType t); +int condition_type_from_string(const char *s); + +#endif diff --git a/src/conf-parser.c b/src/conf-parser.c new file mode 100644 index 0000000..c7dd01a --- /dev/null +++ b/src/conf-parser.c @@ -0,0 +1,811 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "conf-parser.h" +#include "util.h" +#include "macro.h" +#include "strv.h" +#include "log.h" + +int config_item_table_lookup( + void *table, + const char *section, + const char *lvalue, + ConfigParserCallback *func, + int *ltype, + void **data, + void *userdata) { + + ConfigTableItem *t; + + assert(table); + assert(lvalue); + assert(func); + assert(ltype); + assert(data); + + for (t = table; t->lvalue; t++) { + + if (!streq(lvalue, t->lvalue)) + continue; + + if (!streq_ptr(section, t->section)) + continue; + + *func = t->parse; + *ltype = t->ltype; + *data = t->data; + return 1; + } + + return 0; +} + +int config_item_perf_lookup( + void *table, + const char *section, + const char *lvalue, + ConfigParserCallback *func, + int *ltype, + void **data, + void *userdata) { + + ConfigPerfItemLookup lookup = (ConfigPerfItemLookup) table; + const ConfigPerfItem *p; + + assert(table); + assert(lvalue); + assert(func); + assert(ltype); + assert(data); + + if (!section) + p = lookup(lvalue, strlen(lvalue)); + else { + char *key; + + key = join(section, ".", lvalue, NULL); + if (!key) + return -ENOMEM; + + p = lookup(key, strlen(key)); + free(key); + } + + if (!p) + return 0; + + *func = p->parse; + *ltype = p->ltype; + *data = (uint8_t*) userdata + p->offset; + return 1; +} + +/* Run the user supplied parser for an assignment */ +static int next_assignment( + const char *filename, + unsigned line, + ConfigItemLookup lookup, + void *table, + const char *section, + const char *lvalue, + const char *rvalue, + bool relaxed, + void *userdata) { + + ConfigParserCallback func = NULL; + int ltype = 0; + void *data = NULL; + int r; + + assert(filename); + assert(line > 0); + assert(lookup); + assert(lvalue); + assert(rvalue); + + r = lookup(table, section, lvalue, &func, <ype, &data, userdata); + if (r < 0) + return r; + + if (r > 0) { + if (func) + return func(filename, line, section, lvalue, ltype, rvalue, data, userdata); + + return 0; + } + + /* Warn about unknown non-extension fields. */ + if (!relaxed && !startswith(lvalue, "X-")) + log_info("[%s:%u] Unknown lvalue '%s' in section '%s'. Ignoring.", filename, line, lvalue, section); + + return 0; +} + +/* Parse a variable assignment line */ +static int parse_line( + const char *filename, + unsigned line, + const char *sections, + ConfigItemLookup lookup, + void *table, + bool relaxed, + char **section, + char *l, + void *userdata) { + + char *e; + + assert(filename); + assert(line > 0); + assert(lookup); + assert(l); + + l = strstrip(l); + + if (!*l) + return 0; + + if (strchr(COMMENTS, *l)) + return 0; + + if (startswith(l, ".include ")) { + char *fn; + int r; + + fn = file_in_same_dir(filename, strstrip(l+9)); + if (!fn) + return -ENOMEM; + + r = config_parse(fn, NULL, sections, lookup, table, relaxed, userdata); + free(fn); + + return r; + } + + if (*l == '[') { + size_t k; + char *n; + + k = strlen(l); + assert(k > 0); + + if (l[k-1] != ']') { + log_error("[%s:%u] Invalid section header.", filename, line); + return -EBADMSG; + } + + n = strndup(l+1, k-2); + if (!n) + return -ENOMEM; + + if (sections && !nulstr_contains(sections, n)) { + + if (!relaxed) + log_info("[%s:%u] Unknown section '%s'. Ignoring.", filename, line, n); + + free(n); + *section = NULL; + } else { + free(*section); + *section = n; + } + + return 0; + } + + if (sections && !*section) + return 0; + + e = strchr(l, '='); + if (!e) { + log_error("[%s:%u] Missing '='.", filename, line); + return -EBADMSG; + } + + *e = 0; + e++; + + return next_assignment( + filename, + line, + lookup, + table, + *section, + strstrip(l), + strstrip(e), + relaxed, + userdata); +} + +/* Go through the file and parse each line */ +int config_parse( + const char *filename, + FILE *f, + const char *sections, + ConfigItemLookup lookup, + void *table, + bool relaxed, + void *userdata) { + + unsigned line = 0; + char *section = NULL; + int r; + bool ours = false; + char *continuation = NULL; + + assert(filename); + assert(lookup); + + if (!f) { + f = fopen(filename, "re"); + if (!f) { + r = -errno; + log_error("Failed to open configuration file '%s': %s", filename, strerror(-r)); + goto finish; + } + + ours = true; + } + + while (!feof(f)) { + char l[LINE_MAX], *p, *c = NULL, *e; + bool escaped = false; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + r = -errno; + log_error("Failed to read configuration file '%s': %s", filename, strerror(-r)); + goto finish; + } + + truncate_nl(l); + + if (continuation) { + c = strappend(continuation, l); + if (!c) { + r = -ENOMEM; + goto finish; + } + + free(continuation); + continuation = NULL; + p = c; + } else + p = l; + + for (e = p; *e; e++) { + if (escaped) + escaped = false; + else if (*e == '\\') + escaped = true; + } + + if (escaped) { + *(e-1) = ' '; + + if (c) + continuation = c; + else { + continuation = strdup(l); + if (!continuation) { + r = -ENOMEM; + goto finish; + } + } + + continue; + } + + r = parse_line(filename, + ++line, + sections, + lookup, + table, + relaxed, + §ion, + p, + userdata); + free(c); + + if (r < 0) + goto finish; + } + + r = 0; + +finish: + free(section); + free(continuation); + + if (f && ours) + fclose(f); + + return r; +} + +int config_parse_int( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + int *i = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((r = safe_atoi(rvalue, i)) < 0) { + log_error("[%s:%u] Failed to parse numeric value, ingoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_long( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + long *i = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((r = safe_atoli(rvalue, i)) < 0) { + log_error("[%s:%u] Failed to parse numeric value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_uint64( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + uint64_t *u = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((r = safe_atou64(rvalue, u)) < 0) { + log_error("[%s:%u] Failed to parse numeric value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_unsigned( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + unsigned *u = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((r = safe_atou(rvalue, u)) < 0) { + log_error("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue); + return r; + } + + return 0; +} + +int config_parse_bytes_size( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + size_t *sz = data; + off_t o; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (parse_bytes(rvalue, &o) < 0 || (off_t) (size_t) o != o) { + log_error("[%s:%u] Failed to parse byte value, ignoring: %s", filename, line, rvalue); + return 0; + } + + *sz = (size_t) o; + return 0; +} + + +int config_parse_bytes_off( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + off_t *bytes = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + assert_cc(sizeof(off_t) == sizeof(uint64_t)); + + if (parse_bytes(rvalue, bytes) < 0) { + log_error("[%s:%u] Failed to parse bytes value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_bool( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + int k; + bool *b = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((k = parse_boolean(rvalue)) < 0) { + log_error("[%s:%u] Failed to parse boolean value, ignoring: %s", filename, line, rvalue); + return 0; + } + + *b = !!k; + return 0; +} + +int config_parse_tristate( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + int k; + int *b = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + /* Tristates are like booleans, but can also take the 'default' value, i.e. "-1" */ + + k = parse_boolean(rvalue); + if (k < 0) { + log_error("[%s:%u] Failed to parse boolean value, ignoring: %s", filename, line, rvalue); + return 0; + } + + *b = !!k; + return 0; +} + +int config_parse_string( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char **s = data; + char *n; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (*rvalue) { + if (!(n = strdup(rvalue))) + return -ENOMEM; + } else + n = NULL; + + free(*s); + *s = n; + + return 0; +} + +int config_parse_path( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char **s = data; + char *n; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (!path_is_absolute(rvalue)) { + log_error("[%s:%u] Not an absolute path, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (!(n = strdup(rvalue))) + return -ENOMEM; + + path_kill_slashes(n); + + free(*s); + *s = n; + + return 0; +} + +int config_parse_strv( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char*** sv = data; + char **n; + char *w; + unsigned k; + size_t l; + char *state; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + k = strv_length(*sv); + FOREACH_WORD_QUOTED(w, l, rvalue, state) + k++; + + if (!(n = new(char*, k+1))) + return -ENOMEM; + + if (*sv) + for (k = 0; (*sv)[k]; k++) + n[k] = (*sv)[k]; + else + k = 0; + + FOREACH_WORD_QUOTED(w, l, rvalue, state) + if (!(n[k++] = cunescape_length(w, l))) + goto fail; + + n[k] = NULL; + free(*sv); + *sv = n; + + return 0; + +fail: + for (; k > 0; k--) + free(n[k-1]); + free(n); + + return -ENOMEM; +} + +int config_parse_path_strv( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char*** sv = data; + char **n; + char *w; + unsigned k; + size_t l; + char *state; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + k = strv_length(*sv); + FOREACH_WORD_QUOTED(w, l, rvalue, state) + k++; + + if (!(n = new(char*, k+1))) + return -ENOMEM; + + k = 0; + if (*sv) + for (; (*sv)[k]; k++) + n[k] = (*sv)[k]; + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + if (!(n[k] = cunescape_length(w, l))) { + r = -ENOMEM; + goto fail; + } + + if (!path_is_absolute(n[k])) { + log_error("[%s:%u] Not an absolute path, ignoring: %s", filename, line, rvalue); + free(n[k]); + continue; + } + + path_kill_slashes(n[k]); + + k++; + } + + n[k] = NULL; + free(*sv); + *sv = n; + + return 0; + +fail: + free(n[k]); + for (; k > 0; k--) + free(n[k-1]); + free(n); + + return r; +} + +int config_parse_usec( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + usec_t *usec = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (parse_usec(rvalue, usec) < 0) { + log_error("[%s:%u] Failed to parse time value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_mode( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + mode_t *m = data; + long l; + char *x = NULL; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + errno = 0; + l = strtol(rvalue, &x, 8); + if (!x || *x || errno) { + log_error("[%s:%u] Failed to parse mode value, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (l < 0000 || l > 07777) { + log_error("[%s:%u] mode value out of range, ignoring: %s", filename, line, rvalue); + return 0; + } + + *m = (mode_t) l; + return 0; +} diff --git a/src/conf-parser.h b/src/conf-parser.h new file mode 100644 index 0000000..be7d708 --- /dev/null +++ b/src/conf-parser.h @@ -0,0 +1,135 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooconfparserhfoo +#define fooconfparserhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +/* An abstract parser for simple, line based, shallow configuration + * files consisting of variable assignments only. */ + +/* Prototype for a parser for a specific configuration setting */ +typedef int (*ConfigParserCallback)( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata); + +/* Wraps information for parsing a specific configuration variable, to + * be stored in a simple array */ +typedef struct ConfigTableItem { + const char *section; /* Section */ + const char *lvalue; /* Name of the variable */ + ConfigParserCallback parse; /* Function that is called to parse the variable's value */ + int ltype; /* Distinguish different variables passed to the same callback */ + void *data; /* Where to store the variable's data */ +} ConfigTableItem; + +/* Wraps information for parsing a specific configuration variable, to + * ve srored in a gperf perfect hashtable */ +typedef struct ConfigPerfItem { + const char *section_and_lvalue; /* Section + "." + name of the variable */ + ConfigParserCallback parse; /* Function that is called to parse the variable's value */ + int ltype; /* Distinguish different variables passed to the same callback */ + size_t offset; /* Offset where to store data, from the beginning of userdata */ +} ConfigPerfItem; + +/* Prototype for a low-level gperf lookup function */ +typedef const ConfigPerfItem* (*ConfigPerfItemLookup)(const char *section_and_lvalue, unsigned length); + +/* Prototype for a generic high-level lookup function */ +typedef int (*ConfigItemLookup)( + void *table, + const char *section, + const char *lvalue, + ConfigParserCallback *func, + int *ltype, + void **data, + void *userdata); + +/* Linear table search implementation of ConfigItemLookup, based on + * ConfigTableItem arrays */ +int config_item_table_lookup(void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata); + +/* gperf implementation of ConfigItemLookup, based on gperf + * ConfigPerfItem tables */ +int config_item_perf_lookup(void *table, const char *section, const char *lvalue, ConfigParserCallback *func, int *ltype, void **data, void *userdata); + +int config_parse( + const char *filename, + FILE *f, + const char *sections, /* nulstr */ + ConfigItemLookup lookup, + void *table, + bool relaxed, + void *userdata); + +/* Generic parsers */ +int config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_long(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_uint64(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_bytes_size(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_bytes_off(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_tristate(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_string(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_path(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_path_strv(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_usec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_mode(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + +#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \ + int function( \ + const char *filename, \ + unsigned line, \ + const char *section, \ + const char *lvalue, \ + int ltype, \ + const char *rvalue, \ + void *data, \ + void *userdata) { \ + \ + type *i = data, x; \ + \ + assert(filename); \ + assert(lvalue); \ + assert(rvalue); \ + assert(data); \ + \ + if ((x = name##_from_string(rvalue)) < 0) { \ + log_error("[%s:%u] " msg ", ignoring: %s", filename, line, rvalue); \ + return 0; \ + } \ + \ + *i = x; \ + \ + return 0; \ + } + +#endif diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c new file mode 100644 index 0000000..ba59b49 --- /dev/null +++ b/src/cryptsetup/cryptsetup-generator.c @@ -0,0 +1,298 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "unit-name.h" + +const char *arg_dest = "/tmp"; + +static bool has_option(const char *haystack, const char *needle) { + const char *f = haystack; + size_t l; + + assert(needle); + + if (!haystack) + return false; + + l = strlen(needle); + + while ((f = strstr(f, needle))) { + + if (f > haystack && f[-1] != ',') { + f++; + continue; + } + + if (f[l] != 0 && f[l] != ',') { + f++; + continue; + } + + return true; + } + + return false; +} + +static int create_disk( + const char *name, + const char *device, + const char *password, + const char *options) { + + char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *from = NULL, *to = NULL, *e = NULL; + int r; + FILE *f = NULL; + bool noauto, nofail; + + assert(name); + assert(device); + + noauto = has_option(options, "noauto"); + nofail = has_option(options, "nofail"); + + if (!(n = unit_name_build_escape("cryptsetup", name, ".service"))) { + r = -ENOMEM; + log_error("Failed to allocate unit name."); + goto fail; + } + + if (asprintf(&p, "%s/%s", arg_dest, n) < 0) { + r = -ENOMEM; + log_error("Failed to allocate unit file name."); + goto fail; + } + + if (!(u = fstab_node_to_udev_node(device))) { + r = -ENOMEM; + log_error("Failed to allocate device node."); + goto fail; + } + + if (!(d = unit_name_from_path(u, ".device"))) { + r = -ENOMEM; + log_error("Failed to allocate device name."); + goto fail; + } + + if (!(f = fopen(p, "wxe"))) { + r = -errno; + log_error("Failed to create unit file: %m"); + goto fail; + } + + fprintf(f, + "[Unit]\n" + "Description=Cryptography Setup for %%I\n" + "Conflicts=umount.target\n" + "DefaultDependencies=no\n" + "BindTo=%s dev-mapper-%%i.device\n" + "After=systemd-readahead-collect.service systemd-readahead-replay.service %s\n" + "Before=umount.target\n", + d, d); + + if (!nofail) + fprintf(f, + "Before=cryptsetup.target\n"); + + if (password && (streq(password, "/dev/urandom") || + streq(password, "/dev/random") || + streq(password, "/dev/hw_random"))) + fprintf(f, + "After=systemd-random-seed-load.service\n"); + else + fprintf(f, + "Before=local-fs.target\n"); + + fprintf(f, + "\n[Service]\n" + "Type=oneshot\n" + "RemainAfterExit=yes\n" + "TimeoutSec=0\n" /* the binary handles timeouts anyway */ + "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n" + "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n", + name, u, strempty(password), strempty(options), + name); + + if (has_option(options, "tmp")) + fprintf(f, + "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n", + name); + + if (has_option(options, "swap")) + fprintf(f, + "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n", + name); + + fflush(f); + + if (ferror(f)) { + r = -errno; + log_error("Failed to write file: %m"); + goto fail; + } + + if (asprintf(&from, "../%s", n) < 0) { + r = -ENOMEM; + goto fail; + } + + if (!noauto) { + + if (asprintf(&to, "%s/%s.wants/%s", arg_dest, d, n) < 0) { + r = -ENOMEM; + goto fail; + } + + mkdir_parents(to, 0755); + + if (symlink(from, to) < 0) { + log_error("Failed to create symlink '%s' to '%s': %m", from, to); + r = -errno; + goto fail; + } + + free(to); + to = NULL; + + if (!nofail) + asprintf(&to, "%s/cryptsetup.target.requires/%s", arg_dest, n); + else + asprintf(&to, "%s/cryptsetup.target.wants/%s", arg_dest, n); + + if (!to) { + r = -ENOMEM; + goto fail; + } + + mkdir_parents(to, 0755); + + if (symlink(from, to) < 0) { + log_error("Failed to create symlink '%s' to '%s': %m", from, to); + r = -errno; + goto fail; + } + } + + free(to); + to = NULL; + + e = unit_name_escape(name); + if (asprintf(&to, "%s/dev-mapper-%s.device.requires/%s", arg_dest, e, n) < 0) { + r = -ENOMEM; + goto fail; + } + + mkdir_parents(to, 0755); + + if (symlink(from, to) < 0) { + log_error("Failed to create symlink '%s' to '%s': %m", from, to); + r = -errno; + goto fail; + } + + r = 0; + +fail: + free(p); + free(n); + free(d); + free(e); + + free(from); + free(to); + + if (f) + fclose(f); + + return r; +} + +int main(int argc, char *argv[]) { + FILE *f; + int r = EXIT_SUCCESS; + unsigned n = 0; + + if (argc > 2) { + log_error("This program takes one or no arguments."); + return EXIT_FAILURE; + } + + if (argc > 1) + arg_dest = argv[1]; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (!(f = fopen("/etc/crypttab", "re"))) { + + if (errno == ENOENT) + r = EXIT_SUCCESS; + else { + r = EXIT_FAILURE; + log_error("Failed to open /etc/crypttab: %m"); + } + + goto finish; + } + + for (;;) { + char line[LINE_MAX], *l; + char *name = NULL, *device = NULL, *password = NULL, *options = NULL; + int k; + + if (!(fgets(line, sizeof(line), f))) + break; + + n++; + + l = strstrip(line); + if (*l == '#' || *l == 0) + continue; + + if ((k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &password, &options)) < 2 || k > 4) { + log_error("Failed to parse /etc/crypttab:%u, ignoring.", n); + r = EXIT_FAILURE; + goto next; + } + + if (create_disk(name, device, password, options) < 0) + r = EXIT_FAILURE; + + next: + free(name); + free(device); + free(password); + free(options); + } + +finish: + return r; +} diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c new file mode 100644 index 0000000..ac7b6d6 --- /dev/null +++ b/src/cryptsetup/cryptsetup.c @@ -0,0 +1,529 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include +#include + +#include "log.h" +#include "util.h" +#include "strv.h" +#include "ask-password-api.h" +#include "def.h" + +static const char *opt_type = NULL; /* LUKS1 or PLAIN */ +static char *opt_cipher = NULL; +static unsigned opt_key_size = 0; +static char *opt_hash = NULL; +static unsigned opt_tries = 0; +static bool opt_readonly = false; +static bool opt_verify = false; +static usec_t opt_timeout = DEFAULT_TIMEOUT_USEC; + +/* Options Debian's crypttab knows we don't: + + offset= + skip= + precheck= + check= + checkargs= + noearly= + loud= + keyscript= +*/ + +static int parse_one_option(const char *option) { + assert(option); + + /* Handled outside of this tool */ + if (streq(option, "noauto")) + return 0; + + if (startswith(option, "cipher=")) { + char *t; + + if (!(t = strdup(option+7))) + return -ENOMEM; + + free(opt_cipher); + opt_cipher = t; + + } else if (startswith(option, "size=")) { + + if (safe_atou(option+5, &opt_key_size) < 0) { + log_error("size= parse failure, ignoring."); + return 0; + } + + } else if (startswith(option, "hash=")) { + char *t; + + if (!(t = strdup(option+5))) + return -ENOMEM; + + free(opt_hash); + opt_hash = t; + + } else if (startswith(option, "tries=")) { + + if (safe_atou(option+6, &opt_tries) < 0) { + log_error("tries= parse failure, ignoring."); + return 0; + } + + } else if (streq(option, "readonly")) + opt_readonly = true; + else if (streq(option, "verify")) + opt_verify = true; + else if (streq(option, "luks")) + opt_type = CRYPT_LUKS1; + else if (streq(option, "plain") || + streq(option, "swap") || + streq(option, "tmp")) + opt_type = CRYPT_PLAIN; + else if (startswith(option, "timeout=")) { + + if (parse_usec(option+8, &opt_timeout) < 0) { + log_error("timeout= parse failure, ignoring."); + return 0; + } + + } else if (!streq(option, "none")) + log_error("Encountered unknown /etc/crypttab option '%s', ignoring.", option); + + return 0; +} + +static int parse_options(const char *options) { + char *state; + char *w; + size_t l; + + assert(options); + + FOREACH_WORD_SEPARATOR(w, l, options, ",", state) { + char *o; + int r; + + if (!(o = strndup(w, l))) + return -ENOMEM; + + r = parse_one_option(o); + free(o); + + if (r < 0) + return r; + } + + return 0; +} + +static void log_glue(int level, const char *msg, void *usrptr) { + log_debug("%s", msg); +} + +static char *disk_description(const char *path) { + struct udev *udev = NULL; + struct udev_device *device = NULL; + struct stat st; + char *description = NULL; + const char *model; + + assert(path); + + if (stat(path, &st) < 0) + return NULL; + + if (!S_ISBLK(st.st_mode)) + return NULL; + + if (!(udev = udev_new())) + return NULL; + + if (!(device = udev_device_new_from_devnum(udev, 'b', st.st_rdev))) + goto finish; + + if ((model = udev_device_get_property_value(device, "ID_MODEL_FROM_DATABASE")) || + (model = udev_device_get_property_value(device, "ID_MODEL")) || + (model = udev_device_get_property_value(device, "DM_NAME"))) + description = strdup(model); + +finish: + if (device) + udev_device_unref(device); + + if (udev) + udev_unref(udev); + + return description; +} + +static char *disk_mount_point(const char *label) { + char *mp = NULL, *device = NULL; + FILE *f = NULL; + struct mntent *m; + + /* Yeah, we don't support native systemd unit files here for now */ + + if (asprintf(&device, "/dev/mapper/%s", label) < 0) + goto finish; + + if (!(f = setmntent("/etc/fstab", "r"))) + goto finish; + + while ((m = getmntent(f))) + if (path_equal(m->mnt_fsname, device)) { + mp = strdup(m->mnt_dir); + break; + } + +finish: + if (f) + endmntent(f); + + free(device); + + return mp; +} + +static int help(void) { + + printf("%s attach VOLUME SOURCEDEVICE [PASSWORD] [OPTIONS]\n" + "%s detach VOLUME\n\n" + "Attaches or detaches an encrypted block device.\n", + program_invocation_short_name, + program_invocation_short_name); + + return 0; +} + +int main(int argc, char *argv[]) { + int r = EXIT_FAILURE; + struct crypt_device *cd = NULL; + char **passwords = NULL, *truncated_cipher = NULL; + const char *cipher = NULL, *cipher_mode = NULL, *hash = NULL, *name = NULL; + char *description = NULL, *name_buffer = NULL, *mount_point = NULL; + unsigned keyfile_size = 0; + + if (argc <= 1) { + help(); + return EXIT_SUCCESS; + } + + if (argc < 3) { + log_error("This program requires at least two arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (streq(argv[1], "attach")) { + uint32_t flags = 0; + int k; + unsigned try; + const char *key_file = NULL; + usec_t until; + crypt_status_info status; + + /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [PASSWORD] [OPTIONS] */ + + if (argc < 4) { + log_error("attach requires at least two arguments."); + goto finish; + } + + if (argc >= 5 && + argv[4][0] && + !streq(argv[4], "-") && + !streq(argv[4], "none")) { + + if (!path_is_absolute(argv[4])) + log_error("Password file path %s is not absolute. Ignoring.", argv[4]); + else + key_file = argv[4]; + } + + if (argc >= 6 && argv[5][0] && !streq(argv[5], "-")) + parse_options(argv[5]); + + /* A delicious drop of snake oil */ + mlockall(MCL_FUTURE); + + description = disk_description(argv[3]); + mount_point = disk_mount_point(argv[2]); + + if (description && streq(argv[2], description)) { + /* If the description string is simply the + * volume name, then let's not show this + * twice */ + free(description); + description = NULL; + } + + if (mount_point && description) + asprintf(&name_buffer, "%s (%s) on %s", description, argv[2], mount_point); + else if (mount_point) + asprintf(&name_buffer, "%s on %s", argv[2], mount_point); + else if (description) + asprintf(&name_buffer, "%s (%s)", description, argv[2]); + + name = name_buffer ? name_buffer : argv[2]; + + if ((k = crypt_init(&cd, argv[3]))) { + log_error("crypt_init() failed: %s", strerror(-k)); + goto finish; + } + + crypt_set_log_callback(cd, log_glue, NULL); + + status = crypt_status(cd, argv[2]); + if (status == CRYPT_ACTIVE || status == CRYPT_BUSY) { + log_info("Volume %s already active.", argv[2]); + r = EXIT_SUCCESS; + goto finish; + } + + if (opt_readonly) + flags |= CRYPT_ACTIVATE_READONLY; + + if (opt_timeout > 0) + until = now(CLOCK_MONOTONIC) + opt_timeout; + else + until = 0; + + opt_tries = opt_tries > 0 ? opt_tries : 3; + opt_key_size = (opt_key_size > 0 ? opt_key_size : 256); + hash = opt_hash ? opt_hash : "ripemd160"; + + if (opt_cipher) { + size_t l; + + l = strcspn(opt_cipher, "-"); + + if (!(truncated_cipher = strndup(opt_cipher, l))) { + log_error("Out of memory"); + goto finish; + } + + cipher = truncated_cipher; + cipher_mode = opt_cipher[l] ? opt_cipher+l+1 : "plain"; + } else { + cipher = "aes"; + cipher_mode = "cbc-essiv:sha256"; + } + + for (try = 0; try < opt_tries; try++) { + bool pass_volume_key = false; + + strv_free(passwords); + passwords = NULL; + + if (!key_file) { + char *text; + char **p; + + if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0) { + log_error("Out of memory"); + goto finish; + } + + k = ask_password_auto(text, "drive-harddisk", until, try == 0 && !opt_verify, &passwords); + free(text); + + if (k < 0) { + log_error("Failed to query password: %s", strerror(-k)); + goto finish; + } + + if (opt_verify) { + char **passwords2 = NULL; + + assert(strv_length(passwords) == 1); + + if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0) { + log_error("Out of memory"); + goto finish; + } + + k = ask_password_auto(text, "drive-harddisk", until, false, &passwords2); + free(text); + + if (k < 0) { + log_error("Failed to query verification password: %s", strerror(-k)); + goto finish; + } + + assert(strv_length(passwords2) == 1); + + if (!streq(passwords[0], passwords2[0])) { + log_warning("Passwords did not match, retrying."); + strv_free(passwords2); + continue; + } + + strv_free(passwords2); + } + + strv_uniq(passwords); + + STRV_FOREACH(p, passwords) { + char *c; + + if (strlen(*p)+1 >= opt_key_size) + continue; + + /* Pad password if necessary */ + if (!(c = new(char, opt_key_size))) { + log_error("Out of memory."); + goto finish; + } + + strncpy(c, *p, opt_key_size); + free(*p); + *p = c; + } + } + + k = 0; + + if (!opt_type || streq(opt_type, CRYPT_LUKS1)) + k = crypt_load(cd, CRYPT_LUKS1, NULL); + + if ((!opt_type && k < 0) || streq_ptr(opt_type, CRYPT_PLAIN)) { + struct crypt_params_plain params; + + zero(params); + params.hash = hash; + + /* In contrast to what the name + * crypt_setup() might suggest this + * doesn't actually format anything, + * it just configures encryption + * parameters when used for plain + * mode. */ + k = crypt_format(cd, CRYPT_PLAIN, + cipher, + cipher_mode, + NULL, + NULL, + opt_key_size / 8, + ¶ms); + + pass_volume_key = streq(hash, "plain"); + + /* for CRYPT_PLAIN limit reads + * from keyfile to key length */ + keyfile_size = opt_key_size / 8; + } + + if (k < 0) { + log_error("Loading of cryptographic parameters failed: %s", strerror(-k)); + goto finish; + } + + log_info("Set cipher %s, mode %s, key size %i bits for device %s.", + crypt_get_cipher(cd), + crypt_get_cipher_mode(cd), + crypt_get_volume_key_size(cd)*8, + argv[3]); + + if (key_file) + k = crypt_activate_by_keyfile(cd, argv[2], CRYPT_ANY_SLOT, key_file, keyfile_size, flags); + else { + char **p; + + STRV_FOREACH(p, passwords) { + + if (pass_volume_key) + k = crypt_activate_by_volume_key(cd, argv[2], *p, opt_key_size, flags); + else + k = crypt_activate_by_passphrase(cd, argv[2], CRYPT_ANY_SLOT, *p, strlen(*p), flags); + + if (k >= 0) + break; + } + } + + if (k >= 0) + break; + + if (k != -EPERM) { + log_error("Failed to activate: %s", strerror(-k)); + goto finish; + } + + log_warning("Invalid passphrase."); + } + + if (try >= opt_tries) { + log_error("Too many attempts."); + r = EXIT_FAILURE; + goto finish; + } + + } else if (streq(argv[1], "detach")) { + int k; + + if ((k = crypt_init_by_name(&cd, argv[2]))) { + log_error("crypt_init() failed: %s", strerror(-k)); + goto finish; + } + + crypt_set_log_callback(cd, log_glue, NULL); + + if ((k = crypt_deactivate(cd, argv[2])) < 0) { + log_error("Failed to deactivate: %s", strerror(-k)); + goto finish; + } + + } else { + log_error("Unknown verb %s.", argv[1]); + goto finish; + } + + r = EXIT_SUCCESS; + +finish: + + if (cd) + crypt_free(cd); + + free(opt_cipher); + free(opt_hash); + + free(truncated_cipher); + + strv_free(passwords); + + free(description); + free(mount_point); + free(name_buffer); + + return r; +} diff --git a/src/dbus-automount.c b/src/dbus-automount.c new file mode 100644 index 0000000..8e45f81 --- /dev/null +++ b/src/dbus-automount.c @@ -0,0 +1,72 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-automount.h" +#include "dbus-common.h" + +#define BUS_AUTOMOUNT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_AUTOMOUNT_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Automount\0" + +const char bus_automount_interface[] _introspect_("Automount") = BUS_AUTOMOUNT_INTERFACE; + +const char bus_automount_invalidating_properties[] = + "Result\0"; + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_automount_append_automount_result, automount_result, AutomountResult); + +static const BusProperty bus_automount_properties[] = { + { "Where", bus_property_append_string, "s", offsetof(Automount, where), true }, + { "DirectoryMode", bus_property_append_mode, "u", offsetof(Automount, directory_mode) }, + { "Result", bus_automount_append_automount_result, "s", offsetof(Automount, result) }, + { NULL, } +}; + +DBusHandlerResult bus_automount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Automount *am = AUTOMOUNT(u); + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Automount", bus_automount_properties, am }, + { NULL, } + }; + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/dbus-automount.h b/src/dbus-automount.h new file mode 100644 index 0000000..2fc8345 --- /dev/null +++ b/src/dbus-automount.h @@ -0,0 +1,34 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbusautomounthfoo +#define foodbusautomounthfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_automount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_automount_interface[]; +extern const char bus_automount_invalidating_properties[]; + +#endif diff --git a/src/dbus-common.c b/src/dbus-common.c new file mode 100644 index 0000000..2905ac3 --- /dev/null +++ b/src/dbus-common.c @@ -0,0 +1,1092 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "dbus-common.h" +#include "util.h" +#include "def.h" +#include "strv.h" + +int bus_check_peercred(DBusConnection *c) { + int fd; + struct ucred ucred; + socklen_t l; + + assert(c); + + assert_se(dbus_connection_get_unix_fd(c, &fd)); + + l = sizeof(struct ucred); + if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0) { + log_error("SO_PEERCRED failed: %m"); + return -errno; + } + + if (l != sizeof(struct ucred)) { + log_error("SO_PEERCRED returned wrong size."); + return -E2BIG; + } + + if (ucred.uid != 0 && ucred.uid != geteuid()) + return -EPERM; + + return 1; +} + +static int sync_auth(DBusConnection *bus, DBusError *error) { + usec_t begin, tstamp; + + assert(bus); + + /* This complexity should probably move into D-Bus itself: + * + * https://bugs.freedesktop.org/show_bug.cgi?id=35189 */ + + begin = tstamp = now(CLOCK_MONOTONIC); + for (;;) { + + if (tstamp > begin + DEFAULT_TIMEOUT_USEC) + break; + + if (dbus_connection_get_is_authenticated(bus)) + break; + + if (!dbus_connection_read_write_dispatch(bus, ((begin + DEFAULT_TIMEOUT_USEC - tstamp) + USEC_PER_MSEC - 1) / USEC_PER_MSEC)) + break; + + tstamp = now(CLOCK_MONOTONIC); + } + + if (!dbus_connection_get_is_connected(bus)) { + dbus_set_error_const(error, DBUS_ERROR_NO_SERVER, "Connection terminated during authentication."); + return -ECONNREFUSED; + } + + if (!dbus_connection_get_is_authenticated(bus)) { + dbus_set_error_const(error, DBUS_ERROR_TIMEOUT, "Failed to authenticate in time."); + return -EACCES; + } + + return 0; +} + +int bus_connect(DBusBusType t, DBusConnection **_bus, bool *_private, DBusError *error) { + DBusConnection *bus = NULL; + int r; + bool private = true; + + assert(_bus); + + if (geteuid() == 0 && t == DBUS_BUS_SYSTEM) { + /* If we are root, then let's talk directly to the + * system instance, instead of going via the bus */ + + bus = dbus_connection_open_private("unix:path=/run/systemd/private", error); + if (!bus) + return -EIO; + + } else { + if (t == DBUS_BUS_SESSION) { + const char *e; + + /* If we are supposed to talk to the instance, + * try via XDG_RUNTIME_DIR first, then + * fallback to normal bus access */ + + e = getenv("XDG_RUNTIME_DIR"); + if (e) { + char *p; + + if (asprintf(&p, "unix:path=%s/systemd/private", e) < 0) + return -ENOMEM; + + bus = dbus_connection_open_private(p, NULL); + free(p); + } + } + + if (!bus) { + bus = dbus_bus_get_private(t, error); + if (!bus) + return -EIO; + + private = false; + } + } + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + if (private) { + if (bus_check_peercred(bus) < 0) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + + dbus_set_error_const(error, DBUS_ERROR_ACCESS_DENIED, "Failed to verify owner of bus."); + return -EACCES; + } + } + + r = sync_auth(bus, error); + if (r < 0) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + + if (_private) + *_private = private; + + *_bus = bus; + return 0; +} + +int bus_connect_system_ssh(const char *user, const char *host, DBusConnection **_bus, DBusError *error) { + DBusConnection *bus; + char *p = NULL; + int r; + + assert(_bus); + assert(user || host); + + if (user && host) + asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s@%s,argv3=systemd-stdio-bridge", user, host); + else if (user) + asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s@localhost,argv3=systemd-stdio-bridge", user); + else if (host) + asprintf(&p, "unixexec:path=ssh,argv1=-xT,argv2=%s,argv3=systemd-stdio-bridge", host); + + if (!p) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL); + return -ENOMEM; + } + + bus = dbus_connection_open_private(p, error); + free(p); + + if (!bus) + return -EIO; + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + if ((r = sync_auth(bus, error)) < 0) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + + if (!dbus_bus_register(bus, error)) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + + *_bus = bus; + return 0; +} + +int bus_connect_system_polkit(DBusConnection **_bus, DBusError *error) { + DBusConnection *bus; + int r; + + assert(_bus); + + /* Don't bother with PolicyKit if we are root */ + if (geteuid() == 0) + return bus_connect(DBUS_BUS_SYSTEM, _bus, NULL, error); + + bus = dbus_connection_open_private("unixexec:path=pkexec,argv1=" SYSTEMD_STDIO_BRIDGE_BINARY_PATH, error); + if (!bus) + return -EIO; + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + if ((r = sync_auth(bus, error)) < 0) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + + if (!dbus_bus_register(bus, error)) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + return r; + } + + *_bus = bus; + return 0; +} + +const char *bus_error_message(const DBusError *error) { + assert(error); + + /* Sometimes the D-Bus server is a little bit too verbose with + * its error messages, so let's override them here */ + if (dbus_error_has_name(error, DBUS_ERROR_ACCESS_DENIED)) + return "Access denied"; + + return error->message; +} + +DBusHandlerResult bus_default_message_handler( + DBusConnection *c, + DBusMessage *message, + const char *introspection, + const char *interfaces, + const BusBoundProperties *bound_properties) { + + DBusError error; + DBusMessage *reply = NULL; + int r; + + assert(c); + assert(message); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect") && introspection) { + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Get") && bound_properties) { + const char *interface, *property; + const BusBoundProperties *bp; + const BusProperty *p; + void *data; + DBusMessageIter iter, sub; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(c, message, &error, -EINVAL); + + for (bp = bound_properties; bp->interface; bp++) { + if (!streq(bp->interface, interface)) + continue; + + for (p = bp->properties; p->property; p++) + if (streq(p->property, property)) + goto get_prop; + } + + /* no match */ + if (!nulstr_contains(interfaces, interface)) + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + else + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property"); + + return bus_send_error_reply(c, message, &error, -EINVAL); + +get_prop: + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, p->signature, &sub)) + goto oom; + + data = (char*)bp->base + p->offset; + if (p->indirect) + data = *(void**)data; + r = p->append(&sub, property, data); + if (r < 0) { + if (r == -ENOMEM) + goto oom; + + dbus_message_unref(reply); + return bus_send_error_reply(c, message, NULL, r); + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "GetAll") && bound_properties) { + const char *interface; + const BusBoundProperties *bp; + const BusProperty *p; + DBusMessageIter iter, sub, sub2, sub3; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(c, message, &error, -EINVAL); + + if (interface[0] && !nulstr_contains(interfaces, interface)) { + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + return bus_send_error_reply(c, message, &error, -EINVAL); + } + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub)) + goto oom; + + for (bp = bound_properties; bp->interface; bp++) { + if (interface[0] && !streq(bp->interface, interface)) + continue; + + for (p = bp->properties; p->property; p++) { + void *data; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &p->property) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, p->signature, &sub3)) + goto oom; + + data = (char*)bp->base + p->offset; + if (p->indirect) + data = *(void**)data; + r = p->append(&sub3, p->property, data); + if (r < 0) { + if (r == -ENOMEM) + goto oom; + + dbus_message_unref(reply); + return bus_send_error_reply(c, message, NULL, r); + } + + if (!dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set") && bound_properties) { + const char *interface, *property; + DBusMessageIter iter; + const BusBoundProperties *bp; + const BusProperty *p; + DBusMessageIter sub; + char *sig; + + if (!dbus_message_iter_init(message, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return bus_send_error_reply(c, message, NULL, -EINVAL); + + dbus_message_iter_get_basic(&iter, &interface); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return bus_send_error_reply(c, message, NULL, -EINVAL); + + dbus_message_iter_get_basic(&iter, &property); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT || + dbus_message_iter_has_next(&iter)) + return bus_send_error_reply(c, message, NULL, -EINVAL); + + for (bp = bound_properties; bp->interface; bp++) { + if (!streq(bp->interface, interface)) + continue; + + for (p = bp->properties; p->property; p++) + if (streq(p->property, property)) + goto set_prop; + } + + /* no match */ + if (!nulstr_contains(interfaces, interface)) + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + else + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property"); + + return bus_send_error_reply(c, message, &error, -EINVAL); + +set_prop: + if (!p->set) { + dbus_set_error_const(&error, DBUS_ERROR_PROPERTY_READ_ONLY, "Property read-only"); + return bus_send_error_reply(c, message, &error, -EINVAL); + } + + dbus_message_iter_recurse(&iter, &sub); + + sig = dbus_message_iter_get_signature(&sub); + if (!sig) + goto oom; + + if (!streq(sig, p->signature)) { + dbus_free(sig); + return bus_send_error_reply(c, message, NULL, -EINVAL); + } + + dbus_free(sig); + + r = p->set(&sub, property); + if (r < 0) { + if (r == -ENOMEM) + goto oom; + return bus_send_error_reply(c, message, NULL, r); + } + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + } else { + const char *interface = dbus_message_get_interface(message); + + if (!interface || !nulstr_contains(interfaces, interface)) { + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + return bus_send_error_reply(c, message, &error, -EINVAL); + } + } + + if (reply) { + if (!dbus_connection_send(c, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +int bus_property_append_string(DBusMessageIter *i, const char *property, void *data) { + const char *t = data; + + assert(i); + assert(property); + + if (!t) + t = ""; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_strv(DBusMessageIter *i, const char *property, void *data) { + char **t = data; + + assert(i); + assert(property); + + return bus_append_strv_iter(i, t); +} + +int bus_property_append_bool(DBusMessageIter *i, const char *property, void *data) { + bool *b = data; + dbus_bool_t db; + + assert(i); + assert(property); + assert(b); + + db = *b; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &db)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_tristate_false(DBusMessageIter *i, const char *property, void *data) { + int *b = data; + dbus_bool_t db; + + assert(i); + assert(property); + assert(b); + + db = *b > 0; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &db)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_uint64(DBusMessageIter *i, const char *property, void *data) { + assert(i); + assert(property); + assert(data); + + /* Let's ensure that usec_t is actually 64bit, and hence this + * function can be used for usec_t */ + assert_cc(sizeof(uint64_t) == sizeof(usec_t)); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, data)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_uint32(DBusMessageIter *i, const char *property, void *data) { + assert(i); + assert(property); + assert(data); + + /* Let's ensure that pid_t, mode_t, uid_t, gid_t are actually + * 32bit, and hence this function can be used for + * pid_t/mode_t/uid_t/gid_t */ + assert_cc(sizeof(uint32_t) == sizeof(pid_t)); + assert_cc(sizeof(uint32_t) == sizeof(mode_t)); + assert_cc(sizeof(uint32_t) == sizeof(unsigned)); + assert_cc(sizeof(uint32_t) == sizeof(uid_t)); + assert_cc(sizeof(uint32_t) == sizeof(gid_t)); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, data)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_int32(DBusMessageIter *i, const char *property, void *data) { + assert(i); + assert(property); + assert(data); + + assert_cc(sizeof(int32_t) == sizeof(int)); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, data)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_size(DBusMessageIter *i, const char *property, void *data) { + uint64_t u; + + assert(i); + assert(property); + assert(data); + + u = (uint64_t) *(size_t*) data; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_ul(DBusMessageIter *i, const char *property, void *data) { + uint64_t u; + + assert(i); + assert(property); + assert(data); + + u = (uint64_t) *(unsigned long*) data; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u)) + return -ENOMEM; + + return 0; +} + +int bus_property_append_long(DBusMessageIter *i, const char *property, void *data) { + int64_t l; + + assert(i); + assert(property); + assert(data); + + l = (int64_t) *(long*) data; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT64, &l)) + return -ENOMEM; + + return 0; +} + +const char *bus_errno_to_dbus(int error) { + + switch(error) { + + case -EINVAL: + return DBUS_ERROR_INVALID_ARGS; + + case -ENOMEM: + return DBUS_ERROR_NO_MEMORY; + + case -EPERM: + case -EACCES: + return DBUS_ERROR_ACCESS_DENIED; + + case -ESRCH: + return DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN; + + case -ENOENT: + return DBUS_ERROR_FILE_NOT_FOUND; + + case -EEXIST: + return DBUS_ERROR_FILE_EXISTS; + + case -ETIMEDOUT: + case -ETIME: + return DBUS_ERROR_TIMEOUT; + + case -EIO: + return DBUS_ERROR_IO_ERROR; + + case -ENETRESET: + case -ECONNABORTED: + case -ECONNRESET: + return DBUS_ERROR_DISCONNECTED; + } + + return DBUS_ERROR_FAILED; +} + +DBusHandlerResult bus_send_error_reply(DBusConnection *c, DBusMessage *message, DBusError *berror, int error) { + DBusMessage *reply = NULL; + const char *name, *text; + + if (berror && dbus_error_is_set(berror)) { + name = berror->name; + text = berror->message; + } else { + name = bus_errno_to_dbus(error); + text = strerror(-error); + } + + if (!(reply = dbus_message_new_error(message, name, text))) + goto oom; + + if (!dbus_connection_send(c, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + + if (berror) + dbus_error_free(berror); + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + if (berror) + dbus_error_free(berror); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +DBusMessage* bus_properties_changed_new(const char *path, const char *interface, const char *properties) { + DBusMessage *m; + DBusMessageIter iter, sub; + const char *i; + + assert(interface); + assert(properties); + + if (!(m = dbus_message_new_signal(path, "org.freedesktop.DBus.Properties", "PropertiesChanged"))) + goto oom; + + dbus_message_iter_init_append(m, &iter); + + /* We won't send any property values, since they might be + * large and sometimes not cheap to generated */ + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &sub) || + !dbus_message_iter_close_container(&iter, &sub) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) + goto oom; + + NULSTR_FOREACH(i, properties) + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &i)) + goto oom; + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + return m; + +oom: + if (m) + dbus_message_unref(m); + + return NULL; +} + +uint32_t bus_flags_to_events(DBusWatch *bus_watch) { + unsigned flags; + uint32_t events = 0; + + assert(bus_watch); + + /* no watch flags for disabled watches */ + if (!dbus_watch_get_enabled(bus_watch)) + return 0; + + flags = dbus_watch_get_flags(bus_watch); + + if (flags & DBUS_WATCH_READABLE) + events |= EPOLLIN; + if (flags & DBUS_WATCH_WRITABLE) + events |= EPOLLOUT; + + return events | EPOLLHUP | EPOLLERR; +} + +unsigned bus_events_to_flags(uint32_t events) { + unsigned flags = 0; + + if (events & EPOLLIN) + flags |= DBUS_WATCH_READABLE; + if (events & EPOLLOUT) + flags |= DBUS_WATCH_WRITABLE; + if (events & EPOLLHUP) + flags |= DBUS_WATCH_HANGUP; + if (events & EPOLLERR) + flags |= DBUS_WATCH_ERROR; + + return flags; +} + +int bus_parse_strv(DBusMessage *m, char ***_l) { + DBusMessageIter iter; + + assert(m); + assert(_l); + + if (!dbus_message_iter_init(m, &iter)) + return -EINVAL; + + return bus_parse_strv_iter(&iter, _l); +} + +int bus_parse_strv_iter(DBusMessageIter *iter, char ***_l) { + DBusMessageIter sub; + unsigned n = 0, i = 0; + char **l; + + assert(iter); + assert(_l); + + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_recurse(iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + n++; + dbus_message_iter_next(&sub); + } + + if (!(l = new(char*, n+1))) + return -ENOMEM; + + dbus_message_iter_recurse(iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *s; + + assert_se(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING); + dbus_message_iter_get_basic(&sub, &s); + + if (!(l[i++] = strdup(s))) { + strv_free(l); + return -ENOMEM; + } + + dbus_message_iter_next(&sub); + } + + assert(i == n); + l[i] = NULL; + + if (_l) + *_l = l; + + return 0; +} + +int bus_append_strv_iter(DBusMessageIter *iter, char **l) { + DBusMessageIter sub; + + assert(iter); + + if (!dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "s", &sub)) + return -ENOMEM; + + STRV_FOREACH(l, l) + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, l)) + return -ENOMEM; + + if (!dbus_message_iter_close_container(iter, &sub)) + return -ENOMEM; + + return 0; +} + +int bus_iter_get_basic_and_next(DBusMessageIter *iter, int type, void *data, bool next) { + + assert(iter); + assert(data); + + if (dbus_message_iter_get_arg_type(iter) != type) + return -EIO; + + dbus_message_iter_get_basic(iter, data); + + if (!dbus_message_iter_next(iter) != !next) + return -EIO; + + return 0; +} + +int generic_print_property(const char *name, DBusMessageIter *iter, bool all) { + assert(name); + assert(iter); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + dbus_message_iter_get_basic(iter, &s); + + if (all || !isempty(s)) + printf("%s=%s\n", name, s); + + return 1; + } + + case DBUS_TYPE_BOOLEAN: { + dbus_bool_t b; + + dbus_message_iter_get_basic(iter, &b); + printf("%s=%s\n", name, yes_no(b)); + + return 1; + } + + case DBUS_TYPE_UINT64: { + uint64_t u; + dbus_message_iter_get_basic(iter, &u); + + /* Yes, heuristics! But we can change this check + * should it turn out to not be sufficient */ + + if (endswith(name, "Timestamp")) { + char timestamp[FORMAT_TIMESTAMP_MAX], *t; + + t = format_timestamp(timestamp, sizeof(timestamp), u); + if (t || all) + printf("%s=%s\n", name, strempty(t)); + + } else if (strstr(name, "USec")) { + char timespan[FORMAT_TIMESPAN_MAX]; + + printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u)); + } else + printf("%s=%llu\n", name, (unsigned long long) u); + + return 1; + } + + case DBUS_TYPE_UINT32: { + uint32_t u; + dbus_message_iter_get_basic(iter, &u); + + if (strstr(name, "UMask") || strstr(name, "Mode")) + printf("%s=%04o\n", name, u); + else + printf("%s=%u\n", name, (unsigned) u); + + return 1; + } + + case DBUS_TYPE_INT32: { + int32_t i; + dbus_message_iter_get_basic(iter, &i); + + printf("%s=%i\n", name, (int) i); + return 1; + } + + case DBUS_TYPE_DOUBLE: { + double d; + dbus_message_iter_get_basic(iter, &d); + + printf("%s=%g\n", name, d); + return 1; + } + + case DBUS_TYPE_ARRAY: + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING) { + DBusMessageIter sub; + bool space = false; + + dbus_message_iter_recurse(iter, &sub); + if (all || + dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + printf("%s=", name); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *s; + + assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING); + dbus_message_iter_get_basic(&sub, &s); + printf("%s%s", space ? " " : "", s); + + space = true; + dbus_message_iter_next(&sub); + } + + puts(""); + } + + return 1; + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_BYTE) { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + if (all || + dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + printf("%s=", name); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + uint8_t u; + + assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_BYTE); + dbus_message_iter_get_basic(&sub, &u); + printf("%02x", u); + + dbus_message_iter_next(&sub); + } + + puts(""); + } + + return 1; + } + + break; + } + + return 0; +} + +static void release_name_pending_cb(DBusPendingCall *pending, void *userdata) { + DBusMessage *reply; + DBusConnection *bus = userdata; + + assert_se(reply = dbus_pending_call_steal_reply(pending)); + dbus_message_unref(reply); + + dbus_connection_close(bus); +} + +void bus_async_unregister_and_exit(DBusConnection *bus, const char *name) { + DBusMessage *m = NULL; + DBusPendingCall *pending = NULL; + + assert(bus); + + /* We unregister the name here, but we continue to process + * requests, until we get the response for it, so that all + * requests are guaranteed to be processed. */ + + m = dbus_message_new_method_call( + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "ReleaseName"); + if (!m) + goto oom; + + if (!dbus_message_append_args( + m, + DBUS_TYPE_STRING, + &name, + DBUS_TYPE_INVALID)) + goto oom; + + if (!dbus_connection_send_with_reply(bus, m, &pending, -1)) + goto oom; + + if (!dbus_pending_call_set_notify(pending, release_name_pending_cb, bus, NULL)) + goto oom; + + dbus_message_unref(m); + dbus_pending_call_unref(pending); + + return; + +oom: + log_error("Out of memory"); + + if (pending) { + dbus_pending_call_cancel(pending); + dbus_pending_call_unref(pending); + } + + if (m) + dbus_message_unref(m); +} + +DBusHandlerResult bus_exit_idle_filter(DBusConnection *bus, DBusMessage *m, void *userdata) { + usec_t *remain_until = userdata; + + assert(bus); + assert(m); + assert(remain_until); + + /* Everytime we get a new message we reset out timeout */ + *remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC; + + if (dbus_message_is_signal(m, DBUS_INTERFACE_LOCAL, "Disconnected")) + dbus_connection_close(bus); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} diff --git a/src/dbus-common.h b/src/dbus-common.h new file mode 100644 index 0000000..15811a7 --- /dev/null +++ b/src/dbus-common.h @@ -0,0 +1,183 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbuscommonhfoo +#define foodbuscommonhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#ifndef DBUS_ERROR_UNKNOWN_OBJECT +#define DBUS_ERROR_UNKNOWN_OBJECT "org.freedesktop.DBus.Error.UnknownObject" +#endif + +#ifndef DBUS_ERROR_UNKNOWN_INTERFACE +#define DBUS_ERROR_UNKNOWN_INTERFACE "org.freedesktop.DBus.Error.UnknownInterface" +#endif + +#ifndef DBUS_ERROR_UNKNOWN_PROPERTY +#define DBUS_ERROR_UNKNOWN_PROPERTY "org.freedesktop.DBus.Error.UnknownProperty" +#endif + +#ifndef DBUS_ERROR_PROPERTY_READ_ONLY +#define DBUS_ERROR_PROPERTY_READ_ONLY "org.freedesktop.DBus.Error.PropertyReadOnly" +#endif + +#define BUS_PROPERTIES_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_INTROSPECTABLE_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_PEER_INTERFACE \ + "\n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + "\n" + +#define BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.DBus.Properties\0" \ + "org.freedesktop.DBus.Introspectable\0" \ + "org.freedesktop.DBus.Peer\0" + +int bus_check_peercred(DBusConnection *c); + +int bus_connect(DBusBusType t, DBusConnection **_bus, bool *private_bus, DBusError *error); + +int bus_connect_system_ssh(const char *user, const char *host, DBusConnection **_bus, DBusError *error); +int bus_connect_system_polkit(DBusConnection **_bus, DBusError *error); + +const char *bus_error_message(const DBusError *error); + +typedef int (*BusPropertyCallback)(DBusMessageIter *iter, const char *property, void *data); +typedef int (*BusPropertySetCallback)(DBusMessageIter *iter, const char *property); + +typedef struct BusProperty { + const char *property; /* name of the property */ + BusPropertyCallback append; /* Function that is called to serialize this property */ + const char *signature; + const uint16_t offset; /* Offset from BusBoundProperties::base address to the property data. + * uint16_t is sufficient, because we have no structs too big. + * -Werror=overflow will catch it if this does not hold. */ + bool indirect; /* data is indirect, ie. not base+offset, but *(base+offset) */ + BusPropertySetCallback set; /* Optional: Function that is called to set this property */ +} BusProperty; + +typedef struct BusBoundProperties { + const char *interface; /* interface of the properties */ + const BusProperty *properties; /* array of properties, ended by a NULL-filled element */ + const void *const base; /* base pointer to which the offset must be added to reach data */ +} BusBoundProperties; + +DBusHandlerResult bus_send_error_reply( + DBusConnection *c, + DBusMessage *message, + DBusError *bus_error, + int error); + +DBusHandlerResult bus_default_message_handler( + DBusConnection *c, + DBusMessage *message, + const char *introspection, + const char *interfaces, + const BusBoundProperties *bound_properties); + +int bus_property_append_string(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_strv(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_bool(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_tristate_false(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_int32(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_uint32(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_uint64(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_size(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_ul(DBusMessageIter *i, const char *property, void *data); +int bus_property_append_long(DBusMessageIter *i, const char *property, void *data); + +#define bus_property_append_int bus_property_append_int32 +#define bus_property_append_pid bus_property_append_uint32 +#define bus_property_append_uid bus_property_append_uint32 +#define bus_property_append_gid bus_property_append_uint32 +#define bus_property_append_mode bus_property_append_uint32 +#define bus_property_append_unsigned bus_property_append_uint32 +#define bus_property_append_usec bus_property_append_uint64 + +#define DEFINE_BUS_PROPERTY_APPEND_ENUM(function,name,type) \ + int function(DBusMessageIter *i, const char *property, void *data) { \ + const char *value; \ + type *field = data; \ + \ + assert(i); \ + assert(property); \ + \ + value = name##_to_string(*field); \ + \ + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &value)) \ + return -ENOMEM; \ + \ + return 0; \ + } + +const char *bus_errno_to_dbus(int error); + +DBusMessage* bus_properties_changed_new(const char *path, const char *interface, const char *properties); + +uint32_t bus_flags_to_events(DBusWatch *bus_watch); +unsigned bus_events_to_flags(uint32_t events); + +int bus_parse_strv(DBusMessage *m, char ***_l); +int bus_parse_strv_iter(DBusMessageIter *iter, char ***_l); + +int bus_append_strv_iter(DBusMessageIter *iter, char **l); + +int bus_iter_get_basic_and_next(DBusMessageIter *iter, int type, void *data, bool next); + +int generic_print_property(const char *name, DBusMessageIter *iter, bool all); + +void bus_async_unregister_and_exit(DBusConnection *bus, const char *name); + +DBusHandlerResult bus_exit_idle_filter(DBusConnection *bus, DBusMessage *m, void *userdata); + +#endif diff --git a/src/dbus-device.c b/src/dbus-device.c new file mode 100644 index 0000000..b39fb9d --- /dev/null +++ b/src/dbus-device.c @@ -0,0 +1,65 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "dbus-unit.h" +#include "dbus-device.h" +#include "dbus-common.h" + +#define BUS_DEVICE_INTERFACE \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_DEVICE_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Device\0" + +const char bus_device_interface[] _introspect_("Device") = BUS_DEVICE_INTERFACE; + +const char bus_device_invalidating_properties[] = + "SysFSPath\0"; + +static const BusProperty bus_device_properties[] = { + { "SysFSPath", bus_property_append_string, "s", offsetof(Device, sysfs), true }, + { NULL, } +}; + + +DBusHandlerResult bus_device_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Device *d = DEVICE(u); + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Device", bus_device_properties, d }, + { NULL, } + }; + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/dbus-device.h b/src/dbus-device.h new file mode 100644 index 0000000..fba270b --- /dev/null +++ b/src/dbus-device.h @@ -0,0 +1,34 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbusdevicehfoo +#define foodbusdevicehfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_device_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_device_interface[]; +extern const char bus_device_invalidating_properties[]; + +#endif diff --git a/src/dbus-execute.c b/src/dbus-execute.c new file mode 100644 index 0000000..1fd2b21 --- /dev/null +++ b/src/dbus-execute.c @@ -0,0 +1,422 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "dbus-execute.h" +#include "missing.h" +#include "ioprio.h" +#include "strv.h" +#include "dbus-common.h" + +DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_kill_mode, kill_mode, KillMode); + +DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_input, exec_input, ExecInput); +DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_output, exec_output, ExecOutput); + +int bus_execute_append_env_files(DBusMessageIter *i, const char *property, void *data) { + char **env_files = data, **j; + DBusMessageIter sub, sub2; + + assert(i); + assert(property); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sb)", &sub)) + return -ENOMEM; + + STRV_FOREACH(j, env_files) { + dbus_bool_t b = false; + char *fn = *j; + + if (fn[0] == '-') { + b = true; + fn++; + } + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &fn) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_BOOLEAN, &b) || + !dbus_message_iter_close_container(&sub, &sub2)) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_oom_score_adjust(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + int32_t n; + + assert(i); + assert(property); + assert(c); + + if (c->oom_score_adjust_set) + n = c->oom_score_adjust; + else { + char *t; + + n = 0; + if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0) { + safe_atoi(t, &n); + free(t); + } else if (read_one_line_file("/proc/self/oom_adj", &t) >= 0) { + safe_atoi(t, &n); + free(t); + + if (n == OOM_ADJUST_MAX) + n = OOM_SCORE_ADJ_MAX; + else + n = (n * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE; + } + } + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_nice(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + int32_t n; + + assert(i); + assert(property); + assert(c); + + if (c->nice_set) + n = c->nice; + else + n = getpriority(PRIO_PROCESS, 0); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_ioprio(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + int32_t n; + + assert(i); + assert(property); + assert(c); + + if (c->ioprio_set) + n = c->ioprio; + else + n = ioprio_get(IOPRIO_WHO_PROCESS, 0); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_cpu_sched_policy(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + int32_t n; + + assert(i); + assert(property); + assert(c); + + if (c->cpu_sched_set) + n = c->cpu_sched_policy; + else + n = sched_getscheduler(0); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_cpu_sched_priority(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + int32_t n; + + assert(i); + assert(property); + assert(c); + + if (c->cpu_sched_set) + n = c->cpu_sched_priority; + else { + struct sched_param p; + n = 0; + + zero(p); + if (sched_getparam(0, &p) >= 0) + n = p.sched_priority; + } + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_affinity(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + dbus_bool_t b; + DBusMessageIter sub; + + assert(i); + assert(property); + assert(c); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "y", &sub)) + return -ENOMEM; + + if (c->cpuset) + b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus)); + else + b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &c->cpuset, 0); + + if (!b) + return -ENOMEM; + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_timer_slack_nsec(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + uint64_t u; + + assert(i); + assert(property); + assert(c); + + if (c->timer_slack_nsec_set) + u = (uint64_t) c->timer_slack_nsec; + else + u = (uint64_t) prctl(PR_GET_TIMERSLACK); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_capability_bs(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + uint64_t normal, inverted; + + assert(i); + assert(property); + assert(c); + + /* We store this negated internally, to match the kernel, but + * we expose it normalized. */ + + normal = *(uint64_t*) data; + inverted = ~normal; + + return bus_property_append_uint64(i, property, &inverted); +} + +int bus_execute_append_capabilities(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + char *t = NULL; + const char *s; + dbus_bool_t b; + + assert(i); + assert(property); + assert(c); + + if (c->capabilities) + s = t = cap_to_text(c->capabilities, NULL); + else + s = ""; + + if (!s) + return -ENOMEM; + + b = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &s); + + if (t) + cap_free(t); + + if (!b) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_rlimits(DBusMessageIter *i, const char *property, void *data) { + ExecContext *c = data; + int r; + uint64_t u; + + assert(i); + assert(property); + assert(c); + + assert_se((r = rlimit_from_string(property)) >= 0); + + if (c->rlimit[r]) + u = (uint64_t) c->rlimit[r]->rlim_max; + else { + struct rlimit rl; + + zero(rl); + getrlimit(r, &rl); + + u = (uint64_t) rl.rlim_max; + } + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u)) + return -ENOMEM; + + return 0; +} + +int bus_execute_append_command(DBusMessageIter *i, const char *property, void *data) { + ExecCommand *c = data; + DBusMessageIter sub, sub2, sub3; + + assert(i); + assert(property); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sasbttttuii)", &sub)) + return -ENOMEM; + + LIST_FOREACH(command, c, c) { + char **l; + uint32_t pid; + int32_t code, status; + dbus_bool_t b; + + if (!c->path) + continue; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &c->path) || + !dbus_message_iter_open_container(&sub2, DBUS_TYPE_ARRAY, "s", &sub3)) + return -ENOMEM; + + STRV_FOREACH(l, c->argv) + if (!dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, l)) + return -ENOMEM; + + pid = (uint32_t) c->exec_status.pid; + code = (int32_t) c->exec_status.code; + status = (int32_t) c->exec_status.status; + + b = !!c->ignore; + + if (!dbus_message_iter_close_container(&sub2, &sub3) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_BOOLEAN, &b) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.start_timestamp.realtime) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.start_timestamp.monotonic) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.exit_timestamp.realtime) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.exit_timestamp.monotonic) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &pid) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_INT32, &code) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_INT32, &status)) + return -ENOMEM; + + if (!dbus_message_iter_close_container(&sub, &sub2)) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +const BusProperty bus_exec_context_properties[] = { + { "Environment", bus_property_append_strv, "as", offsetof(ExecContext, environment), true }, + { "EnvironmentFiles", bus_execute_append_env_files, "a(sb)", offsetof(ExecContext, environment_files), true }, + { "UMask", bus_property_append_mode, "u", offsetof(ExecContext, umask) }, + { "LimitCPU", bus_execute_append_rlimits, "t", 0 }, + { "LimitFSIZE", bus_execute_append_rlimits, "t", 0 }, + { "LimitDATA", bus_execute_append_rlimits, "t", 0 }, + { "LimitSTACK", bus_execute_append_rlimits, "t", 0 }, + { "LimitCORE", bus_execute_append_rlimits, "t", 0 }, + { "LimitRSS", bus_execute_append_rlimits, "t", 0 }, + { "LimitNOFILE", bus_execute_append_rlimits, "t", 0 }, + { "LimitAS", bus_execute_append_rlimits, "t", 0 }, + { "LimitNPROC", bus_execute_append_rlimits, "t", 0 }, + { "LimitMEMLOCK", bus_execute_append_rlimits, "t", 0 }, + { "LimitLOCKS", bus_execute_append_rlimits, "t", 0 }, + { "LimitSIGPENDING", bus_execute_append_rlimits, "t", 0 }, + { "LimitMSGQUEUE", bus_execute_append_rlimits, "t", 0 }, + { "LimitNICE", bus_execute_append_rlimits, "t", 0 }, + { "LimitRTPRIO", bus_execute_append_rlimits, "t", 0 }, + { "LimitRTTIME", bus_execute_append_rlimits, "t", 0 }, + { "WorkingDirectory", bus_property_append_string, "s", offsetof(ExecContext, working_directory), true }, + { "RootDirectory", bus_property_append_string, "s", offsetof(ExecContext, root_directory), true }, + { "OOMScoreAdjust", bus_execute_append_oom_score_adjust, "i", 0 }, + { "Nice", bus_execute_append_nice, "i", 0 }, + { "IOScheduling", bus_execute_append_ioprio, "i", 0 }, + { "CPUSchedulingPolicy", bus_execute_append_cpu_sched_policy, "i", 0 }, + { "CPUSchedulingPriority", bus_execute_append_cpu_sched_priority, "i", 0 }, + { "CPUAffinity", bus_execute_append_affinity, "ay", 0 }, + { "TimerSlackNSec", bus_execute_append_timer_slack_nsec, "t", 0 }, + { "CPUSchedulingResetOnFork", bus_property_append_bool, "b", offsetof(ExecContext, cpu_sched_reset_on_fork) }, + { "NonBlocking", bus_property_append_bool, "b", offsetof(ExecContext, non_blocking) }, + { "StandardInput", bus_execute_append_input, "s", offsetof(ExecContext, std_input) }, + { "StandardOutput", bus_execute_append_output, "s", offsetof(ExecContext, std_output) }, + { "StandardError", bus_execute_append_output, "s", offsetof(ExecContext, std_error) }, + { "TTYPath", bus_property_append_string, "s", offsetof(ExecContext, tty_path), true }, + { "TTYReset", bus_property_append_bool, "b", offsetof(ExecContext, tty_reset) }, + { "TTYVHangup", bus_property_append_bool, "b", offsetof(ExecContext, tty_vhangup) }, + { "TTYVTDisallocate", bus_property_append_bool, "b", offsetof(ExecContext, tty_vt_disallocate) }, + { "SyslogPriority", bus_property_append_int, "i", offsetof(ExecContext, syslog_priority) }, + { "SyslogIdentifier", bus_property_append_string, "s", offsetof(ExecContext, syslog_identifier), true }, + { "SyslogLevelPrefix", bus_property_append_bool, "b", offsetof(ExecContext, syslog_level_prefix) }, + { "Capabilities", bus_execute_append_capabilities, "s", 0 }, + { "SecureBits", bus_property_append_int, "i", offsetof(ExecContext, secure_bits) }, + { "CapabilityBoundingSet", bus_execute_append_capability_bs, "t", offsetof(ExecContext, capability_bounding_set_drop) }, + { "User", bus_property_append_string, "s", offsetof(ExecContext, user), true }, + { "Group", bus_property_append_string, "s", offsetof(ExecContext, group), true }, + { "SupplementaryGroups", bus_property_append_strv, "as", offsetof(ExecContext, supplementary_groups), true }, + { "TCPWrapName", bus_property_append_string, "s", offsetof(ExecContext, tcpwrap_name), true }, + { "PAMName", bus_property_append_string, "s", offsetof(ExecContext, pam_name), true }, + { "ReadWriteDirectories", bus_property_append_strv, "as", offsetof(ExecContext, read_write_dirs), true }, + { "ReadOnlyDirectories", bus_property_append_strv, "as", offsetof(ExecContext, read_only_dirs), true }, + { "InaccessibleDirectories", bus_property_append_strv, "as", offsetof(ExecContext, inaccessible_dirs), true }, + { "MountFlags", bus_property_append_ul, "t", offsetof(ExecContext, mount_flags) }, + { "PrivateTmp", bus_property_append_bool, "b", offsetof(ExecContext, private_tmp) }, + { "PrivateNetwork", bus_property_append_bool, "b", offsetof(ExecContext, private_network) }, + { "SameProcessGroup", bus_property_append_bool, "b", offsetof(ExecContext, same_pgrp) }, + { "KillMode", bus_execute_append_kill_mode, "s", offsetof(ExecContext, kill_mode) }, + { "KillSignal", bus_property_append_int, "i", offsetof(ExecContext, kill_signal) }, + { "UtmpIdentifier", bus_property_append_string, "s", offsetof(ExecContext, utmp_id), true }, + { "ControlGroupModify", bus_property_append_bool, "b", offsetof(ExecContext, control_group_modify) }, + { "ControlGroupPersistent", bus_property_append_tristate_false, "b", offsetof(ExecContext, control_group_persistent) }, + { "IgnoreSIGPIPE", bus_property_append_bool, "b", offsetof(ExecContext, ignore_sigpipe ) }, + { NULL, } +}; diff --git a/src/dbus-execute.h b/src/dbus-execute.h new file mode 100644 index 0000000..03cd69d --- /dev/null +++ b/src/dbus-execute.h @@ -0,0 +1,125 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbusexecutehfoo +#define foodbusexecutehfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "manager.h" +#include "dbus-common.h" + +#define BUS_EXEC_STATUS_INTERFACE(prefix) \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_EXEC_CONTEXT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_EXEC_COMMAND_INTERFACE(name) \ + " \n" + +extern const BusProperty bus_exec_context_properties[]; + +#define BUS_EXEC_COMMAND_PROPERTY(name, command, indirect) \ + { name, bus_execute_append_command, "a(sasbttttuii)", (command), (indirect), NULL } + +int bus_execute_append_output(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_input(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_oom_score_adjust(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_nice(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_ioprio(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_cpu_sched_policy(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_cpu_sched_priority(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_affinity(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_timer_slack_nsec(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_capabilities(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_capability_bs(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_rlimits(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_command(DBusMessageIter *u, const char *property, void *data); +int bus_execute_append_kill_mode(DBusMessageIter *i, const char *property, void *data); +int bus_execute_append_env_files(DBusMessageIter *i, const char *property, void *data); + +#endif diff --git a/src/dbus-job.c b/src/dbus-job.c new file mode 100644 index 0000000..ab6d610 --- /dev/null +++ b/src/dbus-job.c @@ -0,0 +1,354 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "dbus.h" +#include "log.h" +#include "dbus-job.h" +#include "dbus-common.h" + +#define BUS_JOB_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_JOB_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +const char bus_job_interface[] _introspect_("Job") = BUS_JOB_INTERFACE; + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.systemd1.Job\0" + +#define INVALIDATING_PROPERTIES \ + "State\0" + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_job_append_state, job_state, JobState); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_job_append_type, job_type, JobType); + +static int bus_job_append_unit(DBusMessageIter *i, const char *property, void *data) { + Job *j = data; + DBusMessageIter sub; + char *p; + + assert(i); + assert(property); + assert(j); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) + return -ENOMEM; + + if (!(p = unit_dbus_path(j->unit))) + return -ENOMEM; + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &j->unit->id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static const BusProperty bus_job_properties[] = { + { "Id", bus_property_append_uint32, "u", offsetof(Job, id) }, + { "State", bus_job_append_state, "s", offsetof(Job, state) }, + { "JobType", bus_job_append_type, "s", offsetof(Job, type) }, + { "Unit", bus_job_append_unit, "(so)", 0 }, + { NULL, } +}; + +static DBusHandlerResult bus_job_message_dispatch(Job *j, DBusConnection *connection, DBusMessage *message) { + DBusMessage *reply = NULL; + + if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Job", "Cancel")) { + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + job_finish_and_invalidate(j, JOB_CANCELED); + + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Job", bus_job_properties, j }, + { NULL, } + }; + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + } + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBusMessage *message, void *data) { + Manager *m = data; + Job *j; + int r; + DBusMessage *reply; + + assert(connection); + assert(message); + assert(m); + + if (streq(dbus_message_get_path(message), "/org/freedesktop/systemd1/job")) { + /* Be nice to gdbus and return introspection data for our mid-level paths */ + + if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) { + char *introspection = NULL; + FILE *f; + Iterator i; + size_t size; + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + /* We roll our own introspection code here, instead of + * relying on bus_default_message_handler() because we + * need to generate our introspection string + * dynamically. */ + + if (!(f = open_memstream(&introspection, &size))) + goto oom; + + fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + "\n", f); + + fputs(BUS_INTROSPECTABLE_INTERFACE, f); + fputs(BUS_PEER_INTERFACE, f); + + HASHMAP_FOREACH(j, m->jobs, i) + fprintf(f, "", (unsigned long) j->id); + + fputs("\n", f); + + if (ferror(f)) { + fclose(f); + free(introspection); + goto oom; + } + + fclose(f); + + if (!introspection) + goto oom; + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) { + free(introspection); + goto oom; + } + + free(introspection); + + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if ((r = manager_get_job_from_dbus_path(m, dbus_message_get_path(message), &j)) < 0) { + + if (r == -ENOMEM) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (r == -ENOENT) { + DBusError e; + + dbus_error_init(&e); + dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown job"); + return bus_send_error_reply(connection, message, &e, r); + } + + return bus_send_error_reply(connection, message, NULL, r); + } + + return bus_job_message_dispatch(j, connection, message); + +oom: + if (reply) + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +const DBusObjectPathVTable bus_job_vtable = { + .message_function = bus_job_message_handler +}; + +static int job_send_message(Job *j, DBusMessage *m) { + int r; + + assert(j); + assert(m); + + if (bus_has_subscriber(j->manager)) { + if ((r = bus_broadcast(j->manager, m)) < 0) + return r; + + } else if (j->bus_client) { + /* If nobody is subscribed, we just send the message + * to the client which created the job */ + + assert(j->bus); + + if (!dbus_message_set_destination(m, j->bus_client)) + return -ENOMEM; + + if (!dbus_connection_send(j->bus, m, NULL)) + return -ENOMEM; + } + + return 0; +} + +void bus_job_send_change_signal(Job *j) { + char *p = NULL; + DBusMessage *m = NULL; + + assert(j); + + if (j->in_dbus_queue) { + LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j); + j->in_dbus_queue = false; + } + + if (!bus_has_subscriber(j->manager) && !j->bus_client) { + j->sent_dbus_new_signal = true; + return; + } + + if (!(p = job_dbus_path(j))) + goto oom; + + if (j->sent_dbus_new_signal) { + /* Send a properties changed signal */ + + if (!(m = bus_properties_changed_new(p, "org.freedesktop.systemd1.Job", INVALIDATING_PROPERTIES))) + goto oom; + + } else { + /* Send a new signal */ + + if (!(m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "JobNew"))) + goto oom; + + if (!dbus_message_append_args(m, + DBUS_TYPE_UINT32, &j->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + goto oom; + } + + if (job_send_message(j, m) < 0) + goto oom; + + free(p); + dbus_message_unref(m); + + j->sent_dbus_new_signal = true; + + return; + +oom: + free(p); + + if (m) + dbus_message_unref(m); + + log_error("Failed to allocate job change signal."); +} + +void bus_job_send_removed_signal(Job *j) { + char *p = NULL; + DBusMessage *m = NULL; + const char *r; + + assert(j); + + if (!bus_has_subscriber(j->manager) && !j->bus_client) + return; + + if (!j->sent_dbus_new_signal) + bus_job_send_change_signal(j); + + if (!(p = job_dbus_path(j))) + goto oom; + + if (!(m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "JobRemoved"))) + goto oom; + + r = job_result_to_string(j->result); + + if (!dbus_message_append_args(m, + DBUS_TYPE_UINT32, &j->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_STRING, &r, + DBUS_TYPE_INVALID)) + goto oom; + + if (job_send_message(j, m) < 0) + goto oom; + + free(p); + dbus_message_unref(m); + + return; + +oom: + free(p); + + if (m) + dbus_message_unref(m); + + log_error("Failed to allocate job remove signal."); +} diff --git a/src/dbus-job.h b/src/dbus-job.h new file mode 100644 index 0000000..103c2ff --- /dev/null +++ b/src/dbus-job.h @@ -0,0 +1,36 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbusjobhfoo +#define foodbusjobhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "job.h" + +void bus_job_send_change_signal(Job *j); +void bus_job_send_removed_signal(Job *j); + +extern const DBusObjectPathVTable bus_job_vtable; + +extern const char bus_job_interface[]; + +#endif diff --git a/src/dbus-loop.c b/src/dbus-loop.c new file mode 100644 index 0000000..8eb1d17 --- /dev/null +++ b/src/dbus-loop.c @@ -0,0 +1,263 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "dbus-loop.h" +#include "dbus-common.h" +#include "util.h" + +/* Minimal implementation of the dbus loop which integrates all dbus + * events into a single epoll fd which we can triviall integrate with + * other loops. Note that this is not used in the main systemd daemon + * since we run a more elaborate mainloop there. */ + +typedef struct EpollData { + int fd; + void *object; + bool is_timeout:1; + bool fd_is_dupped:1; +} EpollData; + +static dbus_bool_t add_watch(DBusWatch *watch, void *data) { + EpollData *e; + struct epoll_event ev; + + assert(watch); + + e = new0(EpollData, 1); + if (!e) + return FALSE; + + e->fd = dbus_watch_get_unix_fd(watch); + e->object = watch; + e->is_timeout = false; + + zero(ev); + ev.events = bus_flags_to_events(watch); + ev.data.ptr = e; + + if (epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_ADD, e->fd, &ev) < 0) { + + if (errno != EEXIST) { + free(e); + return FALSE; + } + + /* Hmm, bloody D-Bus creates multiple watches on the + * same fd. epoll() does not like that. As a dirty + * hack we simply dup() the fd and hence get a second + * one we can safely add to the epoll(). */ + + e->fd = dup(e->fd); + if (e->fd < 0) { + free(e); + return FALSE; + } + + if (epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_ADD, e->fd, &ev) < 0) { + close_nointr_nofail(e->fd); + free(e); + return FALSE; + } + + e->fd_is_dupped = true; + } + + dbus_watch_set_data(watch, e, NULL); + + return TRUE; +} + +static void remove_watch(DBusWatch *watch, void *data) { + EpollData *e; + + assert(watch); + + e = dbus_watch_get_data(watch); + if (!e) + return; + + assert_se(epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_DEL, e->fd, NULL) >= 0); + + if (e->fd_is_dupped) + close_nointr_nofail(e->fd); + + free(e); +} + +static void toggle_watch(DBusWatch *watch, void *data) { + EpollData *e; + struct epoll_event ev; + + assert(watch); + + e = dbus_watch_get_data(watch); + if (!e) + return; + + zero(ev); + ev.events = bus_flags_to_events(watch); + ev.data.ptr = e; + + assert_se(epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_MOD, e->fd, &ev) == 0); +} + +static int timeout_arm(EpollData *e) { + struct itimerspec its; + + assert(e); + assert(e->is_timeout); + + zero(its); + + if (dbus_timeout_get_enabled(e->object)) { + timespec_store(&its.it_value, dbus_timeout_get_interval(e->object) * USEC_PER_MSEC); + its.it_interval = its.it_value; + } + + if (timerfd_settime(e->fd, 0, &its, NULL) < 0) + return -errno; + + return 0; +} + +static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) { + EpollData *e; + struct epoll_event ev; + + assert(timeout); + + e = new0(EpollData, 1); + if (!e) + return FALSE; + + e->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC); + if (e->fd < 0) + goto fail; + + e->object = timeout; + e->is_timeout = true; + + if (timeout_arm(e) < 0) + goto fail; + + zero(ev); + ev.events = EPOLLIN; + ev.data.ptr = e; + + if (epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_ADD, e->fd, &ev) < 0) + goto fail; + + dbus_timeout_set_data(timeout, e, NULL); + + return TRUE; + +fail: + if (e->fd >= 0) + close_nointr_nofail(e->fd); + + free(e); + return FALSE; +} + +static void remove_timeout(DBusTimeout *timeout, void *data) { + EpollData *e; + + assert(timeout); + + e = dbus_timeout_get_data(timeout); + if (!e) + return; + + assert_se(epoll_ctl(PTR_TO_INT(data), EPOLL_CTL_DEL, e->fd, NULL) >= 0); + close_nointr_nofail(e->fd); + free(e); +} + +static void toggle_timeout(DBusTimeout *timeout, void *data) { + EpollData *e; + int r; + + assert(timeout); + + e = dbus_timeout_get_data(timeout); + if (!e) + return; + + r = timeout_arm(e); + if (r < 0) + log_error("Failed to rearm timer: %s", strerror(-r)); +} + +int bus_loop_open(DBusConnection *c) { + int fd; + + assert(c); + + fd = epoll_create1(EPOLL_CLOEXEC); + if (fd < 0) + return -errno; + + if (!dbus_connection_set_watch_functions(c, add_watch, remove_watch, toggle_watch, INT_TO_PTR(fd), NULL) || + !dbus_connection_set_timeout_functions(c, add_timeout, remove_timeout, toggle_timeout, INT_TO_PTR(fd), NULL)) { + close_nointr_nofail(fd); + return -ENOMEM; + } + + return fd; +} + +int bus_loop_dispatch(int fd) { + int n; + struct epoll_event event; + EpollData *d; + + assert(fd >= 0); + + zero(event); + + n = epoll_wait(fd, &event, 1, 0); + if (n < 0) + return errno == EAGAIN || errno == EINTR ? 0 : -errno; + + assert_se(d = event.data.ptr); + + if (d->is_timeout) { + DBusTimeout *t = d->object; + + if (dbus_timeout_get_enabled(t)) + dbus_timeout_handle(t); + } else { + DBusWatch *w = d->object; + + if (dbus_watch_get_enabled(w)) + dbus_watch_handle(w, bus_events_to_flags(event.events)); + } + + return 0; +} diff --git a/src/dbus-loop.h b/src/dbus-loop.h new file mode 100644 index 0000000..0bbdfe5 --- /dev/null +++ b/src/dbus-loop.h @@ -0,0 +1,30 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbusloophfoo +#define foodbusloophfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +int bus_loop_open(DBusConnection *c); +int bus_loop_dispatch(int fd); + +#endif diff --git a/src/dbus-manager.c b/src/dbus-manager.c new file mode 100644 index 0000000..6d272cb --- /dev/null +++ b/src/dbus-manager.c @@ -0,0 +1,1537 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "dbus.h" +#include "log.h" +#include "dbus-manager.h" +#include "strv.h" +#include "bus-errors.h" +#include "build.h" +#include "dbus-common.h" +#include "install.h" + +#define BUS_MANAGER_INTERFACE_BEGIN \ + " \n" + +#define BUS_MANAGER_INTERFACE_METHODS \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_MANAGER_INTERFACE_SIGNALS \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " " \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " " \ + " \n" + +#define BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#ifdef HAVE_SYSV_COMPAT +#define BUS_MANAGER_INTERFACE_PROPERTIES_SYSV \ + " \n" \ + " \n" \ + " \n" +#else +#define BUS_MANAGER_INTERFACE_PROPERTIES_SYSV +#endif + +#define BUS_MANAGER_INTERFACE_END \ + " \n" + +#define BUS_MANAGER_INTERFACE \ + BUS_MANAGER_INTERFACE_BEGIN \ + BUS_MANAGER_INTERFACE_METHODS \ + BUS_MANAGER_INTERFACE_SIGNALS \ + BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL \ + BUS_MANAGER_INTERFACE_PROPERTIES_SYSV \ + BUS_MANAGER_INTERFACE_END + +#define INTROSPECTION_BEGIN \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_MANAGER_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE + +#define INTROSPECTION_END \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.systemd1.Manager\0" + +const char bus_manager_interface[] _introspect_("Manager") = BUS_MANAGER_INTERFACE; + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_running_as, manager_running_as, ManagerRunningAs); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_exec_output, exec_output, ExecOutput); + +static int bus_manager_append_tainted(DBusMessageIter *i, const char *property, void *data) { + const char *t; + Manager *m = data; + char buf[LINE_MAX] = "", *e = buf, *p = NULL; + + assert(i); + assert(property); + assert(m); + + if (m->taint_usr) + e = stpcpy(e, "usr-separate-fs "); + + if (readlink_malloc("/etc/mtab", &p) < 0) + e = stpcpy(e, "etc-mtab-not-symlink "); + else + free(p); + + if (access("/proc/cgroups", F_OK) < 0) + stpcpy(e, "cgroups-missing "); + + t = strstrip(buf); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_append_log_target(DBusMessageIter *i, const char *property, void *data) { + const char *t; + + assert(i); + assert(property); + + t = log_target_to_string(log_get_target()); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_set_log_target(DBusMessageIter *i, const char *property) { + const char *t; + + assert(i); + assert(property); + + dbus_message_iter_get_basic(i, &t); + + return log_set_target_from_string(t); +} + +static int bus_manager_append_log_level(DBusMessageIter *i, const char *property, void *data) { + const char *t; + + assert(i); + assert(property); + + t = log_level_to_string(log_get_max_level()); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_set_log_level(DBusMessageIter *i, const char *property) { + const char *t; + + assert(i); + assert(property); + + dbus_message_iter_get_basic(i, &t); + + return log_set_max_level_from_string(t); +} + +static int bus_manager_append_n_names(DBusMessageIter *i, const char *property, void *data) { + Manager *m = data; + uint32_t u; + + assert(i); + assert(property); + assert(m); + + u = hashmap_size(m->units); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, &u)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_append_n_jobs(DBusMessageIter *i, const char *property, void *data) { + Manager *m = data; + uint32_t u; + + assert(i); + assert(property); + assert(m); + + u = hashmap_size(m->jobs); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, &u)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_append_progress(DBusMessageIter *i, const char *property, void *data) { + double d; + Manager *m = data; + + assert(i); + assert(property); + assert(m); + + if (dual_timestamp_is_set(&m->finish_timestamp)) + d = 1.0; + else + d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_DOUBLE, &d)) + return -ENOMEM; + + return 0; +} + +static const char *message_get_sender_with_fallback(DBusMessage *m) { + const char *s; + + assert(m); + + if ((s = dbus_message_get_sender(m))) + return s; + + /* When the message came in from a direct connection the + * message will have no sender. We fix that here. */ + + return ":no-sender"; +} + +static DBusMessage *message_from_file_changes( + DBusMessage *m, + UnitFileChange *changes, + unsigned n_changes, + int carries_install_info) { + + DBusMessageIter iter, sub, sub2; + DBusMessage *reply; + unsigned i; + + reply = dbus_message_new_method_return(m); + if (!reply) + return NULL; + + dbus_message_iter_init_append(reply, &iter); + + if (carries_install_info >= 0) { + dbus_bool_t b; + + b = !!carries_install_info; + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &b)) + goto oom; + } + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(sss)", &sub)) + goto oom; + + for (i = 0; i < n_changes; i++) { + const char *type, *path, *source; + + type = unit_file_change_type_to_string(changes[i].type); + path = strempty(changes[i].path); + source = strempty(changes[i].source); + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &type) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &path) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &source) || + !dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + return reply; + +oom: + dbus_message_unref(reply); + return NULL; +} + +static int bus_manager_send_unit_files_changed(Manager *m) { + DBusMessage *s; + int r; + + s = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged"); + if (!s) + return -ENOMEM; + + r = bus_broadcast(m, s); + dbus_message_unref(s); + + return r; +} + +static const char systemd_property_string[] = PACKAGE_STRING "\0" DISTRIBUTION "\0" SYSTEMD_FEATURES; + +static const BusProperty bus_systemd_properties[] = { + { "Version", bus_property_append_string, "s", 0 }, + { "Distribution", bus_property_append_string, "s", sizeof(PACKAGE_STRING) }, + { "Features", bus_property_append_string, "s", sizeof(PACKAGE_STRING) + sizeof(DISTRIBUTION) }, + { NULL, } +}; + +static const BusProperty bus_manager_properties[] = { + { "RunningAs", bus_manager_append_running_as, "s", offsetof(Manager, running_as) }, + { "Tainted", bus_manager_append_tainted, "s", 0 }, + { "InitRDTimestamp", bus_property_append_uint64, "t", offsetof(Manager, initrd_timestamp.realtime) }, + { "InitRDTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, initrd_timestamp.monotonic) }, + { "StartupTimestamp", bus_property_append_uint64, "t", offsetof(Manager, startup_timestamp.realtime) }, + { "StartupTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, startup_timestamp.monotonic) }, + { "FinishTimestamp", bus_property_append_uint64, "t", offsetof(Manager, finish_timestamp.realtime) }, + { "FinishTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, finish_timestamp.monotonic) }, + { "LogLevel", bus_manager_append_log_level, "s", 0, 0, bus_manager_set_log_level }, + { "LogTarget", bus_manager_append_log_target, "s", 0, 0, bus_manager_set_log_target }, + { "NNames", bus_manager_append_n_names, "u", 0 }, + { "NJobs", bus_manager_append_n_jobs, "u", 0 }, + { "NInstalledJobs",bus_property_append_uint32, "u", offsetof(Manager, n_installed_jobs) }, + { "NFailedJobs", bus_property_append_uint32, "u", offsetof(Manager, n_failed_jobs) }, + { "Progress", bus_manager_append_progress, "d", 0 }, + { "Environment", bus_property_append_strv, "as", offsetof(Manager, environment), true }, + { "ConfirmSpawn", bus_property_append_bool, "b", offsetof(Manager, confirm_spawn) }, + { "ShowStatus", bus_property_append_bool, "b", offsetof(Manager, show_status) }, + { "UnitPath", bus_property_append_strv, "as", offsetof(Manager, lookup_paths.unit_path), true }, + { "NotifySocket", bus_property_append_string, "s", offsetof(Manager, notify_socket), true }, + { "ControlGroupHierarchy", bus_property_append_string, "s", offsetof(Manager, cgroup_hierarchy), true }, + { "MountAuto", bus_property_append_bool, "b", offsetof(Manager, mount_auto) }, + { "SwapAuto", bus_property_append_bool, "b", offsetof(Manager, swap_auto) }, + { "DefaultControllers", bus_property_append_strv, "as", offsetof(Manager, default_controllers), true }, + { "DefaultStandardOutput", bus_manager_append_exec_output, "s", offsetof(Manager, default_std_output) }, + { "DefaultStandardError", bus_manager_append_exec_output, "s", offsetof(Manager, default_std_error) }, +#ifdef HAVE_SYSV_COMPAT + { "SysVConsole", bus_property_append_bool, "b", offsetof(Manager, sysv_console) }, + { "SysVInitPath", bus_property_append_strv, "as", offsetof(Manager, lookup_paths.sysvinit_path), true }, + { "SysVRcndPath", bus_property_append_strv, "as", offsetof(Manager, lookup_paths.sysvrcnd_path), true }, +#endif + { NULL, } +}; + +static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, DBusMessage *message, void *data) { + Manager *m = data; + + int r; + DBusError error; + DBusMessage *reply = NULL; + char * path = NULL; + JobType job_type = _JOB_TYPE_INVALID; + bool reload_if_possible = false; + const char *member; + + assert(connection); + assert(message); + assert(m); + + dbus_error_init(&error); + + member = dbus_message_get_member(message); + + if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnit")) { + const char *name; + Unit *u; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (!(u = manager_get_unit(m, name))) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!(path = unit_dbus_path(u))) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnitByPID")) { + Unit *u; + uint32_t pid; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &pid, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (!(u = cgroup_unit_by_pid(m, (pid_t) pid))) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "No unit for PID %lu is loaded.", (unsigned long) pid); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!(path = unit_dbus_path(u))) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "LoadUnit")) { + const char *name; + Unit *u; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if ((r = manager_load_unit(m, name, NULL, &error, &u)) < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!(path = unit_dbus_path(u))) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartUnit")) + job_type = JOB_START; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartUnitReplace")) + job_type = JOB_START; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StopUnit")) + job_type = JOB_STOP; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReloadUnit")) + job_type = JOB_RELOAD; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "RestartUnit")) + job_type = JOB_RESTART; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "TryRestartUnit")) + job_type = JOB_TRY_RESTART; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReloadOrRestartUnit")) { + reload_if_possible = true; + job_type = JOB_RESTART; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReloadOrTryRestartUnit")) { + reload_if_possible = true; + job_type = JOB_TRY_RESTART; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "KillUnit")) { + const char *name, *swho, *smode; + int32_t signo; + Unit *u; + KillMode mode; + KillWho who; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &swho, + DBUS_TYPE_STRING, &smode, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(swho)) + who = KILL_ALL; + else { + who = kill_who_from_string(swho); + if (who < 0) + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if (isempty(smode)) + mode = KILL_CONTROL_GROUP; + else { + mode = kill_mode_from_string(smode); + if (mode < 0) + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (!(u = manager_get_unit(m, name))) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + + if ((r = unit_kill(u, who, mode, signo, &error)) < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetJob")) { + uint32_t id; + Job *j; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &id, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (!(j = manager_get_job(m, id))) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!(path = job_dbus_path(j))) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ClearJobs")) { + + manager_clear_jobs(m); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ResetFailed")) { + + manager_reset_failed(m); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ResetFailedUnit")) { + const char *name; + Unit *u; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (!(u = manager_get_unit(m, name))) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + + unit_reset_failed(u); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ListUnits")) { + DBusMessageIter iter, sub; + Iterator i; + Unit *u; + const char *k; + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ssssssouso)", &sub)) + goto oom; + + HASHMAP_FOREACH_KEY(u, k, m->units, i) { + char *u_path, *j_path; + const char *description, *load_state, *active_state, *sub_state, *sjob_type, *following; + DBusMessageIter sub2; + uint32_t job_id; + Unit *f; + + if (k != u->id) + continue; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + goto oom; + + description = unit_description(u); + load_state = unit_load_state_to_string(u->load_state); + active_state = unit_active_state_to_string(unit_active_state(u)); + sub_state = unit_sub_state_to_string(u); + + f = unit_following(u); + following = f ? f->id : ""; + + if (!(u_path = unit_dbus_path(u))) + goto oom; + + if (u->job) { + job_id = (uint32_t) u->job->id; + + if (!(j_path = job_dbus_path(u->job))) { + free(u_path); + goto oom; + } + + sjob_type = job_type_to_string(u->job->type); + } else { + job_id = 0; + j_path = u_path; + sjob_type = ""; + } + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &u->id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &description) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &load_state) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &active_state) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &sub_state) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &following) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &u_path) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &job_id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &sjob_type) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &j_path)) { + free(u_path); + if (u->job) + free(j_path); + goto oom; + } + + free(u_path); + if (u->job) + free(j_path); + + if (!dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ListJobs")) { + DBusMessageIter iter, sub; + Iterator i; + Job *j; + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(usssoo)", &sub)) + goto oom; + + HASHMAP_FOREACH(j, m->jobs, i) { + char *u_path, *j_path; + const char *state, *type; + uint32_t id; + DBusMessageIter sub2; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + goto oom; + + id = (uint32_t) j->id; + state = job_state_to_string(j->state); + type = job_type_to_string(j->type); + + if (!(j_path = job_dbus_path(j))) + goto oom; + + if (!(u_path = unit_dbus_path(j->unit))) { + free(j_path); + goto oom; + } + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &j->unit->id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &type) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &state) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &j_path) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &u_path)) { + free(j_path); + free(u_path); + goto oom; + } + + free(j_path); + free(u_path); + + if (!dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Subscribe")) { + char *client; + Set *s; + + if (!(s = BUS_CONNECTION_SUBSCRIBED(m, connection))) { + if (!(s = set_new(string_hash_func, string_compare_func))) + goto oom; + + if (!(dbus_connection_set_data(connection, m->subscribed_data_slot, s, NULL))) { + set_free(s); + goto oom; + } + } + + if (!(client = strdup(message_get_sender_with_fallback(message)))) + goto oom; + + if ((r = set_put(s, client)) < 0) { + free(client); + return bus_send_error_reply(connection, message, NULL, r); + } + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Unsubscribe")) { + char *client; + + if (!(client = set_remove(BUS_CONNECTION_SUBSCRIBED(m, connection), (char*) message_get_sender_with_fallback(message)))) { + dbus_set_error(&error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed."); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + + free(client); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Dump")) { + FILE *f; + char *dump = NULL; + size_t size; + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!(f = open_memstream(&dump, &size))) + goto oom; + + manager_dump_units(m, f, NULL); + manager_dump_jobs(m, f, NULL); + + if (ferror(f)) { + fclose(f); + free(dump); + goto oom; + } + + fclose(f); + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &dump, DBUS_TYPE_INVALID)) { + free(dump); + goto oom; + } + + free(dump); + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "CreateSnapshot")) { + const char *name; + dbus_bool_t cleanup; + Snapshot *s; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_BOOLEAN, &cleanup, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (name && name[0] == 0) + name = NULL; + + if ((r = snapshot_create(m, name, cleanup, &error, &s)) < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!(path = unit_dbus_path(UNIT(s)))) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) { + char *introspection = NULL; + FILE *f; + Iterator i; + Unit *u; + Job *j; + const char *k; + size_t size; + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + /* We roll our own introspection code here, instead of + * relying on bus_default_message_handler() because we + * need to generate our introspection string + * dynamically. */ + + if (!(f = open_memstream(&introspection, &size))) + goto oom; + + fputs(INTROSPECTION_BEGIN, f); + + HASHMAP_FOREACH_KEY(u, k, m->units, i) { + char *p; + + if (k != u->id) + continue; + + if (!(p = bus_path_escape(k))) { + fclose(f); + free(introspection); + goto oom; + } + + fprintf(f, "", p); + free(p); + } + + HASHMAP_FOREACH(j, m->jobs, i) + fprintf(f, "", (unsigned long) j->id); + + fputs(INTROSPECTION_END, f); + + if (ferror(f)) { + fclose(f); + free(introspection); + goto oom; + } + + fclose(f); + + if (!introspection) + goto oom; + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) { + free(introspection); + goto oom; + } + + free(introspection); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reload")) { + + assert(!m->queued_message); + + /* Instead of sending the reply back right away, we + * just remember that we need to and then send it + * after the reload is finished. That way the caller + * knows when the reload finished. */ + + if (!(m->queued_message = dbus_message_new_method_return(message))) + goto oom; + + m->queued_message_connection = connection; + m->exit_code = MANAGER_RELOAD; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reexecute")) { + + /* We don't send a reply back here, the client should + * just wait for us disconnecting. */ + + m->exit_code = MANAGER_REEXECUTE; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Exit")) { + + if (m->running_as == MANAGER_SYSTEM) { + dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers."); + return bus_send_error_reply(connection, message, &error, -ENOTSUP); + } + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + m->exit_code = MANAGER_EXIT; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reboot")) { + + if (m->running_as != MANAGER_SYSTEM) { + dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers."); + return bus_send_error_reply(connection, message, &error, -ENOTSUP); + } + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + m->exit_code = MANAGER_REBOOT; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "PowerOff")) { + + if (m->running_as != MANAGER_SYSTEM) { + dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers."); + return bus_send_error_reply(connection, message, &error, -ENOTSUP); + } + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + m->exit_code = MANAGER_POWEROFF; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Halt")) { + + if (m->running_as != MANAGER_SYSTEM) { + dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "Halting is only supported for system managers."); + return bus_send_error_reply(connection, message, &error, -ENOTSUP); + } + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + m->exit_code = MANAGER_HALT; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "KExec")) { + + if (m->running_as != MANAGER_SYSTEM) { + dbus_set_error(&error, BUS_ERROR_NOT_SUPPORTED, "kexec is only supported for system managers."); + return bus_send_error_reply(connection, message, &error, -ENOTSUP); + } + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + m->exit_code = MANAGER_KEXEC; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SetEnvironment")) { + char **l = NULL, **e = NULL; + + if ((r = bus_parse_strv(message, &l)) < 0) { + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(connection, message, NULL, r); + } + + e = strv_env_merge(2, m->environment, l); + strv_free(l); + + if (!e) + goto oom; + + if (!(reply = dbus_message_new_method_return(message))) { + strv_free(e); + goto oom; + } + + strv_free(m->environment); + m->environment = e; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnsetEnvironment")) { + char **l = NULL, **e = NULL; + + if ((r = bus_parse_strv(message, &l)) < 0) { + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(connection, message, NULL, r); + } + + e = strv_env_delete(m->environment, 1, l); + strv_free(l); + + if (!e) + goto oom; + + if (!(reply = dbus_message_new_method_return(message))) { + strv_free(e); + goto oom; + } + + strv_free(m->environment); + m->environment = e; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnsetAndSetEnvironment")) { + char **l_set = NULL, **l_unset = NULL, **e = NULL, **f = NULL; + DBusMessageIter iter; + + if (!dbus_message_iter_init(message, &iter)) + goto oom; + + r = bus_parse_strv_iter(&iter, &l_unset); + if (r < 0) { + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(connection, message, NULL, r); + } + + if (!dbus_message_iter_next(&iter)) { + strv_free(l_unset); + return bus_send_error_reply(connection, message, NULL, -EINVAL); + } + + r = bus_parse_strv_iter(&iter, &l_set); + if (r < 0) { + strv_free(l_unset); + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(connection, message, NULL, r); + } + + e = strv_env_delete(m->environment, 1, l_unset); + strv_free(l_unset); + + if (!e) { + strv_free(l_set); + goto oom; + } + + f = strv_env_merge(2, e, l_set); + strv_free(l_set); + strv_free(e); + + if (!f) + goto oom; + + if (!(reply = dbus_message_new_method_return(message))) { + strv_free(f); + goto oom; + } + + strv_free(m->environment); + m->environment = f; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ListUnitFiles")) { + DBusMessageIter iter, sub, sub2; + Hashmap *h; + Iterator i; + UnitFileList *item; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + h = hashmap_new(string_hash_func, string_compare_func); + if (!h) + goto oom; + + r = unit_file_get_list(m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h); + if (r < 0) { + unit_file_list_free(h); + dbus_message_unref(reply); + return bus_send_error_reply(connection, message, NULL, r); + } + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ss)", &sub)) { + unit_file_list_free(h); + goto oom; + } + + HASHMAP_FOREACH(item, h, i) { + const char *state; + + state = unit_file_state_to_string(item->state); + assert(state); + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &item->path) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &state) || + !dbus_message_iter_close_container(&sub, &sub2)) { + unit_file_list_free(h); + goto oom; + } + } + + unit_file_list_free(h); + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnitFileState")) { + const char *name; + UnitFileState state; + const char *s; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + state = unit_file_get_state(m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, name); + if (state < 0) + return bus_send_error_reply(connection, message, NULL, state); + + s = unit_file_state_to_string(state); + assert(s); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_STRING, &s, + DBUS_TYPE_INVALID)) + goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "EnableUnitFiles") || + dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReenableUnitFiles") || + dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "LinkUnitFiles") || + dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "PresetUnitFiles") || + dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "MaskUnitFiles")) { + + char **l = NULL; + DBusMessageIter iter; + UnitFileScope scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; + UnitFileChange *changes = NULL; + unsigned n_changes = 0; + dbus_bool_t runtime, force; + int carries_install_info = -1; + + if (!dbus_message_iter_init(message, &iter)) + goto oom; + + r = bus_parse_strv_iter(&iter, &l); + if (r < 0) { + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(connection, message, NULL, r); + } + + if (!dbus_message_iter_next(&iter) || + bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &runtime, true) < 0 || + bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &force, false) < 0) { + strv_free(l); + return bus_send_error_reply(connection, message, NULL, -EIO); + } + + if (streq(member, "EnableUnitFiles")) { + r = unit_file_enable(scope, runtime, NULL, l, force, &changes, &n_changes); + carries_install_info = r; + } else if (streq(member, "ReenableUnitFiles")) { + r = unit_file_reenable(scope, runtime, NULL, l, force, &changes, &n_changes); + carries_install_info = r; + } else if (streq(member, "LinkUnitFiles")) + r = unit_file_link(scope, runtime, NULL, l, force, &changes, &n_changes); + else if (streq(member, "PresetUnitFiles")) { + r = unit_file_preset(scope, runtime, NULL, l, force, &changes, &n_changes); + carries_install_info = r; + } else if (streq(member, "MaskUnitFiles")) + r = unit_file_mask(scope, runtime, NULL, l, force, &changes, &n_changes); + else + assert_not_reached("Uh? Wrong method"); + + strv_free(l); + bus_manager_send_unit_files_changed(m); + + if (r < 0) { + unit_file_changes_free(changes, n_changes); + return bus_send_error_reply(connection, message, NULL, r); + } + + reply = message_from_file_changes(message, changes, n_changes, carries_install_info); + unit_file_changes_free(changes, n_changes); + + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "DisableUnitFiles") || + dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnmaskUnitFiles")) { + + char **l = NULL; + DBusMessageIter iter; + UnitFileScope scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; + UnitFileChange *changes = NULL; + unsigned n_changes = 0; + dbus_bool_t runtime; + + if (!dbus_message_iter_init(message, &iter)) + goto oom; + + r = bus_parse_strv_iter(&iter, &l); + if (r < 0) { + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(connection, message, NULL, r); + } + + if (!dbus_message_iter_next(&iter) || + bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &runtime, false) < 0) { + strv_free(l); + return bus_send_error_reply(connection, message, NULL, -EIO); + } + + if (streq(member, "DisableUnitFiles")) + r = unit_file_disable(scope, runtime, NULL, l, &changes, &n_changes); + else if (streq(member, "UnmaskUnitFiles")) + r = unit_file_unmask(scope, runtime, NULL, l, &changes, &n_changes); + else + assert_not_reached("Uh? Wrong method"); + + strv_free(l); + bus_manager_send_unit_files_changed(m); + + if (r < 0) { + unit_file_changes_free(changes, n_changes); + return bus_send_error_reply(connection, message, NULL, r); + } + + reply = message_from_file_changes(message, changes, n_changes, -1); + unit_file_changes_free(changes, n_changes); + + if (!reply) + goto oom; + + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Manager", bus_systemd_properties, systemd_property_string }, + { "org.freedesktop.systemd1.Manager", bus_manager_properties, m }, + { NULL, } + }; + return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, bps); + } + + if (job_type != _JOB_TYPE_INVALID) { + const char *name, *smode, *old_name = NULL; + JobMode mode; + Job *j; + Unit *u; + bool b; + + if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "StartUnitReplace")) + b = dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &old_name, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &smode, + DBUS_TYPE_INVALID); + else + b = dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &smode, + DBUS_TYPE_INVALID); + + if (!b) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (old_name) + if (!(u = manager_get_unit(m, old_name)) || + !u->job || + u->job->type != JOB_START) { + dbus_set_error(&error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name); + return bus_send_error_reply(connection, message, &error, -ENOENT); + } + + + if ((mode = job_mode_from_string(smode)) == _JOB_MODE_INVALID) { + dbus_set_error(&error, BUS_ERROR_INVALID_JOB_MODE, "Job mode %s is invalid.", smode); + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if ((r = manager_load_unit(m, name, NULL, &error, &u)) < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (reload_if_possible && unit_can_reload(u)) { + if (job_type == JOB_RESTART) + job_type = JOB_RELOAD_OR_START; + else if (job_type == JOB_TRY_RESTART) + job_type = JOB_RELOAD; + } + + if ((job_type == JOB_START && u->refuse_manual_start) || + (job_type == JOB_STOP && u->refuse_manual_stop) || + ((job_type == JOB_RESTART || job_type == JOB_TRY_RESTART) && + (u->refuse_manual_start || u->refuse_manual_stop))) { + dbus_set_error(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, may be requested by dependency only."); + return bus_send_error_reply(connection, message, &error, -EPERM); + } + + if ((r = manager_add_job(m, job_type, u, mode, true, &error, &j)) < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (!(j->bus_client = strdup(message_get_sender_with_fallback(message)))) + goto oom; + + j->bus = connection; + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!(path = job_dbus_path(j))) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + } + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + free(path); + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + free(path); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +const DBusObjectPathVTable bus_manager_vtable = { + .message_function = bus_manager_message_handler +}; diff --git a/src/dbus-manager.h b/src/dbus-manager.h new file mode 100644 index 0000000..2eb2fbb --- /dev/null +++ b/src/dbus-manager.h @@ -0,0 +1,31 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbusmanagerhfoo +#define foodbusmanagerhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +extern const DBusObjectPathVTable bus_manager_vtable; + +extern const char bus_manager_interface[]; + +#endif diff --git a/src/dbus-mount.c b/src/dbus-mount.c new file mode 100644 index 0000000..35d6ea7 --- /dev/null +++ b/src/dbus-mount.c @@ -0,0 +1,168 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-mount.h" +#include "dbus-execute.h" +#include "dbus-common.h" + +#define BUS_MOUNT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + BUS_EXEC_COMMAND_INTERFACE("ExecMount") \ + BUS_EXEC_COMMAND_INTERFACE("ExecUnmount") \ + BUS_EXEC_COMMAND_INTERFACE("ExecRemount") \ + BUS_EXEC_CONTEXT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_MOUNT_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Mount\0" + +const char bus_mount_interface[] _introspect_("Mount") = BUS_MOUNT_INTERFACE; + +const char bus_mount_invalidating_properties[] = + "What\0" + "Options\0" + "Type\0" + "ExecMount\0" + "ExecUnmount\0" + "ExecRemount\0" + "ControlPID\0" + "Result\0"; + +static int bus_mount_append_what(DBusMessageIter *i, const char *property, void *data) { + Mount *m = data; + const char *d; + + assert(i); + assert(property); + assert(m); + + if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what) + d = m->parameters_proc_self_mountinfo.what; + else if (m->from_fragment && m->parameters_fragment.what) + d = m->parameters_fragment.what; + else if (m->from_etc_fstab && m->parameters_etc_fstab.what) + d = m->parameters_etc_fstab.what; + else + d = ""; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d)) + return -ENOMEM; + + return 0; +} + +static int bus_mount_append_options(DBusMessageIter *i, const char *property, void *data) { + Mount *m = data; + const char *d; + + assert(i); + assert(property); + assert(m); + + if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options) + d = m->parameters_proc_self_mountinfo.options; + else if (m->from_fragment && m->parameters_fragment.options) + d = m->parameters_fragment.options; + else if (m->from_etc_fstab && m->parameters_etc_fstab.options) + d = m->parameters_etc_fstab.options; + else + d = ""; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d)) + return -ENOMEM; + + return 0; +} + +static int bus_mount_append_type(DBusMessageIter *i, const char *property, void *data) { + Mount *m = data; + const char *d; + + assert(i); + assert(property); + assert(m); + + if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.fstype) + d = m->parameters_proc_self_mountinfo.fstype; + else if (m->from_fragment && m->parameters_fragment.fstype) + d = m->parameters_fragment.fstype; + else if (m->from_etc_fstab && m->parameters_etc_fstab.fstype) + d = m->parameters_etc_fstab.fstype; + else + d = ""; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d)) + return -ENOMEM; + + return 0; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_mount_append_mount_result, mount_result, MountResult); + +static const BusProperty bus_mount_properties[] = { + { "Where", bus_property_append_string, "s", offsetof(Mount, where), true }, + { "What", bus_mount_append_what, "s", 0 }, + { "Options", bus_mount_append_options, "s", 0 }, + { "Type", bus_mount_append_type, "s", 0 }, + { "TimeoutUSec", bus_property_append_usec, "t", offsetof(Mount, timeout_usec) }, + BUS_EXEC_COMMAND_PROPERTY("ExecMount", offsetof(Mount, exec_command[MOUNT_EXEC_MOUNT]), false), + BUS_EXEC_COMMAND_PROPERTY("ExecUnmount", offsetof(Mount, exec_command[MOUNT_EXEC_UNMOUNT]), false), + BUS_EXEC_COMMAND_PROPERTY("ExecRemount", offsetof(Mount, exec_command[MOUNT_EXEC_REMOUNT]), false), + { "ControlPID", bus_property_append_pid, "u", offsetof(Mount, control_pid) }, + { "DirectoryMode", bus_property_append_mode, "u", offsetof(Mount, directory_mode) }, + { "Result", bus_mount_append_mount_result, "s", offsetof(Mount, result) }, + { NULL, } +}; + +DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Mount *m = MOUNT(u); + + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Mount", bus_mount_properties, m }, + { "org.freedesktop.systemd1.Mount", bus_exec_context_properties, &m->exec_context }, + { NULL, } + }; + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps ); +} diff --git a/src/dbus-mount.h b/src/dbus-mount.h new file mode 100644 index 0000000..b5613fa --- /dev/null +++ b/src/dbus-mount.h @@ -0,0 +1,34 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbusmounthfoo +#define foodbusmounthfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_mount_interface[]; +extern const char bus_mount_invalidating_properties[]; + +#endif diff --git a/src/dbus-path.c b/src/dbus-path.c new file mode 100644 index 0000000..5506784 --- /dev/null +++ b/src/dbus-path.c @@ -0,0 +1,119 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-path.h" +#include "dbus-execute.h" +#include "dbus-common.h" + +#define BUS_PATH_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_PATH_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Path\0" + +const char bus_path_interface[] _introspect_("Path") = BUS_PATH_INTERFACE; + +const char bus_path_invalidating_properties[] = + "Result\0"; + +static int bus_path_append_paths(DBusMessageIter *i, const char *property, void *data) { + Path *p = data; + DBusMessageIter sub, sub2; + PathSpec *k; + + assert(i); + assert(property); + assert(p); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(ss)", &sub)) + return -ENOMEM; + + LIST_FOREACH(spec, k, p->specs) { + const char *t = path_type_to_string(k->type); + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &t) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &k->path) || + !dbus_message_iter_close_container(&sub, &sub2)) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_path_append_unit(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + Path *p = PATH(u); + const char *t; + + assert(i); + assert(property); + assert(u); + + t = UNIT_DEREF(p->unit) ? UNIT_DEREF(p->unit)->id : ""; + + return dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t) ? 0 : -ENOMEM; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_path_append_path_result, path_result, PathResult); + +static const BusProperty bus_path_properties[] = { + { "Unit", bus_path_append_unit, "s", 0 }, + { "Paths", bus_path_append_paths, "a(ss)", 0 }, + { "MakeDirectory", bus_property_append_bool, "b", offsetof(Path, make_directory) }, + { "DirectoryMode", bus_property_append_mode, "u", offsetof(Path, directory_mode) }, + { "Result", bus_path_append_path_result, "s", offsetof(Path, result) }, + { NULL, } +}; + +DBusHandlerResult bus_path_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Path *p = PATH(u); + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Path", bus_path_properties, p }, + { NULL, } + }; + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/dbus-path.h b/src/dbus-path.h new file mode 100644 index 0000000..2888400 --- /dev/null +++ b/src/dbus-path.h @@ -0,0 +1,35 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbuspathhfoo +#define foodbuspathhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_path_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_path_interface[]; + +extern const char bus_path_invalidating_properties[]; + +#endif diff --git a/src/dbus-service.c b/src/dbus-service.c new file mode 100644 index 0000000..7809164 --- /dev/null +++ b/src/dbus-service.c @@ -0,0 +1,168 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-execute.h" +#include "dbus-service.h" +#include "dbus-common.h" + +#ifdef HAVE_SYSV_COMPAT +#define BUS_SERVICE_SYSV_INTERFACE_FRAGMENT \ + " \n" \ + " \n" \ + " \n" +#else +#define BUS_SERVICE_SYSV_INTERFACE_FRAGMENT "" +#endif + +#define BUS_SERVICE_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + BUS_EXEC_COMMAND_INTERFACE("ExecStartPre") \ + BUS_EXEC_COMMAND_INTERFACE("ExecStart") \ + BUS_EXEC_COMMAND_INTERFACE("ExecStartPost") \ + BUS_EXEC_COMMAND_INTERFACE("ExecReload") \ + BUS_EXEC_COMMAND_INTERFACE("ExecStop") \ + BUS_EXEC_COMMAND_INTERFACE("ExecStopPost") \ + BUS_EXEC_CONTEXT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + BUS_EXEC_STATUS_INTERFACE("ExecMain") \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + BUS_SERVICE_SYSV_INTERFACE_FRAGMENT \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_SERVICE_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Service\0" + +const char bus_service_interface[] _introspect_("Service") = BUS_SERVICE_INTERFACE; + +const char bus_service_invalidating_properties[] = + "ExecStartPre\0" + "ExecStart\0" + "ExecStartPost\0" + "ExecReload\0" + "ExecStop\0" + "ExecStopPost\0" + "ExecMain\0" + "WatchdogTimestamp\0" + "WatchdogTimestampMonotonic\0" + "MainPID\0" + "ControlPID\0" + "StatusText\0" + "Result\0"; + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_type, service_type, ServiceType); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_restart, service_restart, ServiceRestart); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_notify_access, notify_access, NotifyAccess); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_service_result, service_result, ServiceResult); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_start_limit_action, start_limit_action, StartLimitAction); + +static const BusProperty bus_exec_main_status_properties[] = { + { "ExecMainStartTimestamp", bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.realtime) }, + { "ExecMainStartTimestampMonotonic",bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.monotonic) }, + { "ExecMainExitTimestamp", bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.realtime) }, + { "ExecMainExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(ExecStatus, start_timestamp.monotonic) }, + { "ExecMainPID", bus_property_append_pid, "u", offsetof(ExecStatus, pid) }, + { "ExecMainCode", bus_property_append_int, "i", offsetof(ExecStatus, code) }, + { "ExecMainStatus", bus_property_append_int, "i", offsetof(ExecStatus, status) }, + { NULL, } +}; + +static const BusProperty bus_service_properties[] = { + { "Type", bus_service_append_type, "s", offsetof(Service, type) }, + { "Restart", bus_service_append_restart, "s", offsetof(Service, restart) }, + { "PIDFile", bus_property_append_string, "s", offsetof(Service, pid_file), true }, + { "NotifyAccess", bus_service_append_notify_access, "s", offsetof(Service, notify_access) }, + { "RestartUSec", bus_property_append_usec, "t", offsetof(Service, restart_usec) }, + { "TimeoutUSec", bus_property_append_usec, "t", offsetof(Service, timeout_usec) }, + { "WatchdogUSec", bus_property_append_usec, "t", offsetof(Service, watchdog_usec) }, + { "WatchdogTimestamp", bus_property_append_usec, "t", offsetof(Service, watchdog_timestamp.realtime) }, + { "WatchdogTimestampMonotonic",bus_property_append_usec, "t", offsetof(Service, watchdog_timestamp.monotonic) }, + { "StartLimitInterval", bus_property_append_usec, "t", offsetof(Service, start_limit.interval) }, + { "StartLimitBurst", bus_property_append_uint32, "u", offsetof(Service, start_limit.burst) }, + { "StartLimitAction", bus_service_append_start_limit_action,"s", offsetof(Service, start_limit_action) }, + BUS_EXEC_COMMAND_PROPERTY("ExecStartPre", offsetof(Service, exec_command[SERVICE_EXEC_START_PRE]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecStart", offsetof(Service, exec_command[SERVICE_EXEC_START]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecStartPost", offsetof(Service, exec_command[SERVICE_EXEC_START_POST]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecReload", offsetof(Service, exec_command[SERVICE_EXEC_RELOAD]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecStop", offsetof(Service, exec_command[SERVICE_EXEC_STOP]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecStopPost", offsetof(Service, exec_command[SERVICE_EXEC_STOP_POST]), true ), + { "PermissionsStartOnly", bus_property_append_bool, "b", offsetof(Service, permissions_start_only) }, + { "RootDirectoryStartOnly", bus_property_append_bool, "b", offsetof(Service, root_directory_start_only) }, + { "RemainAfterExit", bus_property_append_bool, "b", offsetof(Service, remain_after_exit) }, + { "GuessMainPID", bus_property_append_bool, "b", offsetof(Service, guess_main_pid) }, + { "MainPID", bus_property_append_pid, "u", offsetof(Service, main_pid) }, + { "ControlPID", bus_property_append_pid, "u", offsetof(Service, control_pid) }, + { "BusName", bus_property_append_string, "s", offsetof(Service, bus_name), true }, + { "StatusText", bus_property_append_string, "s", offsetof(Service, status_text), true }, +#ifdef HAVE_SYSV_COMPAT + { "SysVRunLevels", bus_property_append_string, "s", offsetof(Service, sysv_runlevels), true }, + { "SysVStartPriority", bus_property_append_int, "i", offsetof(Service, sysv_start_priority) }, + { "SysVPath", bus_property_append_string, "s", offsetof(Service, sysv_path), true }, +#endif + { "FsckPassNo", bus_property_append_int, "i", offsetof(Service, fsck_passno) }, + { "Result", bus_service_append_service_result,"s", offsetof(Service, result) }, + { NULL, } +}; + +DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connection, DBusMessage *message) { + Service *s = SERVICE(u); + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Service", bus_service_properties, s }, + { "org.freedesktop.systemd1.Service", bus_exec_context_properties, &s->exec_context }, + { "org.freedesktop.systemd1.Service", bus_exec_main_status_properties, &s->main_exec_status }, + { NULL, } + }; + + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/dbus-service.h b/src/dbus-service.h new file mode 100644 index 0000000..d6eab65 --- /dev/null +++ b/src/dbus-service.h @@ -0,0 +1,34 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbusservicehfoo +#define foodbusservicehfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_service_interface[]; +extern const char bus_service_invalidating_properties[]; + +#endif diff --git a/src/dbus-snapshot.c b/src/dbus-snapshot.c new file mode 100644 index 0000000..e69388a --- /dev/null +++ b/src/dbus-snapshot.c @@ -0,0 +1,93 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "dbus-unit.h" +#include "dbus-snapshot.h" +#include "dbus-common.h" + +#define BUS_SNAPSHOT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_SNAPSHOT_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Snapshot\0" + +const char bus_snapshot_interface[] _introspect_("Snapshot") = BUS_SNAPSHOT_INTERFACE; + +static const BusProperty bus_snapshot_properties[] = { + { "Cleanup", bus_property_append_bool, "b", offsetof(Snapshot, cleanup) }, + { NULL, } +}; + +DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Snapshot *s = SNAPSHOT(u); + + DBusMessage *reply = NULL; + DBusError error; + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Snapshot", "Remove")) { + + snapshot_remove(SNAPSHOT(u)); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Snapshot", bus_snapshot_properties, s }, + { NULL, } + }; + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); + } + + if (reply) { + if (!dbus_connection_send(c, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} diff --git a/src/dbus-snapshot.h b/src/dbus-snapshot.h new file mode 100644 index 0000000..0b82279 --- /dev/null +++ b/src/dbus-snapshot.h @@ -0,0 +1,33 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbussnapshothfoo +#define foodbussnapshothfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_snapshot_interface[]; + +#endif diff --git a/src/dbus-socket.c b/src/dbus-socket.c new file mode 100644 index 0000000..9fef676 --- /dev/null +++ b/src/dbus-socket.c @@ -0,0 +1,137 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-socket.h" +#include "dbus-execute.h" +#include "dbus-common.h" + +#define BUS_SOCKET_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + BUS_EXEC_COMMAND_INTERFACE("ExecStartPre") \ + BUS_EXEC_COMMAND_INTERFACE("ExecStartPost") \ + BUS_EXEC_COMMAND_INTERFACE("ExecStopPre") \ + BUS_EXEC_COMMAND_INTERFACE("ExecStopPost") \ + BUS_EXEC_CONTEXT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_SOCKET_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Socket\0" + +const char bus_socket_interface[] _introspect_("Socket") = BUS_SOCKET_INTERFACE; + +const char bus_socket_invalidating_properties[] = + "ExecStartPre\0" + "ExecStartPost\0" + "ExecStopPre\0" + "ExecStopPost\0" + "ControlPID\0" + "NAccepted\0" + "NConnections\0" + "Result\0"; + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_socket_result, socket_result, SocketResult); + +static const BusProperty bus_socket_properties[] = { + { "BindIPv6Only", bus_socket_append_bind_ipv6_only, "s", offsetof(Socket, bind_ipv6_only) }, + { "Backlog", bus_property_append_unsigned, "u", offsetof(Socket, backlog) }, + { "TimeoutUSec", bus_property_append_usec, "t", offsetof(Socket, timeout_usec) }, + BUS_EXEC_COMMAND_PROPERTY("ExecStartPre", offsetof(Socket, exec_command[SOCKET_EXEC_START_PRE]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecStartPost", offsetof(Socket, exec_command[SOCKET_EXEC_START_POST]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecStopPre", offsetof(Socket, exec_command[SOCKET_EXEC_STOP_PRE]), true ), + BUS_EXEC_COMMAND_PROPERTY("ExecStopPost", offsetof(Socket, exec_command[SOCKET_EXEC_STOP_POST]), true ), + { "ControlPID", bus_property_append_pid, "u", offsetof(Socket, control_pid) }, + { "BindToDevice", bus_property_append_string, "s", offsetof(Socket, bind_to_device), true }, + { "DirectoryMode", bus_property_append_mode, "u", offsetof(Socket, directory_mode) }, + { "SocketMode", bus_property_append_mode, "u", offsetof(Socket, socket_mode) }, + { "Accept", bus_property_append_bool, "b", offsetof(Socket, accept) }, + { "KeepAlive", bus_property_append_bool, "b", offsetof(Socket, keep_alive) }, + { "Priority", bus_property_append_int, "i", offsetof(Socket, priority) }, + { "ReceiveBuffer", bus_property_append_size, "t", offsetof(Socket, receive_buffer) }, + { "SendBuffer", bus_property_append_size, "t", offsetof(Socket, send_buffer) }, + { "IPTOS", bus_property_append_int, "i", offsetof(Socket, ip_tos) }, + { "IPTTL", bus_property_append_int, "i", offsetof(Socket, ip_ttl) }, + { "PipeSize", bus_property_append_size, "t", offsetof(Socket, pipe_size) }, + { "FreeBind", bus_property_append_bool, "b", offsetof(Socket, free_bind) }, + { "Transparent", bus_property_append_bool, "b", offsetof(Socket, transparent) }, + { "Broadcast", bus_property_append_bool, "b", offsetof(Socket, broadcast) }, + { "PassCredentials",bus_property_append_bool, "b", offsetof(Socket, pass_cred) }, + { "Mark", bus_property_append_int, "i", offsetof(Socket, mark) }, + { "MaxConnections", bus_property_append_unsigned, "u", offsetof(Socket, max_connections) }, + { "NConnections", bus_property_append_unsigned, "u", offsetof(Socket, n_connections) }, + { "NAccepted", bus_property_append_unsigned, "u", offsetof(Socket, n_accepted) }, + { "MessageQueueMaxMessages", bus_property_append_long, "x", offsetof(Socket, mq_maxmsg) }, + { "MessageQueueMessageSize", bus_property_append_long, "x", offsetof(Socket, mq_msgsize) }, + { "Result", bus_socket_append_socket_result, "s", offsetof(Socket, result) }, + { NULL, } +}; + +DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Socket *s = SOCKET(u); + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Socket", bus_socket_properties, s }, + { "org.freedesktop.systemd1.Socket", bus_exec_context_properties, &s->exec_context }, + { NULL, } + }; + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/dbus-socket.h b/src/dbus-socket.h new file mode 100644 index 0000000..069a2f5 --- /dev/null +++ b/src/dbus-socket.h @@ -0,0 +1,34 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbussockethfoo +#define foodbussockethfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_socket_interface[]; +extern const char bus_socket_invalidating_properties[]; + +#endif diff --git a/src/dbus-swap.c b/src/dbus-swap.c new file mode 100644 index 0000000..09cd1e8 --- /dev/null +++ b/src/dbus-swap.c @@ -0,0 +1,111 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + Copyright 2010 Maarten Lankhorst + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-swap.h" +#include "dbus-execute.h" +#include "dbus-common.h" + +#define BUS_SWAP_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + BUS_EXEC_COMMAND_INTERFACE("ExecActivate") \ + BUS_EXEC_COMMAND_INTERFACE("ExecDeactivate") \ + BUS_EXEC_CONTEXT_INTERFACE \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_SWAP_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Swap\0" + +const char bus_swap_interface[] _introspect_("Swap") = BUS_SWAP_INTERFACE; + +const char bus_swap_invalidating_properties[] = + "What\0" + "Priority\0" + "ExecActivate\0" + "ExecDeactivate\0" + "ControlPID\0" + "Result\0"; + +static int bus_swap_append_priority(DBusMessageIter *i, const char *property, void *data) { + Swap *s = data; + dbus_int32_t j; + + assert(i); + assert(property); + assert(s); + + if (s->from_proc_swaps) + j = s->parameters_proc_swaps.priority; + else if (s->from_fragment) + j = s->parameters_fragment.priority; + else if (s->from_etc_fstab) + j = s->parameters_etc_fstab.priority; + else + j = -1; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &j)) + return -ENOMEM; + + return 0; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_swap_append_swap_result, swap_result, SwapResult); + +static const BusProperty bus_swap_properties[] = { + { "What", bus_property_append_string, "s", offsetof(Swap, what), true }, + { "Priority", bus_swap_append_priority, "i", 0 }, + BUS_EXEC_COMMAND_PROPERTY("ExecActivate", offsetof(Swap, exec_command[SWAP_EXEC_ACTIVATE]), false), + BUS_EXEC_COMMAND_PROPERTY("ExecDeactivate", offsetof(Swap, exec_command[SWAP_EXEC_DEACTIVATE]), false), + { "ControlPID", bus_property_append_pid, "u", offsetof(Swap, control_pid) }, + { "Result", bus_swap_append_swap_result,"s", offsetof(Swap, result) }, + { NULL, } +}; + +DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Swap *s = SWAP(u); + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Swap", bus_swap_properties, s }, + { "org.freedesktop.systemd1.Swap", bus_exec_context_properties, &s->exec_context }, + { NULL, } + }; + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/dbus-swap.h b/src/dbus-swap.h new file mode 100644 index 0000000..15b9147 --- /dev/null +++ b/src/dbus-swap.h @@ -0,0 +1,35 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbusswaphfoo +#define foodbusswaphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + Copyright 2010 Maarten Lankhorst + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_swap_interface[]; +extern const char bus_swap_invalidating_properties[]; + +#endif diff --git a/src/dbus-target.c b/src/dbus-target.c new file mode 100644 index 0000000..55cf862 --- /dev/null +++ b/src/dbus-target.c @@ -0,0 +1,55 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-target.h" +#include "dbus-common.h" + +#define BUS_TARGET_INTERFACE \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_TARGET_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Target\0" + +const char bus_target_interface[] _introspect_("Target") = BUS_TARGET_INTERFACE; + +DBusHandlerResult bus_target_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { NULL, } + }; + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/dbus-target.h b/src/dbus-target.h new file mode 100644 index 0000000..13d3876 --- /dev/null +++ b/src/dbus-target.h @@ -0,0 +1,33 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbustargethfoo +#define foodbustargethfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_target_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_target_interface[]; + +#endif diff --git a/src/dbus-timer.c b/src/dbus-timer.c new file mode 100644 index 0000000..b396aed --- /dev/null +++ b/src/dbus-timer.c @@ -0,0 +1,137 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "dbus-unit.h" +#include "dbus-timer.h" +#include "dbus-execute.h" +#include "dbus-common.h" + +#define BUS_TIMER_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_UNIT_INTERFACE \ + BUS_TIMER_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Timer\0" + +const char bus_timer_interface[] _introspect_("Timer") = BUS_TIMER_INTERFACE; + +const char bus_timer_invalidating_properties[] = + "Timers\0" + "NextElapseUSec\0" + "Result\0"; + +static int bus_timer_append_timers(DBusMessageIter *i, const char *property, void *data) { + Timer *p = data; + DBusMessageIter sub, sub2; + TimerValue *k; + + assert(i); + assert(property); + assert(p); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(stt)", &sub)) + return -ENOMEM; + + LIST_FOREACH(value, k, p->values) { + char *buf; + const char *t; + size_t l; + bool b; + + t = timer_base_to_string(k->base); + assert(endswith(t, "Sec")); + + /* s/Sec/USec/ */ + l = strlen(t); + if (!(buf = new(char, l+2))) + return -ENOMEM; + + memcpy(buf, t, l-3); + memcpy(buf+l-3, "USec", 5); + + b = dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) && + dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &buf) && + dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->value) && + dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &k->next_elapse) && + dbus_message_iter_close_container(&sub, &sub2); + + free(buf); + if (!b) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_timer_append_unit(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + Timer *timer = TIMER(u); + const char *t; + + assert(i); + assert(property); + assert(u); + + t = UNIT_DEREF(timer->unit) ? UNIT_DEREF(timer->unit)->id : ""; + + return dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t) ? 0 : -ENOMEM; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_timer_append_timer_result, timer_result, TimerResult); + +static const BusProperty bus_timer_properties[] = { + { "Unit", bus_timer_append_unit, "s", 0 }, + { "Timers", bus_timer_append_timers, "a(stt)", 0 }, + { "NextElapseUSec", bus_property_append_usec, "t", offsetof(Timer, next_elapse) }, + { "Result", bus_timer_append_timer_result,"s", offsetof(Timer, result) }, + { NULL, } +}; + +DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { + Timer *t = TIMER(u); + const BusBoundProperties bps[] = { + { "org.freedesktop.systemd1.Unit", bus_unit_properties, u }, + { "org.freedesktop.systemd1.Timer", bus_timer_properties, t }, + { NULL, } + }; + + return bus_default_message_handler(c, message, INTROSPECTION, INTERFACES_LIST, bps); +} diff --git a/src/dbus-timer.h b/src/dbus-timer.h new file mode 100644 index 0000000..e692e12 --- /dev/null +++ b/src/dbus-timer.h @@ -0,0 +1,34 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbustimerhfoo +#define foodbustimerhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "unit.h" + +DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); + +extern const char bus_timer_interface[]; +extern const char bus_timer_invalidating_properties[]; + +#endif diff --git a/src/dbus-unit.c b/src/dbus-unit.c new file mode 100644 index 0000000..c7532c7 --- /dev/null +++ b/src/dbus-unit.c @@ -0,0 +1,850 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "dbus.h" +#include "log.h" +#include "dbus-unit.h" +#include "bus-errors.h" +#include "dbus-common.h" + +const char bus_unit_interface[] _introspect_("Unit") = BUS_UNIT_INTERFACE; + +#define INVALIDATING_PROPERTIES \ + "LoadState\0" \ + "ActiveState\0" \ + "SubState\0" \ + "InactiveExitTimestamp\0" \ + "ActiveEnterTimestamp\0" \ + "ActiveExitTimestamp\0" \ + "InactiveEnterTimestamp\0" \ + "Job\0" \ + "NeedDaemonReload\0" + +static int bus_unit_append_names(DBusMessageIter *i, const char *property, void *data) { + char *t; + Iterator j; + DBusMessageIter sub; + Unit *u = data; + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub)) + return -ENOMEM; + + SET_FOREACH(t, u->names, j) + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &t)) + return -ENOMEM; + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_following(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data, *f; + const char *d; + + assert(i); + assert(property); + assert(u); + + f = unit_following(u); + d = f ? f->id : ""; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_dependencies(DBusMessageIter *i, const char *property, void *data) { + Unit *u; + Iterator j; + DBusMessageIter sub; + Set *s = data; + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub)) + return -ENOMEM; + + SET_FOREACH(u, s, j) + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &u->id)) + return -ENOMEM; + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_description(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + const char *d; + + assert(i); + assert(property); + assert(u); + + d = unit_description(u); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &d)) + return -ENOMEM; + + return 0; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_unit_append_load_state, unit_load_state, UnitLoadState); + +static int bus_unit_append_active_state(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + const char *state; + + assert(i); + assert(property); + assert(u); + + state = unit_active_state_to_string(unit_active_state(u)); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_sub_state(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + const char *state; + + assert(i); + assert(property); + assert(u); + + state = unit_sub_state_to_string(u); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_file_state(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + const char *state; + + assert(i); + assert(property); + assert(u); + + state = strempty(unit_file_state_to_string(unit_get_unit_file_state(u))); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_can_start(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(u); + + b = unit_can_start(u) && + !u->refuse_manual_start; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_can_stop(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(u); + + /* On the lower levels we assume that every unit we can start + * we can also stop */ + + b = unit_can_start(u) && + !u->refuse_manual_stop; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_can_reload(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(u); + + b = unit_can_reload(u); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_can_isolate(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(u); + + b = unit_can_isolate(u) && + !u->refuse_manual_start; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_job(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + DBusMessageIter sub; + char *p; + + assert(i); + assert(property); + assert(u); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) + return -ENOMEM; + + if (u->job) { + + if (!(p = job_dbus_path(u->job))) + return -ENOMEM; + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &u->job->id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + return -ENOMEM; + } + } else { + uint32_t id = 0; + + /* No job, so let's fill in some placeholder + * data. Since we need to fill in a valid path we + * simple point to ourselves. */ + + if (!(p = unit_dbus_path(u))) + return -ENOMEM; + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + return -ENOMEM; + } + } + + free(p); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_default_cgroup(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + char *t; + CGroupBonding *cgb; + bool success; + + assert(i); + assert(property); + assert(u); + + if ((cgb = unit_get_default_cgroup(u))) { + if (!(t = cgroup_bonding_to_string(cgb))) + return -ENOMEM; + } else + t = (char*) ""; + + success = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &t); + + if (cgb) + free(t); + + return success ? 0 : -ENOMEM; +} + +static int bus_unit_append_cgroups(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + CGroupBonding *cgb; + DBusMessageIter sub; + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "s", &sub)) + return -ENOMEM; + + LIST_FOREACH(by_unit, cgb, u->cgroup_bondings) { + char *t; + bool success; + + if (!(t = cgroup_bonding_to_string(cgb))) + return -ENOMEM; + + success = dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &t); + free(t); + + if (!success) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_cgroup_attrs(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + CGroupAttribute *a; + DBusMessageIter sub, sub2; + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sss)", &sub)) + return -ENOMEM; + + LIST_FOREACH(by_unit, a, u->cgroup_attributes) { + char *v = NULL; + bool success; + + if (a->map_callback) + a->map_callback(a->controller, a->name, a->value, &v); + + success = + dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) && + dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &a->controller) && + dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &a->name) && + dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, v ? &v : &a->value) && + dbus_message_iter_close_container(&sub, &sub2); + + free(v); + + if (!success) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_need_daemon_reload(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(u); + + b = unit_need_daemon_reload(u); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_unit_append_load_error(DBusMessageIter *i, const char *property, void *data) { + Unit *u = data; + const char *name, *message; + DBusMessageIter sub; + + assert(i); + assert(property); + assert(u); + + if (u->load_error != 0) { + name = bus_errno_to_dbus(u->load_error); + message = strempty(strerror(-u->load_error)); + } else + name = message = ""; + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &name) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &message) || + !dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *connection, DBusMessage *message) { + DBusMessage *reply = NULL; + Manager *m = u->manager; + DBusError error; + JobType job_type = _JOB_TYPE_INVALID; + char *path = NULL; + bool reload_if_possible = false; + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Start")) + job_type = JOB_START; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Stop")) + job_type = JOB_STOP; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Reload")) + job_type = JOB_RELOAD; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Restart")) + job_type = JOB_RESTART; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "TryRestart")) + job_type = JOB_TRY_RESTART; + else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ReloadOrRestart")) { + reload_if_possible = true; + job_type = JOB_RESTART; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ReloadOrTryRestart")) { + reload_if_possible = true; + job_type = JOB_TRY_RESTART; + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Kill")) { + const char *swho, *smode; + int32_t signo; + KillMode mode; + KillWho who; + int r; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &swho, + DBUS_TYPE_STRING, &smode, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(swho)) + who = KILL_ALL; + else { + who = kill_who_from_string(swho); + if (who < 0) + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if (isempty(smode)) + mode = KILL_CONTROL_GROUP; + else { + mode = kill_mode_from_string(smode); + if (mode < 0) + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if ((r = unit_kill(u, who, mode, signo, &error)) < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "ResetFailed")) { + + unit_reset_failed(u); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + } else if (UNIT_VTABLE(u)->bus_message_handler) + return UNIT_VTABLE(u)->bus_message_handler(u, connection, message); + else + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (job_type != _JOB_TYPE_INVALID) { + const char *smode; + JobMode mode; + Job *j; + int r; + + if ((job_type == JOB_START && u->refuse_manual_start) || + (job_type == JOB_STOP && u->refuse_manual_stop) || + ((job_type == JOB_RESTART || job_type == JOB_TRY_RESTART) && + (u->refuse_manual_start || u->refuse_manual_stop))) { + dbus_set_error(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, may be requested by dependency only."); + return bus_send_error_reply(connection, message, &error, -EPERM); + } + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &smode, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (reload_if_possible && unit_can_reload(u)) { + if (job_type == JOB_RESTART) + job_type = JOB_RELOAD_OR_START; + else if (job_type == JOB_TRY_RESTART) + job_type = JOB_RELOAD; + } + + if ((mode = job_mode_from_string(smode)) == _JOB_MODE_INVALID) { + dbus_set_error(&error, BUS_ERROR_INVALID_JOB_MODE, "Job mode %s is invalid.", smode); + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if ((r = manager_add_job(m, job_type, u, mode, true, &error, &j)) < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!(path = job_dbus_path(j))) + goto oom; + + if (!dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto oom; + } + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + free(path); + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + free(path); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult bus_unit_message_handler(DBusConnection *connection, DBusMessage *message, void *data) { + Manager *m = data; + Unit *u; + int r; + DBusMessage *reply; + + assert(connection); + assert(message); + assert(m); + + if (streq(dbus_message_get_path(message), "/org/freedesktop/systemd1/unit")) { + /* Be nice to gdbus and return introspection data for our mid-level paths */ + + if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) { + char *introspection = NULL; + FILE *f; + Iterator i; + const char *k; + size_t size; + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + /* We roll our own introspection code here, instead of + * relying on bus_default_message_handler() because we + * need to generate our introspection string + * dynamically. */ + + if (!(f = open_memstream(&introspection, &size))) + goto oom; + + fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + "\n", f); + + fputs(BUS_INTROSPECTABLE_INTERFACE, f); + fputs(BUS_PEER_INTERFACE, f); + + HASHMAP_FOREACH_KEY(u, k, m->units, i) { + char *p; + + if (k != u->id) + continue; + + if (!(p = bus_path_escape(k))) { + fclose(f); + free(introspection); + goto oom; + } + + fprintf(f, "", p); + free(p); + } + + fputs("\n", f); + + if (ferror(f)) { + fclose(f); + free(introspection); + goto oom; + } + + fclose(f); + + if (!introspection) + goto oom; + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) { + free(introspection); + goto oom; + } + + free(introspection); + + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if ((r = manager_get_unit_from_dbus_path(m, dbus_message_get_path(message), &u)) < 0) { + + if (r == -ENOMEM) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (r == -ENOENT) { + DBusError e; + + dbus_error_init(&e); + dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown unit"); + return bus_send_error_reply(connection, message, &e, r); + } + + return bus_send_error_reply(connection, message, NULL, r); + } + + return bus_unit_message_dispatch(u, connection, message); + +oom: + if (reply) + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +const DBusObjectPathVTable bus_unit_vtable = { + .message_function = bus_unit_message_handler +}; + +void bus_unit_send_change_signal(Unit *u) { + char *p = NULL; + DBusMessage *m = NULL; + + assert(u); + + if (u->in_dbus_queue) { + LIST_REMOVE(Unit, dbus_queue, u->manager->dbus_unit_queue, u); + u->in_dbus_queue = false; + } + + if (!u->id) + return; + + if (!bus_has_subscriber(u->manager)) { + u->sent_dbus_new_signal = true; + return; + } + + if (!(p = unit_dbus_path(u))) + goto oom; + + if (u->sent_dbus_new_signal) { + /* Send a properties changed signal. First for the + * specific type, then for the generic unit. The + * clients may rely on this order to get atomic + * behaviour if needed. */ + + if (UNIT_VTABLE(u)->bus_invalidating_properties) { + + if (!(m = bus_properties_changed_new(p, + UNIT_VTABLE(u)->bus_interface, + UNIT_VTABLE(u)->bus_invalidating_properties))) + goto oom; + + if (bus_broadcast(u->manager, m) < 0) + goto oom; + + dbus_message_unref(m); + } + + if (!(m = bus_properties_changed_new(p, "org.freedesktop.systemd1.Unit", INVALIDATING_PROPERTIES))) + goto oom; + + } else { + /* Send a new signal */ + + if (!(m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitNew"))) + goto oom; + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &u->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + goto oom; + } + + if (bus_broadcast(u->manager, m) < 0) + goto oom; + + free(p); + dbus_message_unref(m); + + u->sent_dbus_new_signal = true; + + return; + +oom: + free(p); + + if (m) + dbus_message_unref(m); + + log_error("Failed to allocate unit change/new signal."); +} + +void bus_unit_send_removed_signal(Unit *u) { + char *p = NULL; + DBusMessage *m = NULL; + + assert(u); + + if (!bus_has_subscriber(u->manager)) + return; + + if (!u->sent_dbus_new_signal) + bus_unit_send_change_signal(u); + + if (!u->id) + return; + + if (!(p = unit_dbus_path(u))) + goto oom; + + if (!(m = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitRemoved"))) + goto oom; + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &u->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + goto oom; + + if (bus_broadcast(u->manager, m) < 0) + goto oom; + + free(p); + dbus_message_unref(m); + + return; + +oom: + free(p); + + if (m) + dbus_message_unref(m); + + log_error("Failed to allocate unit remove signal."); +} + +const BusProperty bus_unit_properties[] = { + { "Id", bus_property_append_string, "s", offsetof(Unit, id), true }, + { "Names", bus_unit_append_names, "as", 0 }, + { "Following", bus_unit_append_following, "s", 0 }, + { "Requires", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES]), true }, + { "RequiresOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES_OVERRIDABLE]), true }, + { "Requisite", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE]), true }, + { "RequisiteOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE_OVERRIDABLE]), true }, + { "Wants", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTS]), true }, + { "BindTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BIND_TO]), true }, + { "RequiredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY]), true }, + { "RequiredByOverridable",bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY_OVERRIDABLE]), true }, + { "WantedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTED_BY]), true }, + { "BoundBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BOUND_BY]), true }, + { "Conflicts", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTS]), true }, + { "ConflictedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTED_BY]), true }, + { "Before", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BEFORE]), true }, + { "After", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_AFTER]), true }, + { "OnFailure", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_ON_FAILURE]), true }, + { "Triggers", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERS]), true }, + { "TriggeredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]), true }, + { "PropagateReloadTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATE_RELOAD_TO]), true }, + { "PropagateReloadFrom", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATE_RELOAD_FROM]), true }, + { "Description", bus_unit_append_description, "s", 0 }, + { "LoadState", bus_unit_append_load_state, "s", offsetof(Unit, load_state) }, + { "ActiveState", bus_unit_append_active_state, "s", 0 }, + { "SubState", bus_unit_append_sub_state, "s", 0 }, + { "FragmentPath", bus_property_append_string, "s", offsetof(Unit, fragment_path), true }, + { "UnitFileState", bus_unit_append_file_state, "s", 0 }, + { "InactiveExitTimestamp",bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.realtime) }, + { "InactiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.monotonic) }, + { "ActiveEnterTimestamp", bus_property_append_usec, "t", offsetof(Unit, active_enter_timestamp.realtime) }, + { "ActiveEnterTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, active_enter_timestamp.monotonic) }, + { "ActiveExitTimestamp", bus_property_append_usec, "t", offsetof(Unit, active_exit_timestamp.realtime) }, + { "ActiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, active_exit_timestamp.monotonic) }, + { "InactiveEnterTimestamp", bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.realtime) }, + { "InactiveEnterTimestampMonotonic",bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.monotonic) }, + { "CanStart", bus_unit_append_can_start, "b", 0 }, + { "CanStop", bus_unit_append_can_stop, "b", 0 }, + { "CanReload", bus_unit_append_can_reload, "b", 0 }, + { "CanIsolate", bus_unit_append_can_isolate, "b", 0 }, + { "Job", bus_unit_append_job, "(uo)", 0 }, + { "StopWhenUnneeded", bus_property_append_bool, "b", offsetof(Unit, stop_when_unneeded) }, + { "RefuseManualStart", bus_property_append_bool, "b", offsetof(Unit, refuse_manual_start) }, + { "RefuseManualStop", bus_property_append_bool, "b", offsetof(Unit, refuse_manual_stop) }, + { "AllowIsolate", bus_property_append_bool, "b", offsetof(Unit, allow_isolate) }, + { "DefaultDependencies", bus_property_append_bool, "b", offsetof(Unit, default_dependencies) }, + { "OnFailureIsolate", bus_property_append_bool, "b", offsetof(Unit, on_failure_isolate) }, + { "IgnoreOnIsolate", bus_property_append_bool, "b", offsetof(Unit, ignore_on_isolate) }, + { "IgnoreOnSnapshot", bus_property_append_bool, "b", offsetof(Unit, ignore_on_snapshot) }, + { "DefaultControlGroup", bus_unit_append_default_cgroup, "s", 0 }, + { "ControlGroup", bus_unit_append_cgroups, "as", 0 }, + { "ControlGroupAttributes", bus_unit_append_cgroup_attrs,"a(sss)", 0 }, + { "NeedDaemonReload", bus_unit_append_need_daemon_reload, "b", 0 }, + { "JobTimeoutUSec", bus_property_append_usec, "t", offsetof(Unit, job_timeout) }, + { "ConditionTimestamp", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.realtime) }, + { "ConditionTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.monotonic) }, + { "ConditionResult", bus_property_append_bool, "b", offsetof(Unit, condition_result) }, + { "LoadError", bus_unit_append_load_error, "(ss)", 0 }, + { NULL, } +}; diff --git a/src/dbus-unit.h b/src/dbus-unit.h new file mode 100644 index 0000000..4f19a80 --- /dev/null +++ b/src/dbus-unit.h @@ -0,0 +1,139 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbusunithfoo +#define foodbusunithfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "manager.h" +#include "dbus-common.h" + +#define BUS_UNIT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define BUS_UNIT_INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.systemd1.Unit\0" + +extern const BusProperty bus_unit_properties[]; + +void bus_unit_send_change_signal(Unit *u); +void bus_unit_send_removed_signal(Unit *u); + +extern const DBusObjectPathVTable bus_unit_vtable; + +extern const char bus_unit_interface[]; + +#endif diff --git a/src/dbus.c b/src/dbus.c new file mode 100644 index 0000000..8e6e9fd --- /dev/null +++ b/src/dbus.c @@ -0,0 +1,1482 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "dbus.h" +#include "log.h" +#include "strv.h" +#include "cgroup.h" +#include "dbus-unit.h" +#include "dbus-job.h" +#include "dbus-manager.h" +#include "dbus-service.h" +#include "dbus-socket.h" +#include "dbus-target.h" +#include "dbus-device.h" +#include "dbus-mount.h" +#include "dbus-automount.h" +#include "dbus-snapshot.h" +#include "dbus-swap.h" +#include "dbus-timer.h" +#include "dbus-path.h" +#include "bus-errors.h" +#include "special.h" +#include "dbus-common.h" + +#define CONNECTIONS_MAX 52 + +/* Well-known address (http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-types) */ +#define DBUS_SYSTEM_BUS_DEFAULT_ADDRESS "unix:path=/var/run/dbus/system_bus_socket" +/* Only used as a fallback */ +#define DBUS_SESSION_BUS_DEFAULT_ADDRESS "autolaunch:" + +static const char bus_properties_interface[] = BUS_PROPERTIES_INTERFACE; +static const char bus_introspectable_interface[] = BUS_INTROSPECTABLE_INTERFACE; + +const char *const bus_interface_table[] = { + "org.freedesktop.DBus.Properties", bus_properties_interface, + "org.freedesktop.DBus.Introspectable", bus_introspectable_interface, + "org.freedesktop.systemd1.Manager", bus_manager_interface, + "org.freedesktop.systemd1.Job", bus_job_interface, + "org.freedesktop.systemd1.Unit", bus_unit_interface, + "org.freedesktop.systemd1.Service", bus_service_interface, + "org.freedesktop.systemd1.Socket", bus_socket_interface, + "org.freedesktop.systemd1.Target", bus_target_interface, + "org.freedesktop.systemd1.Device", bus_device_interface, + "org.freedesktop.systemd1.Mount", bus_mount_interface, + "org.freedesktop.systemd1.Automount", bus_automount_interface, + "org.freedesktop.systemd1.Snapshot", bus_snapshot_interface, + "org.freedesktop.systemd1.Swap", bus_swap_interface, + "org.freedesktop.systemd1.Timer", bus_timer_interface, + "org.freedesktop.systemd1.Path", bus_path_interface, + NULL +}; + +static void bus_done_api(Manager *m); +static void bus_done_system(Manager *m); +static void bus_done_private(Manager *m); +static void shutdown_connection(Manager *m, DBusConnection *c); + +static void bus_dispatch_status(DBusConnection *bus, DBusDispatchStatus status, void *data) { + Manager *m = data; + + assert(bus); + assert(m); + + /* We maintain two sets, one for those connections where we + * requested a dispatch, and another where we didn't. And then, + * we move the connections between the two sets. */ + + if (status == DBUS_DISPATCH_COMPLETE) + set_move_one(m->bus_connections, m->bus_connections_for_dispatch, bus); + else + set_move_one(m->bus_connections_for_dispatch, m->bus_connections, bus); +} + +void bus_watch_event(Manager *m, Watch *w, int events) { + assert(m); + assert(w); + + /* This is called by the event loop whenever there is + * something happening on D-Bus' file handles. */ + + if (!dbus_watch_get_enabled(w->data.bus_watch)) + return; + + dbus_watch_handle(w->data.bus_watch, bus_events_to_flags(events)); +} + +static dbus_bool_t bus_add_watch(DBusWatch *bus_watch, void *data) { + Manager *m = data; + Watch *w; + struct epoll_event ev; + + assert(bus_watch); + assert(m); + + if (!(w = new0(Watch, 1))) + return FALSE; + + w->fd = dbus_watch_get_unix_fd(bus_watch); + w->type = WATCH_DBUS_WATCH; + w->data.bus_watch = bus_watch; + + zero(ev); + ev.events = bus_flags_to_events(bus_watch); + ev.data.ptr = w; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0) { + + if (errno != EEXIST) { + free(w); + return FALSE; + } + + /* Hmm, bloody D-Bus creates multiple watches on the + * same fd. epoll() does not like that. As a dirty + * hack we simply dup() the fd and hence get a second + * one we can safely add to the epoll(). */ + + if ((w->fd = dup(w->fd)) < 0) { + free(w); + return FALSE; + } + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0) { + close_nointr_nofail(w->fd); + free(w); + return FALSE; + } + + w->fd_is_dupped = true; + } + + dbus_watch_set_data(bus_watch, w, NULL); + + return TRUE; +} + +static void bus_remove_watch(DBusWatch *bus_watch, void *data) { + Manager *m = data; + Watch *w; + + assert(bus_watch); + assert(m); + + w = dbus_watch_get_data(bus_watch); + if (!w) + return; + + assert(w->type == WATCH_DBUS_WATCH); + assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0); + + if (w->fd_is_dupped) + close_nointr_nofail(w->fd); + + free(w); +} + +static void bus_toggle_watch(DBusWatch *bus_watch, void *data) { + Manager *m = data; + Watch *w; + struct epoll_event ev; + + assert(bus_watch); + assert(m); + + w = dbus_watch_get_data(bus_watch); + if (!w) + return; + + assert(w->type == WATCH_DBUS_WATCH); + + zero(ev); + ev.events = bus_flags_to_events(bus_watch); + ev.data.ptr = w; + + assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_MOD, w->fd, &ev) == 0); +} + +static int bus_timeout_arm(Manager *m, Watch *w) { + struct itimerspec its; + + assert(m); + assert(w); + + zero(its); + + if (dbus_timeout_get_enabled(w->data.bus_timeout)) { + timespec_store(&its.it_value, dbus_timeout_get_interval(w->data.bus_timeout) * USEC_PER_MSEC); + its.it_interval = its.it_value; + } + + if (timerfd_settime(w->fd, 0, &its, NULL) < 0) + return -errno; + + return 0; +} + +void bus_timeout_event(Manager *m, Watch *w, int events) { + assert(m); + assert(w); + + /* This is called by the event loop whenever there is + * something happening on D-Bus' file handles. */ + + if (!(dbus_timeout_get_enabled(w->data.bus_timeout))) + return; + + dbus_timeout_handle(w->data.bus_timeout); +} + +static dbus_bool_t bus_add_timeout(DBusTimeout *timeout, void *data) { + Manager *m = data; + Watch *w; + struct epoll_event ev; + + assert(timeout); + assert(m); + + if (!(w = new0(Watch, 1))) + return FALSE; + + if ((w->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) + goto fail; + + w->type = WATCH_DBUS_TIMEOUT; + w->data.bus_timeout = timeout; + + if (bus_timeout_arm(m, w) < 0) + goto fail; + + zero(ev); + ev.events = EPOLLIN; + ev.data.ptr = w; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0) + goto fail; + + dbus_timeout_set_data(timeout, w, NULL); + + return TRUE; + +fail: + if (w->fd >= 0) + close_nointr_nofail(w->fd); + + free(w); + return FALSE; +} + +static void bus_remove_timeout(DBusTimeout *timeout, void *data) { + Manager *m = data; + Watch *w; + + assert(timeout); + assert(m); + + w = dbus_timeout_get_data(timeout); + if (!w) + return; + + assert(w->type == WATCH_DBUS_TIMEOUT); + + assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0); + close_nointr_nofail(w->fd); + free(w); +} + +static void bus_toggle_timeout(DBusTimeout *timeout, void *data) { + Manager *m = data; + Watch *w; + int r; + + assert(timeout); + assert(m); + + w = dbus_timeout_get_data(timeout); + if (!w) + return; + + assert(w->type == WATCH_DBUS_TIMEOUT); + + if ((r = bus_timeout_arm(m, w)) < 0) + log_error("Failed to rearm timer: %s", strerror(-r)); +} + +static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) { + Manager *m = data; + DBusError error; + DBusMessage *reply = NULL; + + assert(connection); + assert(message); + assert(m); + + dbus_error_init(&error); + + if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL || + dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL) + log_debug("Got D-Bus request: %s.%s() on %s", + dbus_message_get_interface(message), + dbus_message_get_member(message), + dbus_message_get_path(message)); + + if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { + log_debug("API D-Bus connection terminated."); + bus_done_api(m); + + } else if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) { + const char *name, *old_owner, *new_owner; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &old_owner, + DBUS_TYPE_STRING, &new_owner, + DBUS_TYPE_INVALID)) + log_error("Failed to parse NameOwnerChanged message: %s", bus_error_message(&error)); + else { + if (set_remove(BUS_CONNECTION_SUBSCRIBED(m, connection), (char*) name)) + log_debug("Subscription client vanished: %s (left: %u)", name, set_size(BUS_CONNECTION_SUBSCRIBED(m, connection))); + + if (old_owner[0] == 0) + old_owner = NULL; + + if (new_owner[0] == 0) + new_owner = NULL; + + manager_dispatch_bus_name_owner_changed(m, name, old_owner, new_owner); + } + } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Activator", "ActivationRequest")) { + const char *name; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + log_error("Failed to parse ActivationRequest message: %s", bus_error_message(&error)); + else { + int r; + Unit *u; + + log_debug("Got D-Bus activation request for %s", name); + + if (manager_unit_pending_inactive(m, SPECIAL_DBUS_SERVICE) || + manager_unit_pending_inactive(m, SPECIAL_DBUS_SOCKET)) { + r = -EADDRNOTAVAIL; + dbus_set_error(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down."); + } else { + r = manager_load_unit(m, name, NULL, &error, &u); + + if (r >= 0 && u->refuse_manual_start) + r = -EPERM; + + if (r >= 0) + r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL); + } + + if (r < 0) { + const char *id, *text; + + log_debug("D-Bus activation failed for %s: %s", name, strerror(-r)); + + if (!(reply = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure"))) + goto oom; + + id = error.name ? error.name : bus_errno_to_dbus(r); + text = bus_error(&error, r); + + if (!dbus_message_set_destination(reply, DBUS_SERVICE_DBUS) || + !dbus_message_append_args(reply, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &id, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) + goto oom; + } + + /* On success we don't do anything, the service will be spawned now */ + } + } + + dbus_error_free(&error); + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult system_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) { + Manager *m = data; + DBusError error; + + assert(connection); + assert(message); + assert(m); + + dbus_error_init(&error); + + if (m->api_bus != m->system_bus && + (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL || + dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)) + log_debug("Got D-Bus request on system bus: %s.%s() on %s", + dbus_message_get_interface(message), + dbus_message_get_member(message), + dbus_message_get_path(message)); + + if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { + log_debug("System D-Bus connection terminated."); + bus_done_system(m); + + } else if (m->running_as != MANAGER_SYSTEM && + dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) { + + const char *cgroup; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &cgroup, + DBUS_TYPE_INVALID)) + log_error("Failed to parse Released message: %s", bus_error_message(&error)); + else + cgroup_notify_empty(m, cgroup); + } + + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult private_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) { + Manager *m = data; + DBusError error; + + assert(connection); + assert(message); + assert(m); + + dbus_error_init(&error); + + if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL || + dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL) + log_debug("Got D-Bus request: %s.%s() on %s", + dbus_message_get_interface(message), + dbus_message_get_member(message), + dbus_message_get_path(message)); + + if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) + shutdown_connection(m, connection); + else if (m->running_as == MANAGER_SYSTEM && + dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) { + + const char *cgroup; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &cgroup, + DBUS_TYPE_INVALID)) + log_error("Failed to parse Released message: %s", bus_error_message(&error)); + else + cgroup_notify_empty(m, cgroup); + + /* Forward the message to the system bus, so that user + * instances are notified as well */ + + if (m->system_bus) + dbus_connection_send(m->system_bus, message, NULL); + } + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +unsigned bus_dispatch(Manager *m) { + DBusConnection *c; + + assert(m); + + if (m->queued_message) { + /* If we cannot get rid of this message we won't + * dispatch any D-Bus messages, so that we won't end + * up wanting to queue another message. */ + + if (m->queued_message_connection) + if (!dbus_connection_send(m->queued_message_connection, m->queued_message, NULL)) + return 0; + + dbus_message_unref(m->queued_message); + m->queued_message = NULL; + m->queued_message_connection = NULL; + } + + if ((c = set_first(m->bus_connections_for_dispatch))) { + if (dbus_connection_dispatch(c) == DBUS_DISPATCH_COMPLETE) + set_move_one(m->bus_connections, m->bus_connections_for_dispatch, c); + + return 1; + } + + return 0; +} + +static void request_name_pending_cb(DBusPendingCall *pending, void *userdata) { + DBusMessage *reply; + DBusError error; + + dbus_error_init(&error); + + assert_se(reply = dbus_pending_call_steal_reply(pending)); + + switch (dbus_message_get_type(reply)) { + + case DBUS_MESSAGE_TYPE_ERROR: + + assert_se(dbus_set_error_from_message(&error, reply)); + log_warning("RequestName() failed: %s", bus_error_message(&error)); + break; + + case DBUS_MESSAGE_TYPE_METHOD_RETURN: { + uint32_t r; + + if (!dbus_message_get_args(reply, + &error, + DBUS_TYPE_UINT32, &r, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse RequestName() reply: %s", bus_error_message(&error)); + break; + } + + if (r == 1) + log_debug("Successfully acquired name."); + else + log_error("Name already owned."); + + break; + } + + default: + assert_not_reached("Invalid reply message"); + } + + dbus_message_unref(reply); + dbus_error_free(&error); +} + +static int request_name(Manager *m) { + const char *name = "org.freedesktop.systemd1"; + /* Allow replacing of our name, to ease implementation of + * reexecution, where we keep the old connection open until + * after the new connection is set up and the name installed + * to allow clients to synchronously wait for reexecution to + * finish */ + uint32_t flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT|DBUS_NAME_FLAG_REPLACE_EXISTING; + DBusMessage *message = NULL; + DBusPendingCall *pending = NULL; + + if (!(message = dbus_message_new_method_call( + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "RequestName"))) + goto oom; + + if (!dbus_message_append_args( + message, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_UINT32, &flags, + DBUS_TYPE_INVALID)) + goto oom; + + if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1)) + goto oom; + + if (!dbus_pending_call_set_notify(pending, request_name_pending_cb, m, NULL)) + goto oom; + + dbus_message_unref(message); + dbus_pending_call_unref(pending); + + /* We simple ask for the name and don't wait for it. Sooner or + * later we'll have it. */ + + return 0; + +oom: + if (pending) { + dbus_pending_call_cancel(pending); + dbus_pending_call_unref(pending); + } + + if (message) + dbus_message_unref(message); + + return -ENOMEM; +} + +static void query_name_list_pending_cb(DBusPendingCall *pending, void *userdata) { + DBusMessage *reply; + DBusError error; + Manager *m = userdata; + + assert(m); + + dbus_error_init(&error); + + assert_se(reply = dbus_pending_call_steal_reply(pending)); + + switch (dbus_message_get_type(reply)) { + + case DBUS_MESSAGE_TYPE_ERROR: + + assert_se(dbus_set_error_from_message(&error, reply)); + log_warning("ListNames() failed: %s", bus_error_message(&error)); + break; + + case DBUS_MESSAGE_TYPE_METHOD_RETURN: { + int r; + char **l; + + if ((r = bus_parse_strv(reply, &l)) < 0) + log_warning("Failed to parse ListNames() reply: %s", strerror(-r)); + else { + char **t; + + STRV_FOREACH(t, l) + /* This is a bit hacky, we say the + * owner of the name is the name + * itself, because we don't want the + * extra traffic to figure out the + * real owner. */ + manager_dispatch_bus_name_owner_changed(m, *t, NULL, *t); + + strv_free(l); + } + + break; + } + + default: + assert_not_reached("Invalid reply message"); + } + + dbus_message_unref(reply); + dbus_error_free(&error); +} + +static int query_name_list(Manager *m) { + DBusMessage *message = NULL; + DBusPendingCall *pending = NULL; + + /* Asks for the currently installed bus names */ + + if (!(message = dbus_message_new_method_call( + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "ListNames"))) + goto oom; + + if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1)) + goto oom; + + if (!dbus_pending_call_set_notify(pending, query_name_list_pending_cb, m, NULL)) + goto oom; + + dbus_message_unref(message); + dbus_pending_call_unref(pending); + + /* We simple ask for the list and don't wait for it. Sooner or + * later we'll get it. */ + + return 0; + +oom: + if (pending) { + dbus_pending_call_cancel(pending); + dbus_pending_call_unref(pending); + } + + if (message) + dbus_message_unref(message); + + return -ENOMEM; +} + +static int bus_setup_loop(Manager *m, DBusConnection *bus) { + assert(m); + assert(bus); + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + if (!dbus_connection_set_watch_functions(bus, bus_add_watch, bus_remove_watch, bus_toggle_watch, m, NULL) || + !dbus_connection_set_timeout_functions(bus, bus_add_timeout, bus_remove_timeout, bus_toggle_timeout, m, NULL)) { + log_error("Not enough memory"); + return -ENOMEM; + } + + if (set_put(m->bus_connections_for_dispatch, bus) < 0) { + log_error("Not enough memory"); + return -ENOMEM; + } + + dbus_connection_set_dispatch_status_function(bus, bus_dispatch_status, m, NULL); + return 0; +} + +static dbus_bool_t allow_only_same_user(DBusConnection *connection, unsigned long uid, void *data) { + return uid == 0 || uid == geteuid(); +} + +static void bus_new_connection( + DBusServer *server, + DBusConnection *new_connection, + void *data) { + + Manager *m = data; + + assert(m); + + if (set_size(m->bus_connections) >= CONNECTIONS_MAX) { + log_error("Too many concurrent connections."); + return; + } + + dbus_connection_set_unix_user_function(new_connection, allow_only_same_user, NULL, NULL); + + if (bus_setup_loop(m, new_connection) < 0) + return; + + if (!dbus_connection_register_object_path(new_connection, "/org/freedesktop/systemd1", &bus_manager_vtable, m) || + !dbus_connection_register_fallback(new_connection, "/org/freedesktop/systemd1/unit", &bus_unit_vtable, m) || + !dbus_connection_register_fallback(new_connection, "/org/freedesktop/systemd1/job", &bus_job_vtable, m) || + !dbus_connection_add_filter(new_connection, private_bus_message_filter, m, NULL)) { + log_error("Not enough memory."); + return; + } + + log_debug("Accepted connection on private bus."); + + dbus_connection_ref(new_connection); +} + +static int init_registered_system_bus(Manager *m) { + char *id; + + if (!dbus_connection_add_filter(m->system_bus, system_bus_message_filter, m, NULL)) { + log_error("Not enough memory"); + return -ENOMEM; + } + + if (m->running_as != MANAGER_SYSTEM) { + DBusError error; + + dbus_error_init(&error); + + dbus_bus_add_match(m->system_bus, + "type='signal'," + "interface='org.freedesktop.systemd1.Agent'," + "member='Released'," + "path='/org/freedesktop/systemd1/agent'", + &error); + + if (dbus_error_is_set(&error)) { + log_error("Failed to register match: %s", bus_error_message(&error)); + dbus_error_free(&error); + return -1; + } + } + + log_debug("Successfully connected to system D-Bus bus %s as %s", + strnull((id = dbus_connection_get_server_id(m->system_bus))), + strnull(dbus_bus_get_unique_name(m->system_bus))); + dbus_free(id); + + return 0; +} + +static int init_registered_api_bus(Manager *m) { + int r; + + if (!dbus_connection_register_object_path(m->api_bus, "/org/freedesktop/systemd1", &bus_manager_vtable, m) || + !dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/unit", &bus_unit_vtable, m) || + !dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/job", &bus_job_vtable, m) || + !dbus_connection_add_filter(m->api_bus, api_bus_message_filter, m, NULL)) { + log_error("Not enough memory"); + return -ENOMEM; + } + + /* Get NameOwnerChange messages */ + dbus_bus_add_match(m->api_bus, + "type='signal'," + "sender='"DBUS_SERVICE_DBUS"'," + "interface='"DBUS_INTERFACE_DBUS"'," + "member='NameOwnerChanged'," + "path='"DBUS_PATH_DBUS"'", + NULL); + + /* Get activation requests */ + dbus_bus_add_match(m->api_bus, + "type='signal'," + "sender='"DBUS_SERVICE_DBUS"'," + "interface='org.freedesktop.systemd1.Activator'," + "member='ActivationRequest'," + "path='"DBUS_PATH_DBUS"'", + NULL); + + r = request_name(m); + if (r < 0) + return r; + + r = query_name_list(m); + if (r < 0) + return r; + + if (m->running_as == MANAGER_USER) { + char *id; + log_debug("Successfully connected to API D-Bus bus %s as %s", + strnull((id = dbus_connection_get_server_id(m->api_bus))), + strnull(dbus_bus_get_unique_name(m->api_bus))); + dbus_free(id); + } else + log_debug("Successfully initialized API on the system bus"); + + return 0; +} + +static void bus_register_cb(DBusPendingCall *pending, void *userdata) { + Manager *m = userdata; + DBusConnection **conn; + DBusMessage *reply; + DBusError error; + const char *name; + int r = 0; + + dbus_error_init(&error); + + conn = dbus_pending_call_get_data(pending, m->conn_data_slot); + assert(conn == &m->system_bus || conn == &m->api_bus); + + reply = dbus_pending_call_steal_reply(pending); + + switch (dbus_message_get_type(reply)) { + case DBUS_MESSAGE_TYPE_ERROR: + assert_se(dbus_set_error_from_message(&error, reply)); + log_warning("Failed to register to bus: %s", bus_error_message(&error)); + r = -1; + break; + case DBUS_MESSAGE_TYPE_METHOD_RETURN: + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse Hello reply: %s", bus_error_message(&error)); + r = -1; + break; + } + + log_debug("Received name %s in reply to Hello", name); + if (!dbus_bus_set_unique_name(*conn, name)) { + log_error("Failed to set unique name"); + r = -1; + break; + } + + if (conn == &m->system_bus) { + r = init_registered_system_bus(m); + if (r == 0 && m->running_as == MANAGER_SYSTEM) + r = init_registered_api_bus(m); + } else + r = init_registered_api_bus(m); + + break; + default: + assert_not_reached("Invalid reply message"); + } + + dbus_message_unref(reply); + dbus_error_free(&error); + + if (r < 0) { + if (conn == &m->system_bus) { + log_debug("Failed setting up the system bus"); + bus_done_system(m); + } else { + log_debug("Failed setting up the API bus"); + bus_done_api(m); + } + } +} + +static int manager_bus_async_register(Manager *m, DBusConnection **conn) { + DBusMessage *message = NULL; + DBusPendingCall *pending = NULL; + + message = dbus_message_new_method_call(DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "Hello"); + if (!message) + goto oom; + + if (!dbus_connection_send_with_reply(*conn, message, &pending, -1)) + goto oom; + + if (!dbus_pending_call_set_data(pending, m->conn_data_slot, conn, NULL)) + goto oom; + + if (!dbus_pending_call_set_notify(pending, bus_register_cb, m, NULL)) + goto oom; + + dbus_message_unref(message); + dbus_pending_call_unref(pending); + + return 0; +oom: + if (pending) { + dbus_pending_call_cancel(pending); + dbus_pending_call_unref(pending); + } + + if (message) + dbus_message_unref(message); + + return -ENOMEM; +} + +static DBusConnection* manager_bus_connect_private(Manager *m, DBusBusType type) { + const char *address; + DBusConnection *connection; + DBusError error; + + switch (type) { + case DBUS_BUS_SYSTEM: + address = getenv("DBUS_SYSTEM_BUS_ADDRESS"); + if (!address || !address[0]) + address = DBUS_SYSTEM_BUS_DEFAULT_ADDRESS; + break; + case DBUS_BUS_SESSION: + address = getenv("DBUS_SESSION_BUS_ADDRESS"); + if (!address || !address[0]) + address = DBUS_SESSION_BUS_DEFAULT_ADDRESS; + break; + default: + assert_not_reached("Invalid bus type"); + } + + dbus_error_init(&error); + + connection = dbus_connection_open_private(address, &error); + if (!connection) { + log_warning("Failed to open private bus connection: %s", bus_error_message(&error)); + goto fail; + } + + return connection; +fail: + if (connection) + dbus_connection_close(connection); + dbus_error_free(&error); + return NULL; +} + +static int bus_init_system(Manager *m) { + int r; + + if (m->system_bus) + return 0; + + m->system_bus = manager_bus_connect_private(m, DBUS_BUS_SYSTEM); + if (!m->system_bus) { + log_debug("Failed to connect to system D-Bus, retrying later"); + r = 0; + goto fail; + } + + r = bus_setup_loop(m, m->system_bus); + if (r < 0) + goto fail; + + r = manager_bus_async_register(m, &m->system_bus); + if (r < 0) + goto fail; + + return 0; +fail: + bus_done_system(m); + + return r; +} + +static int bus_init_api(Manager *m) { + int r; + + if (m->api_bus) + return 0; + + if (m->running_as == MANAGER_SYSTEM) { + m->api_bus = m->system_bus; + /* In this mode there is no distinct connection to the API bus, + * the API is published on the system bus. + * bus_register_cb() is aware of that and will init the API + * when the system bus gets registered. + * No need to setup anything here. */ + return 0; + } + + m->api_bus = manager_bus_connect_private(m, DBUS_BUS_SESSION); + if (!m->api_bus) { + log_debug("Failed to connect to API D-Bus, retrying later"); + r = 0; + goto fail; + } + + r = bus_setup_loop(m, m->api_bus); + if (r < 0) + goto fail; + + r = manager_bus_async_register(m, &m->api_bus); + if (r < 0) + goto fail; + + return 0; +fail: + bus_done_api(m); + + return r; +} + +static int bus_init_private(Manager *m) { + DBusError error; + int r; + const char *const external_only[] = { + "EXTERNAL", + NULL + }; + + assert(m); + + dbus_error_init(&error); + + if (m->private_bus) + return 0; + + if (m->running_as == MANAGER_SYSTEM) { + + /* We want the private bus only when running as init */ + if (getpid() != 1) + return 0; + + unlink("/run/systemd/private"); + m->private_bus = dbus_server_listen("unix:path=/run/systemd/private", &error); + } else { + const char *e; + char *p; + + e = getenv("XDG_RUNTIME_DIR"); + if (!e) + return 0; + + if (asprintf(&p, "unix:path=%s/systemd/private", e) < 0) { + log_error("Not enough memory"); + r = -ENOMEM; + goto fail; + } + + mkdir_parents(p+10, 0755); + unlink(p+10); + m->private_bus = dbus_server_listen(p, &error); + free(p); + } + + if (!m->private_bus) { + log_error("Failed to create private D-Bus server: %s", bus_error_message(&error)); + r = -EIO; + goto fail; + } + + if (!dbus_server_set_auth_mechanisms(m->private_bus, (const char**) external_only) || + !dbus_server_set_watch_functions(m->private_bus, bus_add_watch, bus_remove_watch, bus_toggle_watch, m, NULL) || + !dbus_server_set_timeout_functions(m->private_bus, bus_add_timeout, bus_remove_timeout, bus_toggle_timeout, m, NULL)) { + log_error("Not enough memory"); + r = -ENOMEM; + goto fail; + } + + dbus_server_set_new_connection_function(m->private_bus, bus_new_connection, m, NULL); + + log_debug("Successfully created private D-Bus server."); + + return 0; + +fail: + bus_done_private(m); + dbus_error_free(&error); + + return r; +} + +int bus_init(Manager *m, bool try_bus_connect) { + int r; + + if (set_ensure_allocated(&m->bus_connections, trivial_hash_func, trivial_compare_func) < 0 || + set_ensure_allocated(&m->bus_connections_for_dispatch, trivial_hash_func, trivial_compare_func) < 0) + goto oom; + + if (m->name_data_slot < 0) + if (!dbus_pending_call_allocate_data_slot(&m->name_data_slot)) + goto oom; + + if (m->conn_data_slot < 0) + if (!dbus_pending_call_allocate_data_slot(&m->conn_data_slot)) + goto oom; + + if (m->subscribed_data_slot < 0) + if (!dbus_connection_allocate_data_slot(&m->subscribed_data_slot)) + goto oom; + + if (try_bus_connect) { + if ((r = bus_init_system(m)) < 0 || + (r = bus_init_api(m)) < 0) + return r; + } + + if ((r = bus_init_private(m)) < 0) + return r; + + return 0; +oom: + log_error("Not enough memory"); + return -ENOMEM; +} + +static void shutdown_connection(Manager *m, DBusConnection *c) { + Set *s; + Job *j; + Iterator i; + + HASHMAP_FOREACH(j, m->jobs, i) + if (j->bus == c) { + free(j->bus_client); + j->bus_client = NULL; + + j->bus = NULL; + } + + set_remove(m->bus_connections, c); + set_remove(m->bus_connections_for_dispatch, c); + + if ((s = BUS_CONNECTION_SUBSCRIBED(m, c))) { + char *t; + + while ((t = set_steal_first(s))) + free(t); + + set_free(s); + } + + if (m->queued_message_connection == c) { + m->queued_message_connection = NULL; + + if (m->queued_message) { + dbus_message_unref(m->queued_message); + m->queued_message = NULL; + } + } + + dbus_connection_set_dispatch_status_function(c, NULL, NULL, NULL); + /* system manager cannot afford to block on DBus */ + if (m->running_as != MANAGER_SYSTEM) + dbus_connection_flush(c); + dbus_connection_close(c); + dbus_connection_unref(c); +} + +static void bus_done_api(Manager *m) { + if (!m->api_bus) + return; + + if (m->running_as == MANAGER_USER) + shutdown_connection(m, m->api_bus); + + m->api_bus = NULL; + + if (m->queued_message) { + dbus_message_unref(m->queued_message); + m->queued_message = NULL; + } +} + +static void bus_done_system(Manager *m) { + if (!m->system_bus) + return; + + if (m->running_as == MANAGER_SYSTEM) + bus_done_api(m); + + shutdown_connection(m, m->system_bus); + m->system_bus = NULL; +} + +static void bus_done_private(Manager *m) { + if (!m->private_bus) + return; + + dbus_server_disconnect(m->private_bus); + dbus_server_unref(m->private_bus); + m->private_bus = NULL; +} + +void bus_done(Manager *m) { + DBusConnection *c; + + bus_done_api(m); + bus_done_system(m); + bus_done_private(m); + + while ((c = set_steal_first(m->bus_connections))) + shutdown_connection(m, c); + + while ((c = set_steal_first(m->bus_connections_for_dispatch))) + shutdown_connection(m, c); + + set_free(m->bus_connections); + set_free(m->bus_connections_for_dispatch); + + if (m->name_data_slot >= 0) + dbus_pending_call_free_data_slot(&m->name_data_slot); + + if (m->conn_data_slot >= 0) + dbus_pending_call_free_data_slot(&m->conn_data_slot); + + if (m->subscribed_data_slot >= 0) + dbus_connection_free_data_slot(&m->subscribed_data_slot); +} + +static void query_pid_pending_cb(DBusPendingCall *pending, void *userdata) { + Manager *m = userdata; + DBusMessage *reply; + DBusError error; + const char *name; + + dbus_error_init(&error); + + assert_se(name = BUS_PENDING_CALL_NAME(m, pending)); + assert_se(reply = dbus_pending_call_steal_reply(pending)); + + switch (dbus_message_get_type(reply)) { + + case DBUS_MESSAGE_TYPE_ERROR: + + assert_se(dbus_set_error_from_message(&error, reply)); + log_warning("GetConnectionUnixProcessID() failed: %s", bus_error_message(&error)); + break; + + case DBUS_MESSAGE_TYPE_METHOD_RETURN: { + uint32_t r; + + if (!dbus_message_get_args(reply, + &error, + DBUS_TYPE_UINT32, &r, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse GetConnectionUnixProcessID() reply: %s", bus_error_message(&error)); + break; + } + + manager_dispatch_bus_query_pid_done(m, name, (pid_t) r); + break; + } + + default: + assert_not_reached("Invalid reply message"); + } + + dbus_message_unref(reply); + dbus_error_free(&error); +} + +int bus_query_pid(Manager *m, const char *name) { + DBusMessage *message = NULL; + DBusPendingCall *pending = NULL; + char *n = NULL; + + assert(m); + assert(name); + + if (!(message = dbus_message_new_method_call( + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetConnectionUnixProcessID"))) + goto oom; + + if (!(dbus_message_append_args( + message, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID))) + goto oom; + + if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1)) + goto oom; + + if (!(n = strdup(name))) + goto oom; + + if (!dbus_pending_call_set_data(pending, m->name_data_slot, n, free)) + goto oom; + + n = NULL; + + if (!dbus_pending_call_set_notify(pending, query_pid_pending_cb, m, NULL)) + goto oom; + + dbus_message_unref(message); + dbus_pending_call_unref(pending); + + return 0; + +oom: + free(n); + + if (pending) { + dbus_pending_call_cancel(pending); + dbus_pending_call_unref(pending); + } + + if (message) + dbus_message_unref(message); + + return -ENOMEM; +} + +int bus_broadcast(Manager *m, DBusMessage *message) { + bool oom = false; + Iterator i; + DBusConnection *c; + + assert(m); + assert(message); + + SET_FOREACH(c, m->bus_connections_for_dispatch, i) + if (c != m->system_bus || m->running_as == MANAGER_SYSTEM) + oom = !dbus_connection_send(c, message, NULL); + + SET_FOREACH(c, m->bus_connections, i) + if (c != m->system_bus || m->running_as == MANAGER_SYSTEM) + oom = !dbus_connection_send(c, message, NULL); + + return oom ? -ENOMEM : 0; +} + +bool bus_has_subscriber(Manager *m) { + Iterator i; + DBusConnection *c; + + assert(m); + + SET_FOREACH(c, m->bus_connections_for_dispatch, i) + if (bus_connection_has_subscriber(m, c)) + return true; + + SET_FOREACH(c, m->bus_connections, i) + if (bus_connection_has_subscriber(m, c)) + return true; + + return false; +} + +bool bus_connection_has_subscriber(Manager *m, DBusConnection *c) { + assert(m); + assert(c); + + return !set_isempty(BUS_CONNECTION_SUBSCRIBED(m, c)); +} + +int bus_fdset_add_all(Manager *m, FDSet *fds) { + Iterator i; + DBusConnection *c; + + assert(m); + assert(fds); + + /* When we are about to reexecute we add all D-Bus fds to the + * set to pass over to the newly executed systemd. They won't + * be used there however, except that they are closed at the + * very end of deserialization, those making it possible for + * clients to synchronously wait for systemd to reexec by + * simply waiting for disconnection */ + + SET_FOREACH(c, m->bus_connections_for_dispatch, i) { + int fd; + + if (dbus_connection_get_unix_fd(c, &fd)) { + fd = fdset_put_dup(fds, fd); + + if (fd < 0) + return fd; + } + } + + SET_FOREACH(c, m->bus_connections, i) { + int fd; + + if (dbus_connection_get_unix_fd(c, &fd)) { + fd = fdset_put_dup(fds, fd); + + if (fd < 0) + return fd; + } + } + + return 0; +} + +void bus_broadcast_finished( + Manager *m, + usec_t kernel_usec, + usec_t initrd_usec, + usec_t userspace_usec, + usec_t total_usec) { + + DBusMessage *message; + + assert(m); + + message = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished"); + if (!message) { + log_error("Out of memory."); + return; + } + + assert_cc(sizeof(usec_t) == sizeof(uint64_t)); + if (!dbus_message_append_args(message, + DBUS_TYPE_UINT64, &kernel_usec, + DBUS_TYPE_UINT64, &initrd_usec, + DBUS_TYPE_UINT64, &userspace_usec, + DBUS_TYPE_UINT64, &total_usec, + DBUS_TYPE_INVALID)) { + log_error("Out of memory."); + goto finish; + } + + + if (bus_broadcast(m, message) < 0) { + log_error("Out of memory."); + goto finish; + } + +finish: + if (message) + dbus_message_unref(message); +} diff --git a/src/dbus.h b/src/dbus.h new file mode 100644 index 0000000..bd539d0 --- /dev/null +++ b/src/dbus.h @@ -0,0 +1,53 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodbushfoo +#define foodbushfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "manager.h" + +int bus_init(Manager *m, bool try_bus_connect); +void bus_done(Manager *m); + +unsigned bus_dispatch(Manager *m); + +void bus_watch_event(Manager *m, Watch *w, int events); +void bus_timeout_event(Manager *m, Watch *w, int events); + +int bus_query_pid(Manager *m, const char *name); + +int bus_broadcast(Manager *m, DBusMessage *message); + +bool bus_has_subscriber(Manager *m); +bool bus_connection_has_subscriber(Manager *m, DBusConnection *c); + +int bus_fdset_add_all(Manager *m, FDSet *fds); + +void bus_broadcast_finished(Manager *m, usec_t kernel_usec, usec_t initrd_usec, usec_t userspace_usec, usec_t total_usec); + +#define BUS_CONNECTION_SUBSCRIBED(m, c) dbus_connection_get_data((c), (m)->subscribed_data_slot) +#define BUS_PENDING_CALL_NAME(m, p) dbus_pending_call_get_data((p), (m)->name_data_slot) + +extern const char * const bus_interface_table[]; + +#endif diff --git a/src/def.h b/src/def.h new file mode 100644 index 0000000..20aaa7c --- /dev/null +++ b/src/def.h @@ -0,0 +1,37 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodefhfoo +#define foodefhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "util.h" + +#define DEFAULT_TIMEOUT_USEC (90*USEC_PER_SEC) +#define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC) + +#define DEFAULT_EXIT_USEC (5*USEC_PER_MINUTE) + +#define SYSTEMD_CGROUP_CONTROLLER "name=systemd" + +#define SIGNALS_CRASH_HANDLER SIGSEGV,SIGILL,SIGFPE,SIGBUS,SIGQUIT,SIGABRT +#define SIGNALS_IGNORE SIGKILL,SIGPIPE + +#endif diff --git a/src/detect-virt.c b/src/detect-virt.c new file mode 100644 index 0000000..79cad5d --- /dev/null +++ b/src/detect-virt.c @@ -0,0 +1,48 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "virt.h" + +int main(int argc, char *argv[]) { + Virtualization r; + const char *id; + + /* This is mostly intended to be used for scripts which want + * to detect whether we are being run in a virtualized + * environment or not */ + + r = detect_virtualization(&id); + if (r < 0) { + log_error("Failed to check for virtualization: %s", strerror(-r)); + return EXIT_FAILURE; + } + + if (r > 0) + puts(id); + + return r > 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/src/device.c b/src/device.c new file mode 100644 index 0000000..0575379 --- /dev/null +++ b/src/device.c @@ -0,0 +1,616 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "unit.h" +#include "device.h" +#include "strv.h" +#include "log.h" +#include "unit-name.h" +#include "dbus-device.h" +#include "def.h" + +static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = { + [DEVICE_DEAD] = UNIT_INACTIVE, + [DEVICE_PLUGGED] = UNIT_ACTIVE +}; + +static void device_unset_sysfs(Device *d) { + Device *first; + + assert(d); + + if (!d->sysfs) + return; + + /* Remove this unit from the chain of devices which share the + * same sysfs path. */ + first = hashmap_get(UNIT(d)->manager->devices_by_sysfs, d->sysfs); + LIST_REMOVE(Device, same_sysfs, first, d); + + if (first) + hashmap_remove_and_replace(UNIT(d)->manager->devices_by_sysfs, d->sysfs, first->sysfs, first); + else + hashmap_remove(UNIT(d)->manager->devices_by_sysfs, d->sysfs); + + free(d->sysfs); + d->sysfs = NULL; +} + +static void device_init(Unit *u) { + Device *d = DEVICE(u); + + assert(d); + assert(UNIT(d)->load_state == UNIT_STUB); + + /* In contrast to all other unit types we timeout jobs waiting + * for devices by default. This is because they otherwise wait + * indefinitely for plugged in devices, something which cannot + * happen for the other units since their operations time out + * anyway. */ + UNIT(d)->job_timeout = DEFAULT_TIMEOUT_USEC; + + UNIT(d)->ignore_on_isolate = true; + UNIT(d)->ignore_on_snapshot = true; +} + +static void device_done(Unit *u) { + Device *d = DEVICE(u); + + assert(d); + + device_unset_sysfs(d); +} + +static void device_set_state(Device *d, DeviceState state) { + DeviceState old_state; + assert(d); + + old_state = d->state; + d->state = state; + + if (state != old_state) + log_debug("%s changed %s -> %s", + UNIT(d)->id, + device_state_to_string(old_state), + device_state_to_string(state)); + + unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state], true); +} + +static int device_coldplug(Unit *u) { + Device *d = DEVICE(u); + + assert(d); + assert(d->state == DEVICE_DEAD); + + if (d->sysfs) + device_set_state(d, DEVICE_PLUGGED); + + return 0; +} + +static void device_dump(Unit *u, FILE *f, const char *prefix) { + Device *d = DEVICE(u); + + assert(d); + + fprintf(f, + "%sDevice State: %s\n" + "%sSysfs Path: %s\n", + prefix, device_state_to_string(d->state), + prefix, strna(d->sysfs)); +} + +static UnitActiveState device_active_state(Unit *u) { + assert(u); + + return state_translation_table[DEVICE(u)->state]; +} + +static const char *device_sub_state_to_string(Unit *u) { + assert(u); + + return device_state_to_string(DEVICE(u)->state); +} + +static int device_add_escaped_name(Unit *u, const char *dn) { + char *e; + int r; + + assert(u); + assert(dn); + assert(dn[0] == '/'); + + if (!(e = unit_name_from_path(dn, ".device"))) + return -ENOMEM; + + r = unit_add_name(u, e); + free(e); + + if (r < 0 && r != -EEXIST) + return r; + + return 0; +} + +static int device_find_escape_name(Manager *m, const char *dn, Unit **_u) { + char *e; + Unit *u; + + assert(m); + assert(dn); + assert(dn[0] == '/'); + assert(_u); + + if (!(e = unit_name_from_path(dn, ".device"))) + return -ENOMEM; + + u = manager_get_unit(m, e); + free(e); + + if (u) { + *_u = u; + return 1; + } + + return 0; +} + +static int device_update_unit(Manager *m, struct udev_device *dev, const char *path, bool main) { + const char *sysfs, *model; + Unit *u = NULL; + int r; + bool delete; + + assert(m); + + if (!(sysfs = udev_device_get_syspath(dev))) + return -ENOMEM; + + if ((r = device_find_escape_name(m, path, &u)) < 0) + return r; + + if (u && DEVICE(u)->sysfs && !path_equal(DEVICE(u)->sysfs, sysfs)) + return -EEXIST; + + if (!u) { + delete = true; + + u = unit_new(m, sizeof(Device)); + if (!u) + return -ENOMEM; + + r = device_add_escaped_name(u, path); + if (r < 0) + goto fail; + + unit_add_to_load_queue(u); + } else + delete = false; + + /* If this was created via some dependency and has not + * actually been seen yet ->sysfs will not be + * initialized. Hence initialize it if necessary. */ + + if (!DEVICE(u)->sysfs) { + Device *first; + + if (!(DEVICE(u)->sysfs = strdup(sysfs))) { + r = -ENOMEM; + goto fail; + } + + if (!m->devices_by_sysfs) + if (!(m->devices_by_sysfs = hashmap_new(string_hash_func, string_compare_func))) { + r = -ENOMEM; + goto fail; + } + + first = hashmap_get(m->devices_by_sysfs, sysfs); + LIST_PREPEND(Device, same_sysfs, first, DEVICE(u)); + + if ((r = hashmap_replace(m->devices_by_sysfs, DEVICE(u)->sysfs, first)) < 0) + goto fail; + } + + if ((model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE")) || + (model = udev_device_get_property_value(dev, "ID_MODEL"))) { + if ((r = unit_set_description(u, model)) < 0) + goto fail; + } else + if ((r = unit_set_description(u, path)) < 0) + goto fail; + + if (main) { + /* The additional systemd udev properties we only + * interpret for the main object */ + const char *wants, *alias; + + if ((alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS"))) { + if (!is_path(alias)) + log_warning("SYSTEMD_ALIAS for %s is not a path, ignoring: %s", sysfs, alias); + else { + if ((r = device_add_escaped_name(u, alias)) < 0) + goto fail; + } + } + + if ((wants = udev_device_get_property_value(dev, "SYSTEMD_WANTS"))) { + char *state, *w; + size_t l; + + FOREACH_WORD_QUOTED(w, l, wants, state) { + char *e; + + if (!(e = strndup(w, l))) { + r = -ENOMEM; + goto fail; + } + + r = unit_add_dependency_by_name(u, UNIT_WANTS, e, NULL, true); + free(e); + + if (r < 0) + goto fail; + } + } + } + + unit_add_to_dbus_queue(u); + return 0; + +fail: + log_warning("Failed to load device unit: %s", strerror(-r)); + + if (delete && u) + unit_free(u); + + return r; +} + +static int device_process_new_device(Manager *m, struct udev_device *dev, bool update_state) { + const char *sysfs, *dn; + struct udev_list_entry *item = NULL, *first = NULL; + + assert(m); + + if (!(sysfs = udev_device_get_syspath(dev))) + return -ENOMEM; + + /* Add the main unit named after the sysfs path */ + device_update_unit(m, dev, sysfs, true); + + /* Add an additional unit for the device node */ + if ((dn = udev_device_get_devnode(dev))) + device_update_unit(m, dev, dn, false); + + /* Add additional units for all symlinks */ + first = udev_device_get_devlinks_list_entry(dev); + udev_list_entry_foreach(item, first) { + const char *p; + struct stat st; + + /* Don't bother with the /dev/block links */ + p = udev_list_entry_get_name(item); + + if (path_startswith(p, "/dev/block/") || + path_startswith(p, "/dev/char/")) + continue; + + /* Verify that the symlink in the FS actually belongs + * to this device. This is useful to deal with + * conflicting devices, e.g. when two disks want the + * same /dev/disk/by-label/xxx link because they have + * the same label. We want to make sure that the same + * device that won the symlink wins in systemd, so we + * check the device node major/minor*/ + if (stat(p, &st) >= 0) + if ((!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode)) || + st.st_rdev != udev_device_get_devnum(dev)) + continue; + + device_update_unit(m, dev, p, false); + } + + if (update_state) { + Device *d, *l; + + manager_dispatch_load_queue(m); + + l = hashmap_get(m->devices_by_sysfs, sysfs); + LIST_FOREACH(same_sysfs, d, l) + device_set_state(d, DEVICE_PLUGGED); + } + + return 0; +} + +static int device_process_path(Manager *m, const char *path, bool update_state) { + int r; + struct udev_device *dev; + + assert(m); + assert(path); + + if (!(dev = udev_device_new_from_syspath(m->udev, path))) { + log_warning("Failed to get udev device object from udev for path %s.", path); + return -ENOMEM; + } + + r = device_process_new_device(m, dev, update_state); + udev_device_unref(dev); + return r; +} + +static int device_process_removed_device(Manager *m, struct udev_device *dev) { + const char *sysfs; + Device *d; + + assert(m); + assert(dev); + + if (!(sysfs = udev_device_get_syspath(dev))) + return -ENOMEM; + + /* Remove all units of this sysfs path */ + while ((d = hashmap_get(m->devices_by_sysfs, sysfs))) { + device_unset_sysfs(d); + device_set_state(d, DEVICE_DEAD); + } + + return 0; +} + +static Unit *device_following(Unit *u) { + Device *d = DEVICE(u); + Device *other, *first = NULL; + + assert(d); + + if (startswith(u->id, "sys-")) + return NULL; + + /* Make everybody follow the unit that's named after the sysfs path */ + for (other = d->same_sysfs_next; other; other = other->same_sysfs_next) + if (startswith(UNIT(other)->id, "sys-")) + return UNIT(other); + + for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) { + if (startswith(UNIT(other)->id, "sys-")) + return UNIT(other); + + first = other; + } + + return UNIT(first); +} + +static int device_following_set(Unit *u, Set **_s) { + Device *d = DEVICE(u); + Device *other; + Set *s; + int r; + + assert(d); + assert(_s); + + if (!d->same_sysfs_prev && !d->same_sysfs_next) { + *_s = NULL; + return 0; + } + + if (!(s = set_new(NULL, NULL))) + return -ENOMEM; + + for (other = d->same_sysfs_next; other; other = other->same_sysfs_next) + if ((r = set_put(s, other)) < 0) + goto fail; + + for (other = d->same_sysfs_prev; other; other = other->same_sysfs_prev) + if ((r = set_put(s, other)) < 0) + goto fail; + + *_s = s; + return 1; + +fail: + set_free(s); + return r; +} + +static void device_shutdown(Manager *m) { + assert(m); + + if (m->udev_monitor) { + udev_monitor_unref(m->udev_monitor); + m->udev_monitor = NULL; + } + + if (m->udev) { + udev_unref(m->udev); + m->udev = NULL; + } + + hashmap_free(m->devices_by_sysfs); + m->devices_by_sysfs = NULL; +} + +static int device_enumerate(Manager *m) { + struct epoll_event ev; + int r; + struct udev_enumerate *e = NULL; + struct udev_list_entry *item = NULL, *first = NULL; + + assert(m); + + if (!m->udev) { + if (!(m->udev = udev_new())) + return -ENOMEM; + + if (!(m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev"))) { + r = -ENOMEM; + goto fail; + } + + /* This will fail if we are unprivileged, but that + * should not matter much, as user instances won't run + * during boot. */ + udev_monitor_set_receive_buffer_size(m->udev_monitor, 128*1024*1024); + + if (udev_monitor_filter_add_match_tag(m->udev_monitor, "systemd") < 0) { + r = -ENOMEM; + goto fail; + } + + if (udev_monitor_enable_receiving(m->udev_monitor) < 0) { + r = -EIO; + goto fail; + } + + m->udev_watch.type = WATCH_UDEV; + m->udev_watch.fd = udev_monitor_get_fd(m->udev_monitor); + + zero(ev); + ev.events = EPOLLIN; + ev.data.ptr = &m->udev_watch; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_watch.fd, &ev) < 0) + return -errno; + } + + if (!(e = udev_enumerate_new(m->udev))) { + r = -ENOMEM; + goto fail; + } + if (udev_enumerate_add_match_tag(e, "systemd") < 0) { + r = -EIO; + goto fail; + } + + if (udev_enumerate_scan_devices(e) < 0) { + r = -EIO; + goto fail; + } + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) + device_process_path(m, udev_list_entry_get_name(item), false); + + udev_enumerate_unref(e); + return 0; + +fail: + if (e) + udev_enumerate_unref(e); + + device_shutdown(m); + return r; +} + +void device_fd_event(Manager *m, int events) { + struct udev_device *dev; + int r; + const char *action, *ready; + + assert(m); + + if (events != EPOLLIN) { + static RATELIMIT_DEFINE(limit, 10*USEC_PER_SEC, 5); + + if (!ratelimit_test(&limit)) + log_error("Failed to get udev event: %m"); + if (!(events & EPOLLIN)) + return; + } + + if (!(dev = udev_monitor_receive_device(m->udev_monitor))) { + /* + * libudev might filter-out devices which pass the bloom filter, + * so getting NULL here is not necessarily an error + */ + return; + } + + if (!(action = udev_device_get_action(dev))) { + log_error("Failed to get udev action string."); + goto fail; + } + + ready = udev_device_get_property_value(dev, "SYSTEMD_READY"); + + if (streq(action, "remove") || (ready && parse_boolean(ready) == 0)) { + if ((r = device_process_removed_device(m, dev)) < 0) { + log_error("Failed to process udev device event: %s", strerror(-r)); + goto fail; + } + } else { + if ((r = device_process_new_device(m, dev, true)) < 0) { + log_error("Failed to process udev device event: %s", strerror(-r)); + goto fail; + } + } + +fail: + udev_device_unref(dev); +} + +static const char* const device_state_table[_DEVICE_STATE_MAX] = { + [DEVICE_DEAD] = "dead", + [DEVICE_PLUGGED] = "plugged" +}; + +DEFINE_STRING_TABLE_LOOKUP(device_state, DeviceState); + +const UnitVTable device_vtable = { + .suffix = ".device", + .object_size = sizeof(Device), + .sections = + "Unit\0" + "Device\0" + "Install\0", + + .no_instances = true, + + .init = device_init, + + .load = unit_load_fragment_and_dropin_optional, + .done = device_done, + .coldplug = device_coldplug, + + .dump = device_dump, + + .active_state = device_active_state, + .sub_state_to_string = device_sub_state_to_string, + + .bus_interface = "org.freedesktop.systemd1.Device", + .bus_message_handler = bus_device_message_handler, + .bus_invalidating_properties = bus_device_invalidating_properties, + + .following = device_following, + .following_set = device_following_set, + + .enumerate = device_enumerate, + .shutdown = device_shutdown +}; diff --git a/src/device.h b/src/device.h new file mode 100644 index 0000000..a05c3d3 --- /dev/null +++ b/src/device.h @@ -0,0 +1,59 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foodevicehfoo +#define foodevicehfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct Device Device; + +#include "unit.h" + +/* We simply watch devices, we cannot plug/unplug them. That + * simplifies the state engine greatly */ +typedef enum DeviceState { + DEVICE_DEAD, + DEVICE_PLUGGED, + _DEVICE_STATE_MAX, + _DEVICE_STATE_INVALID = -1 +} DeviceState; + +struct Device { + Unit meta; + + char *sysfs; + + /* In order to be able to distinguish dependencies on + different device nodes we might end up creating multiple + devices for the same sysfs path. We chain them up here. */ + + LIST_FIELDS(struct Device, same_sysfs); + + DeviceState state; +}; + +extern const UnitVTable device_vtable; + +void device_fd_event(Manager *m, int events); + +const char* device_state_to_string(DeviceState i); +DeviceState device_state_from_string(const char *s); + +#endif diff --git a/src/execute.c b/src/execute.c new file mode 100644 index 0000000..dab4856 --- /dev/null +++ b/src/execute.c @@ -0,0 +1,2112 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_PAM +#include +#endif + +#include "execute.h" +#include "strv.h" +#include "macro.h" +#include "util.h" +#include "log.h" +#include "ioprio.h" +#include "securebits.h" +#include "cgroup.h" +#include "namespace.h" +#include "tcpwrap.h" +#include "exit-status.h" +#include "missing.h" +#include "utmp-wtmp.h" +#include "def.h" +#include "loopback-setup.h" + +/* This assumes there is a 'tty' group */ +#define TTY_MODE 0620 + +static int shift_fds(int fds[], unsigned n_fds) { + int start, restart_from; + + if (n_fds <= 0) + return 0; + + /* Modifies the fds array! (sorts it) */ + + assert(fds); + + start = 0; + for (;;) { + int i; + + restart_from = -1; + + for (i = start; i < (int) n_fds; i++) { + int nfd; + + /* Already at right index? */ + if (fds[i] == i+3) + continue; + + if ((nfd = fcntl(fds[i], F_DUPFD, i+3)) < 0) + return -errno; + + close_nointr_nofail(fds[i]); + fds[i] = nfd; + + /* Hmm, the fd we wanted isn't free? Then + * let's remember that and try again from here*/ + if (nfd != i+3 && restart_from < 0) + restart_from = i; + } + + if (restart_from < 0) + break; + + start = restart_from; + } + + return 0; +} + +static int flags_fds(const int fds[], unsigned n_fds, bool nonblock) { + unsigned i; + int r; + + if (n_fds <= 0) + return 0; + + assert(fds); + + /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */ + + for (i = 0; i < n_fds; i++) { + + if ((r = fd_nonblock(fds[i], nonblock)) < 0) + return r; + + /* We unconditionally drop FD_CLOEXEC from the fds, + * since after all we want to pass these fds to our + * children */ + + if ((r = fd_cloexec(fds[i], false)) < 0) + return r; + } + + return 0; +} + +static const char *tty_path(const ExecContext *context) { + assert(context); + + if (context->tty_path) + return context->tty_path; + + return "/dev/console"; +} + +void exec_context_tty_reset(const ExecContext *context) { + assert(context); + + if (context->tty_vhangup) + terminal_vhangup(tty_path(context)); + + if (context->tty_reset) + reset_terminal(tty_path(context)); + + if (context->tty_vt_disallocate && context->tty_path) + vt_disallocate(context->tty_path); +} + +static int open_null_as(int flags, int nfd) { + int fd, r; + + assert(nfd >= 0); + + if ((fd = open("/dev/null", flags|O_NOCTTY)) < 0) + return -errno; + + if (fd != nfd) { + r = dup2(fd, nfd) < 0 ? -errno : nfd; + close_nointr_nofail(fd); + } else + r = nfd; + + return r; +} + +static int connect_logger_as(const ExecContext *context, ExecOutput output, const char *ident, int nfd) { + int fd, r; + union sockaddr_union sa; + + assert(context); + assert(output < _EXEC_OUTPUT_MAX); + assert(ident); + assert(nfd >= 0); + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) + return -errno; + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path)); + + r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)); + if (r < 0) { + close_nointr_nofail(fd); + return -errno; + } + + if (shutdown(fd, SHUT_RD) < 0) { + close_nointr_nofail(fd); + return -errno; + } + + dprintf(fd, + "%s\n" + "%i\n" + "%i\n" + "%i\n" + "%i\n" + "%i\n", + context->syslog_identifier ? context->syslog_identifier : ident, + context->syslog_priority, + !!context->syslog_level_prefix, + output == EXEC_OUTPUT_SYSLOG || output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE, + output == EXEC_OUTPUT_KMSG || output == EXEC_OUTPUT_KMSG_AND_CONSOLE, + output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || output == EXEC_OUTPUT_KMSG_AND_CONSOLE || output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE); + + if (fd != nfd) { + r = dup2(fd, nfd) < 0 ? -errno : nfd; + close_nointr_nofail(fd); + } else + r = nfd; + + return r; +} +static int open_terminal_as(const char *path, mode_t mode, int nfd) { + int fd, r; + + assert(path); + assert(nfd >= 0); + + if ((fd = open_terminal(path, mode | O_NOCTTY)) < 0) + return fd; + + if (fd != nfd) { + r = dup2(fd, nfd) < 0 ? -errno : nfd; + close_nointr_nofail(fd); + } else + r = nfd; + + return r; +} + +static bool is_terminal_input(ExecInput i) { + return + i == EXEC_INPUT_TTY || + i == EXEC_INPUT_TTY_FORCE || + i == EXEC_INPUT_TTY_FAIL; +} + +static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin) { + + if (is_terminal_input(std_input) && !apply_tty_stdin) + return EXEC_INPUT_NULL; + + if (std_input == EXEC_INPUT_SOCKET && socket_fd < 0) + return EXEC_INPUT_NULL; + + return std_input; +} + +static int fixup_output(ExecOutput std_output, int socket_fd) { + + if (std_output == EXEC_OUTPUT_SOCKET && socket_fd < 0) + return EXEC_OUTPUT_INHERIT; + + return std_output; +} + +static int setup_input(const ExecContext *context, int socket_fd, bool apply_tty_stdin) { + ExecInput i; + + assert(context); + + i = fixup_input(context->std_input, socket_fd, apply_tty_stdin); + + switch (i) { + + case EXEC_INPUT_NULL: + return open_null_as(O_RDONLY, STDIN_FILENO); + + case EXEC_INPUT_TTY: + case EXEC_INPUT_TTY_FORCE: + case EXEC_INPUT_TTY_FAIL: { + int fd, r; + + if ((fd = acquire_terminal( + tty_path(context), + i == EXEC_INPUT_TTY_FAIL, + i == EXEC_INPUT_TTY_FORCE, + false)) < 0) + return fd; + + if (fd != STDIN_FILENO) { + r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO; + close_nointr_nofail(fd); + } else + r = STDIN_FILENO; + + return r; + } + + case EXEC_INPUT_SOCKET: + return dup2(socket_fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO; + + default: + assert_not_reached("Unknown input type"); + } +} + +static int setup_output(const ExecContext *context, int socket_fd, const char *ident, bool apply_tty_stdin) { + ExecOutput o; + ExecInput i; + + assert(context); + assert(ident); + + i = fixup_input(context->std_input, socket_fd, apply_tty_stdin); + o = fixup_output(context->std_output, socket_fd); + + /* This expects the input is already set up */ + + switch (o) { + + case EXEC_OUTPUT_INHERIT: + + /* If input got downgraded, inherit the original value */ + if (i == EXEC_INPUT_NULL && is_terminal_input(context->std_input)) + return open_terminal_as(tty_path(context), O_WRONLY, STDOUT_FILENO); + + /* If the input is connected to anything that's not a /dev/null, inherit that... */ + if (i != EXEC_INPUT_NULL) + return dup2(STDIN_FILENO, STDOUT_FILENO) < 0 ? -errno : STDOUT_FILENO; + + /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */ + if (getppid() != 1) + return STDOUT_FILENO; + + /* We need to open /dev/null here anew, to get the + * right access mode. So we fall through */ + + case EXEC_OUTPUT_NULL: + return open_null_as(O_WRONLY, STDOUT_FILENO); + + case EXEC_OUTPUT_TTY: + if (is_terminal_input(i)) + return dup2(STDIN_FILENO, STDOUT_FILENO) < 0 ? -errno : STDOUT_FILENO; + + /* We don't reset the terminal if this is just about output */ + return open_terminal_as(tty_path(context), O_WRONLY, STDOUT_FILENO); + + case EXEC_OUTPUT_SYSLOG: + case EXEC_OUTPUT_SYSLOG_AND_CONSOLE: + case EXEC_OUTPUT_KMSG: + case EXEC_OUTPUT_KMSG_AND_CONSOLE: + case EXEC_OUTPUT_JOURNAL: + case EXEC_OUTPUT_JOURNAL_AND_CONSOLE: + return connect_logger_as(context, o, ident, STDOUT_FILENO); + + case EXEC_OUTPUT_SOCKET: + assert(socket_fd >= 0); + return dup2(socket_fd, STDOUT_FILENO) < 0 ? -errno : STDOUT_FILENO; + + default: + assert_not_reached("Unknown output type"); + } +} + +static int setup_error(const ExecContext *context, int socket_fd, const char *ident, bool apply_tty_stdin) { + ExecOutput o, e; + ExecInput i; + + assert(context); + assert(ident); + + i = fixup_input(context->std_input, socket_fd, apply_tty_stdin); + o = fixup_output(context->std_output, socket_fd); + e = fixup_output(context->std_error, socket_fd); + + /* This expects the input and output are already set up */ + + /* Don't change the stderr file descriptor if we inherit all + * the way and are not on a tty */ + if (e == EXEC_OUTPUT_INHERIT && + o == EXEC_OUTPUT_INHERIT && + i == EXEC_INPUT_NULL && + !is_terminal_input(context->std_input) && + getppid () != 1) + return STDERR_FILENO; + + /* Duplicate from stdout if possible */ + if (e == o || e == EXEC_OUTPUT_INHERIT) + return dup2(STDOUT_FILENO, STDERR_FILENO) < 0 ? -errno : STDERR_FILENO; + + switch (e) { + + case EXEC_OUTPUT_NULL: + return open_null_as(O_WRONLY, STDERR_FILENO); + + case EXEC_OUTPUT_TTY: + if (is_terminal_input(i)) + return dup2(STDIN_FILENO, STDERR_FILENO) < 0 ? -errno : STDERR_FILENO; + + /* We don't reset the terminal if this is just about output */ + return open_terminal_as(tty_path(context), O_WRONLY, STDERR_FILENO); + + case EXEC_OUTPUT_SYSLOG: + case EXEC_OUTPUT_SYSLOG_AND_CONSOLE: + case EXEC_OUTPUT_KMSG: + case EXEC_OUTPUT_KMSG_AND_CONSOLE: + case EXEC_OUTPUT_JOURNAL: + case EXEC_OUTPUT_JOURNAL_AND_CONSOLE: + return connect_logger_as(context, e, ident, STDERR_FILENO); + + case EXEC_OUTPUT_SOCKET: + assert(socket_fd >= 0); + return dup2(socket_fd, STDERR_FILENO) < 0 ? -errno : STDERR_FILENO; + + default: + assert_not_reached("Unknown error type"); + } +} + +static int chown_terminal(int fd, uid_t uid) { + struct stat st; + + assert(fd >= 0); + + /* This might fail. What matters are the results. */ + (void) fchown(fd, uid, -1); + (void) fchmod(fd, TTY_MODE); + + if (fstat(fd, &st) < 0) + return -errno; + + if (st.st_uid != uid || (st.st_mode & 0777) != TTY_MODE) + return -EPERM; + + return 0; +} + +static int setup_confirm_stdio(const ExecContext *context, + int *_saved_stdin, + int *_saved_stdout) { + int fd = -1, saved_stdin, saved_stdout = -1, r; + + assert(context); + assert(_saved_stdin); + assert(_saved_stdout); + + /* This returns positive EXIT_xxx return values instead of + * negative errno style values! */ + + if ((saved_stdin = fcntl(STDIN_FILENO, F_DUPFD, 3)) < 0) + return EXIT_STDIN; + + if ((saved_stdout = fcntl(STDOUT_FILENO, F_DUPFD, 3)) < 0) { + r = EXIT_STDOUT; + goto fail; + } + + if ((fd = acquire_terminal( + tty_path(context), + context->std_input == EXEC_INPUT_TTY_FAIL, + context->std_input == EXEC_INPUT_TTY_FORCE, + false)) < 0) { + r = EXIT_STDIN; + goto fail; + } + + if (chown_terminal(fd, getuid()) < 0) { + r = EXIT_STDIN; + goto fail; + } + + if (dup2(fd, STDIN_FILENO) < 0) { + r = EXIT_STDIN; + goto fail; + } + + if (dup2(fd, STDOUT_FILENO) < 0) { + r = EXIT_STDOUT; + goto fail; + } + + if (fd >= 2) + close_nointr_nofail(fd); + + *_saved_stdin = saved_stdin; + *_saved_stdout = saved_stdout; + + return 0; + +fail: + if (saved_stdout >= 0) + close_nointr_nofail(saved_stdout); + + if (saved_stdin >= 0) + close_nointr_nofail(saved_stdin); + + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +static int restore_confirm_stdio(const ExecContext *context, + int *saved_stdin, + int *saved_stdout, + bool *keep_stdin, + bool *keep_stdout) { + + assert(context); + assert(saved_stdin); + assert(*saved_stdin >= 0); + assert(saved_stdout); + assert(*saved_stdout >= 0); + + /* This returns positive EXIT_xxx return values instead of + * negative errno style values! */ + + if (is_terminal_input(context->std_input)) { + + /* The service wants terminal input. */ + + *keep_stdin = true; + *keep_stdout = + context->std_output == EXEC_OUTPUT_INHERIT || + context->std_output == EXEC_OUTPUT_TTY; + + } else { + /* If the service doesn't want a controlling terminal, + * then we need to get rid entirely of what we have + * already. */ + + if (release_terminal() < 0) + return EXIT_STDIN; + + if (dup2(*saved_stdin, STDIN_FILENO) < 0) + return EXIT_STDIN; + + if (dup2(*saved_stdout, STDOUT_FILENO) < 0) + return EXIT_STDOUT; + + *keep_stdout = *keep_stdin = false; + } + + return 0; +} + +static int enforce_groups(const ExecContext *context, const char *username, gid_t gid) { + bool keep_groups = false; + int r; + + assert(context); + + /* Lookup and set GID and supplementary group list. Here too + * we avoid NSS lookups for gid=0. */ + + if (context->group || username) { + + if (context->group) { + const char *g = context->group; + + if ((r = get_group_creds(&g, &gid)) < 0) + return r; + } + + /* First step, initialize groups from /etc/groups */ + if (username && gid != 0) { + if (initgroups(username, gid) < 0) + return -errno; + + keep_groups = true; + } + + /* Second step, set our gids */ + if (setresgid(gid, gid, gid) < 0) + return -errno; + } + + if (context->supplementary_groups) { + int ngroups_max, k; + gid_t *gids; + char **i; + + /* Final step, initialize any manually set supplementary groups */ + assert_se((ngroups_max = (int) sysconf(_SC_NGROUPS_MAX)) > 0); + + if (!(gids = new(gid_t, ngroups_max))) + return -ENOMEM; + + if (keep_groups) { + if ((k = getgroups(ngroups_max, gids)) < 0) { + free(gids); + return -errno; + } + } else + k = 0; + + STRV_FOREACH(i, context->supplementary_groups) { + const char *g; + + if (k >= ngroups_max) { + free(gids); + return -E2BIG; + } + + g = *i; + r = get_group_creds(&g, gids+k); + if (r < 0) { + free(gids); + return r; + } + + k++; + } + + if (setgroups(k, gids) < 0) { + free(gids); + return -errno; + } + + free(gids); + } + + return 0; +} + +static int enforce_user(const ExecContext *context, uid_t uid) { + int r; + assert(context); + + /* Sets (but doesn't lookup) the uid and make sure we keep the + * capabilities while doing so. */ + + if (context->capabilities) { + cap_t d; + static const cap_value_t bits[] = { + CAP_SETUID, /* Necessary so that we can run setresuid() below */ + CAP_SETPCAP /* Necessary so that we can set PR_SET_SECUREBITS later on */ + }; + + /* First step: If we need to keep capabilities but + * drop privileges we need to make sure we keep our + * caps, whiel we drop privileges. */ + if (uid != 0) { + int sb = context->secure_bits|SECURE_KEEP_CAPS; + + if (prctl(PR_GET_SECUREBITS) != sb) + if (prctl(PR_SET_SECUREBITS, sb) < 0) + return -errno; + } + + /* Second step: set the capabilities. This will reduce + * the capabilities to the minimum we need. */ + + if (!(d = cap_dup(context->capabilities))) + return -errno; + + if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 || + cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0) { + r = -errno; + cap_free(d); + return r; + } + + if (cap_set_proc(d) < 0) { + r = -errno; + cap_free(d); + return r; + } + + cap_free(d); + } + + /* Third step: actually set the uids */ + if (setresuid(uid, uid, uid) < 0) + return -errno; + + /* At this point we should have all necessary capabilities but + are otherwise a normal user. However, the caps might got + corrupted due to the setresuid() so we need clean them up + later. This is done outside of this call. */ + + return 0; +} + +#ifdef HAVE_PAM + +static int null_conv( + int num_msg, + const struct pam_message **msg, + struct pam_response **resp, + void *appdata_ptr) { + + /* We don't support conversations */ + + return PAM_CONV_ERR; +} + +static int setup_pam( + const char *name, + const char *user, + const char *tty, + char ***pam_env, + int fds[], unsigned n_fds) { + + static const struct pam_conv conv = { + .conv = null_conv, + .appdata_ptr = NULL + }; + + pam_handle_t *handle = NULL; + sigset_t ss, old_ss; + int pam_code = PAM_SUCCESS; + int err; + char **e = NULL; + bool close_session = false; + pid_t pam_pid = 0, parent_pid; + + assert(name); + assert(user); + assert(pam_env); + + /* We set up PAM in the parent process, then fork. The child + * will then stay around until killed via PR_GET_PDEATHSIG or + * systemd via the cgroup logic. It will then remove the PAM + * session again. The parent process will exec() the actual + * daemon. We do things this way to ensure that the main PID + * of the daemon is the one we initially fork()ed. */ + + if ((pam_code = pam_start(name, user, &conv, &handle)) != PAM_SUCCESS) { + handle = NULL; + goto fail; + } + + if (tty) + if ((pam_code = pam_set_item(handle, PAM_TTY, tty)) != PAM_SUCCESS) + goto fail; + + if ((pam_code = pam_acct_mgmt(handle, PAM_SILENT)) != PAM_SUCCESS) + goto fail; + + if ((pam_code = pam_open_session(handle, PAM_SILENT)) != PAM_SUCCESS) + goto fail; + + close_session = true; + + if ((!(e = pam_getenvlist(handle)))) { + pam_code = PAM_BUF_ERR; + goto fail; + } + + /* Block SIGTERM, so that we know that it won't get lost in + * the child */ + if (sigemptyset(&ss) < 0 || + sigaddset(&ss, SIGTERM) < 0 || + sigprocmask(SIG_BLOCK, &ss, &old_ss) < 0) + goto fail; + + parent_pid = getpid(); + + if ((pam_pid = fork()) < 0) + goto fail; + + if (pam_pid == 0) { + int sig; + int r = EXIT_PAM; + + /* The child's job is to reset the PAM session on + * termination */ + + /* This string must fit in 10 chars (i.e. the length + * of "/sbin/init"), to look pretty in /bin/ps */ + rename_process("(sd-pam)"); + + /* Make sure we don't keep open the passed fds in this + child. We assume that otherwise only those fds are + open here that have been opened by PAM. */ + close_many(fds, n_fds); + + /* Wait until our parent died. This will most likely + * not work since the kernel does not allow + * unprivileged parents kill their privileged children + * this way. We rely on the control groups kill logic + * to do the rest for us. */ + if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) + goto child_finish; + + /* Check if our parent process might already have + * died? */ + if (getppid() == parent_pid) { + for (;;) { + if (sigwait(&ss, &sig) < 0) { + if (errno == EINTR) + continue; + + goto child_finish; + } + + assert(sig == SIGTERM); + break; + } + } + + /* If our parent died we'll end the session */ + if (getppid() != parent_pid) + if ((pam_code = pam_close_session(handle, PAM_DATA_SILENT)) != PAM_SUCCESS) + goto child_finish; + + r = 0; + + child_finish: + pam_end(handle, pam_code | PAM_DATA_SILENT); + _exit(r); + } + + /* If the child was forked off successfully it will do all the + * cleanups, so forget about the handle here. */ + handle = NULL; + + /* Unblock SIGTERM again in the parent */ + if (sigprocmask(SIG_SETMASK, &old_ss, NULL) < 0) + goto fail; + + /* We close the log explicitly here, since the PAM modules + * might have opened it, but we don't want this fd around. */ + closelog(); + + *pam_env = e; + e = NULL; + + return 0; + +fail: + if (pam_code != PAM_SUCCESS) + err = -EPERM; /* PAM errors do not map to errno */ + else + err = -errno; + + if (handle) { + if (close_session) + pam_code = pam_close_session(handle, PAM_DATA_SILENT); + + pam_end(handle, pam_code | PAM_DATA_SILENT); + } + + strv_free(e); + + closelog(); + + if (pam_pid > 1) { + kill(pam_pid, SIGTERM); + kill(pam_pid, SIGCONT); + } + + return err; +} +#endif + +static int do_capability_bounding_set_drop(uint64_t drop) { + unsigned long i; + cap_t old_cap = NULL, new_cap = NULL; + cap_flag_value_t fv; + int r; + + /* If we are run as PID 1 we will lack CAP_SETPCAP by default + * in the effective set (yes, the kernel drops that when + * executing init!), so get it back temporarily so that we can + * call PR_CAPBSET_DROP. */ + + old_cap = cap_get_proc(); + if (!old_cap) + return -errno; + + if (cap_get_flag(old_cap, CAP_SETPCAP, CAP_EFFECTIVE, &fv) < 0) { + r = -errno; + goto finish; + } + + if (fv != CAP_SET) { + static const cap_value_t v = CAP_SETPCAP; + + new_cap = cap_dup(old_cap); + if (!new_cap) { + r = -errno; + goto finish; + } + + if (cap_set_flag(new_cap, CAP_EFFECTIVE, 1, &v, CAP_SET) < 0) { + r = -errno; + goto finish; + } + + if (cap_set_proc(new_cap) < 0) { + r = -errno; + goto finish; + } + } + + for (i = 0; i <= cap_last_cap(); i++) + if (drop & ((uint64_t) 1ULL << (uint64_t) i)) { + if (prctl(PR_CAPBSET_DROP, i) < 0) { + r = -errno; + goto finish; + } + } + + r = 0; + +finish: + if (new_cap) + cap_free(new_cap); + + if (old_cap) { + cap_set_proc(old_cap); + cap_free(old_cap); + } + + return r; +} + +static void rename_process_from_path(const char *path) { + char process_name[11]; + const char *p; + size_t l; + + /* This resulting string must fit in 10 chars (i.e. the length + * of "/sbin/init") to look pretty in /bin/ps */ + + p = file_name_from_path(path); + if (isempty(p)) { + rename_process("(...)"); + return; + } + + l = strlen(p); + if (l > 8) { + /* The end of the process name is usually more + * interesting, since the first bit might just be + * "systemd-" */ + p = p + l - 8; + l = 8; + } + + process_name[0] = '('; + memcpy(process_name+1, p, l); + process_name[1+l] = ')'; + process_name[1+l+1] = 0; + + rename_process(process_name); +} + +int exec_spawn(ExecCommand *command, + char **argv, + const ExecContext *context, + int fds[], unsigned n_fds, + char **environment, + bool apply_permissions, + bool apply_chroot, + bool apply_tty_stdin, + bool confirm_spawn, + CGroupBonding *cgroup_bondings, + CGroupAttribute *cgroup_attributes, + pid_t *ret) { + + pid_t pid; + int r; + char *line; + int socket_fd; + char **files_env = NULL; + + assert(command); + assert(context); + assert(ret); + assert(fds || n_fds <= 0); + + if (context->std_input == EXEC_INPUT_SOCKET || + context->std_output == EXEC_OUTPUT_SOCKET || + context->std_error == EXEC_OUTPUT_SOCKET) { + + if (n_fds != 1) + return -EINVAL; + + socket_fd = fds[0]; + + fds = NULL; + n_fds = 0; + } else + socket_fd = -1; + + if ((r = exec_context_load_environment(context, &files_env)) < 0) { + log_error("Failed to load environment files: %s", strerror(-r)); + return r; + } + + if (!argv) + argv = command->argv; + + if (!(line = exec_command_line(argv))) { + r = -ENOMEM; + goto fail_parent; + } + + log_debug("About to execute: %s", line); + free(line); + + r = cgroup_bonding_realize_list(cgroup_bondings); + if (r < 0) + goto fail_parent; + + cgroup_attribute_apply_list(cgroup_attributes, cgroup_bondings); + + if ((pid = fork()) < 0) { + r = -errno; + goto fail_parent; + } + + if (pid == 0) { + int i, err; + sigset_t ss; + const char *username = NULL, *home = NULL; + uid_t uid = (uid_t) -1; + gid_t gid = (gid_t) -1; + char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL; + unsigned n_env = 0; + int saved_stdout = -1, saved_stdin = -1; + bool keep_stdout = false, keep_stdin = false, set_access = false; + + /* child */ + + rename_process_from_path(command->path); + + /* We reset exactly these signals, since they are the + * only ones we set to SIG_IGN in the main daemon. All + * others we leave untouched because we set them to + * SIG_DFL or a valid handler initially, both of which + * will be demoted to SIG_DFL. */ + default_signals(SIGNALS_CRASH_HANDLER, + SIGNALS_IGNORE, -1); + + if (context->ignore_sigpipe) + ignore_signals(SIGPIPE, -1); + + assert_se(sigemptyset(&ss) == 0); + if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0) { + err = -errno; + r = EXIT_SIGNAL_MASK; + goto fail_child; + } + + /* Close sockets very early to make sure we don't + * block init reexecution because it cannot bind its + * sockets */ + log_forget_fds(); + err = close_all_fds(socket_fd >= 0 ? &socket_fd : fds, + socket_fd >= 0 ? 1 : n_fds); + if (err < 0) { + r = EXIT_FDS; + goto fail_child; + } + + if (!context->same_pgrp) + if (setsid() < 0) { + err = -errno; + r = EXIT_SETSID; + goto fail_child; + } + + if (context->tcpwrap_name) { + if (socket_fd >= 0) + if (!socket_tcpwrap(socket_fd, context->tcpwrap_name)) { + err = -EACCES; + r = EXIT_TCPWRAP; + goto fail_child; + } + + for (i = 0; i < (int) n_fds; i++) { + if (!socket_tcpwrap(fds[i], context->tcpwrap_name)) { + err = -EACCES; + r = EXIT_TCPWRAP; + goto fail_child; + } + } + } + + exec_context_tty_reset(context); + + /* We skip the confirmation step if we shall not apply the TTY */ + if (confirm_spawn && + (!is_terminal_input(context->std_input) || apply_tty_stdin)) { + char response; + + /* Set up terminal for the question */ + if ((r = setup_confirm_stdio(context, + &saved_stdin, &saved_stdout))) { + err = -errno; + goto fail_child; + } + + /* Now ask the question. */ + if (!(line = exec_command_line(argv))) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + r = ask(&response, "yns", "Execute %s? [Yes, No, Skip] ", line); + free(line); + + if (r < 0 || response == 'n') { + err = -ECANCELED; + r = EXIT_CONFIRM; + goto fail_child; + } else if (response == 's') { + err = r = 0; + goto fail_child; + } + + /* Release terminal for the question */ + if ((r = restore_confirm_stdio(context, + &saved_stdin, &saved_stdout, + &keep_stdin, &keep_stdout))) { + err = -errno; + goto fail_child; + } + } + + /* If a socket is connected to STDIN/STDOUT/STDERR, we + * must sure to drop O_NONBLOCK */ + if (socket_fd >= 0) + fd_nonblock(socket_fd, false); + + if (!keep_stdin) { + err = setup_input(context, socket_fd, apply_tty_stdin); + if (err < 0) { + r = EXIT_STDIN; + goto fail_child; + } + } + + if (!keep_stdout) { + err = setup_output(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin); + if (err < 0) { + r = EXIT_STDOUT; + goto fail_child; + } + } + + err = setup_error(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin); + if (err < 0) { + r = EXIT_STDERR; + goto fail_child; + } + + if (cgroup_bondings) { + err = cgroup_bonding_install_list(cgroup_bondings, 0); + if (err < 0) { + r = EXIT_CGROUP; + goto fail_child; + } + } + + if (context->oom_score_adjust_set) { + char t[16]; + + snprintf(t, sizeof(t), "%i", context->oom_score_adjust); + char_array_0(t); + + if (write_one_line_file("/proc/self/oom_score_adj", t) < 0) { + /* Compatibility with Linux <= 2.6.35 */ + + int adj; + + adj = (context->oom_score_adjust * -OOM_DISABLE) / OOM_SCORE_ADJ_MAX; + adj = CLAMP(adj, OOM_DISABLE, OOM_ADJUST_MAX); + + snprintf(t, sizeof(t), "%i", adj); + char_array_0(t); + + if (write_one_line_file("/proc/self/oom_adj", t) < 0 + && errno != EACCES) { + err = -errno; + r = EXIT_OOM_ADJUST; + goto fail_child; + } + } + } + + if (context->nice_set) + if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) { + err = -errno; + r = EXIT_NICE; + goto fail_child; + } + + if (context->cpu_sched_set) { + struct sched_param param; + + zero(param); + param.sched_priority = context->cpu_sched_priority; + + if (sched_setscheduler(0, context->cpu_sched_policy | + (context->cpu_sched_reset_on_fork ? SCHED_RESET_ON_FORK : 0), ¶m) < 0) { + err = -errno; + r = EXIT_SETSCHEDULER; + goto fail_child; + } + } + + if (context->cpuset) + if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) { + err = -errno; + r = EXIT_CPUAFFINITY; + goto fail_child; + } + + if (context->ioprio_set) + if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) { + err = -errno; + r = EXIT_IOPRIO; + goto fail_child; + } + + if (context->timer_slack_nsec_set) + if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) { + err = -errno; + r = EXIT_TIMERSLACK; + goto fail_child; + } + + if (context->utmp_id) + utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path); + + if (context->user) { + username = context->user; + err = get_user_creds(&username, &uid, &gid, &home); + if (err < 0) { + r = EXIT_USER; + goto fail_child; + } + + if (is_terminal_input(context->std_input)) { + err = chown_terminal(STDIN_FILENO, uid); + if (err < 0) { + r = EXIT_STDIN; + goto fail_child; + } + } + + if (cgroup_bondings && context->control_group_modify) { + err = cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid); + if (err >= 0) + err = cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid, context->control_group_persistent); + if (err < 0) { + r = EXIT_CGROUP; + goto fail_child; + } + + set_access = true; + } + } + + if (cgroup_bondings && !set_access && context->control_group_persistent >= 0) { + err = cgroup_bonding_set_task_access_list(cgroup_bondings, (mode_t) -1, (uid_t) -1, (uid_t) -1, context->control_group_persistent); + if (err < 0) { + r = EXIT_CGROUP; + goto fail_child; + } + } + + if (apply_permissions) { + err = enforce_groups(context, username, gid); + if (err < 0) { + r = EXIT_GROUP; + goto fail_child; + } + } + + umask(context->umask); + +#ifdef HAVE_PAM + if (context->pam_name && username) { + err = setup_pam(context->pam_name, username, context->tty_path, &pam_env, fds, n_fds); + if (err < 0) { + r = EXIT_PAM; + goto fail_child; + } + } +#endif + if (context->private_network) { + if (unshare(CLONE_NEWNET) < 0) { + err = -errno; + r = EXIT_NETWORK; + goto fail_child; + } + + loopback_setup(); + } + + if (strv_length(context->read_write_dirs) > 0 || + strv_length(context->read_only_dirs) > 0 || + strv_length(context->inaccessible_dirs) > 0 || + context->mount_flags != MS_SHARED || + context->private_tmp) { + err = setup_namespace(context->read_write_dirs, + context->read_only_dirs, + context->inaccessible_dirs, + context->private_tmp, + context->mount_flags); + if (err < 0) { + r = EXIT_NAMESPACE; + goto fail_child; + } + } + + if (apply_chroot) { + if (context->root_directory) + if (chroot(context->root_directory) < 0) { + err = -errno; + r = EXIT_CHROOT; + goto fail_child; + } + + if (chdir(context->working_directory ? context->working_directory : "/") < 0) { + err = -errno; + r = EXIT_CHDIR; + goto fail_child; + } + } else { + + char *d; + + if (asprintf(&d, "%s/%s", + context->root_directory ? context->root_directory : "", + context->working_directory ? context->working_directory : "") < 0) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + if (chdir(d) < 0) { + err = -errno; + free(d); + r = EXIT_CHDIR; + goto fail_child; + } + + free(d); + } + + /* We repeat the fd closing here, to make sure that + * nothing is leaked from the PAM modules */ + err = close_all_fds(fds, n_fds); + if (err >= 0) + err = shift_fds(fds, n_fds); + if (err >= 0) + err = flags_fds(fds, n_fds, context->non_blocking); + if (err < 0) { + r = EXIT_FDS; + goto fail_child; + } + + if (apply_permissions) { + + for (i = 0; i < RLIMIT_NLIMITS; i++) { + if (!context->rlimit[i]) + continue; + + if (setrlimit(i, context->rlimit[i]) < 0) { + err = -errno; + r = EXIT_LIMITS; + goto fail_child; + } + } + + if (context->capability_bounding_set_drop) { + err = do_capability_bounding_set_drop(context->capability_bounding_set_drop); + if (err < 0) { + r = EXIT_CAPABILITIES; + goto fail_child; + } + } + + if (context->user) { + err = enforce_user(context, uid); + if (err < 0) { + r = EXIT_USER; + goto fail_child; + } + } + + /* PR_GET_SECUREBITS is not privileged, while + * PR_SET_SECUREBITS is. So to suppress + * potential EPERMs we'll try not to call + * PR_SET_SECUREBITS unless necessary. */ + if (prctl(PR_GET_SECUREBITS) != context->secure_bits) + if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) { + err = -errno; + r = EXIT_SECUREBITS; + goto fail_child; + } + + if (context->capabilities) + if (cap_set_proc(context->capabilities) < 0) { + err = -errno; + r = EXIT_CAPABILITIES; + goto fail_child; + } + } + + if (!(our_env = new0(char*, 7))) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + if (n_fds > 0) + if (asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 || + asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + if (home) + if (asprintf(our_env + n_env++, "HOME=%s", home) < 0) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + if (username) + if (asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 || + asprintf(our_env + n_env++, "USER=%s", username) < 0) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + if (is_terminal_input(context->std_input) || + context->std_output == EXEC_OUTPUT_TTY || + context->std_error == EXEC_OUTPUT_TTY) + if (!(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + assert(n_env <= 7); + + if (!(final_env = strv_env_merge( + 5, + environment, + our_env, + context->environment, + files_env, + pam_env, + NULL))) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + if (!(final_argv = replace_env_argv(argv, final_env))) { + err = -ENOMEM; + r = EXIT_MEMORY; + goto fail_child; + } + + final_env = strv_env_clean(final_env); + + execve(command->path, final_argv, final_env); + err = -errno; + r = EXIT_EXEC; + + fail_child: + if (r != 0) { + log_open(); + log_warning("Failed at step %s spawning %s: %s", + exit_status_to_string(r, EXIT_STATUS_SYSTEMD), + command->path, strerror(-err)); + } + + strv_free(our_env); + strv_free(final_env); + strv_free(pam_env); + strv_free(files_env); + strv_free(final_argv); + + if (saved_stdin >= 0) + close_nointr_nofail(saved_stdin); + + if (saved_stdout >= 0) + close_nointr_nofail(saved_stdout); + + _exit(r); + } + + strv_free(files_env); + + /* We add the new process to the cgroup both in the child (so + * that we can be sure that no user code is ever executed + * outside of the cgroup) and in the parent (so that we can be + * sure that when we kill the cgroup the process will be + * killed too). */ + if (cgroup_bondings) + cgroup_bonding_install_list(cgroup_bondings, pid); + + log_debug("Forked %s as %lu", command->path, (unsigned long) pid); + + exec_status_start(&command->exec_status, pid); + + *ret = pid; + return 0; + +fail_parent: + strv_free(files_env); + + return r; +} + +void exec_context_init(ExecContext *c) { + assert(c); + + c->umask = 0022; + c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0); + c->cpu_sched_policy = SCHED_OTHER; + c->syslog_priority = LOG_DAEMON|LOG_INFO; + c->syslog_level_prefix = true; + c->mount_flags = MS_SHARED; + c->kill_signal = SIGTERM; + c->send_sigkill = true; + c->control_group_persistent = -1; + c->ignore_sigpipe = true; +} + +void exec_context_done(ExecContext *c) { + unsigned l; + + assert(c); + + strv_free(c->environment); + c->environment = NULL; + + strv_free(c->environment_files); + c->environment_files = NULL; + + for (l = 0; l < ELEMENTSOF(c->rlimit); l++) { + free(c->rlimit[l]); + c->rlimit[l] = NULL; + } + + free(c->working_directory); + c->working_directory = NULL; + free(c->root_directory); + c->root_directory = NULL; + + free(c->tty_path); + c->tty_path = NULL; + + free(c->tcpwrap_name); + c->tcpwrap_name = NULL; + + free(c->syslog_identifier); + c->syslog_identifier = NULL; + + free(c->user); + c->user = NULL; + + free(c->group); + c->group = NULL; + + strv_free(c->supplementary_groups); + c->supplementary_groups = NULL; + + free(c->pam_name); + c->pam_name = NULL; + + if (c->capabilities) { + cap_free(c->capabilities); + c->capabilities = NULL; + } + + strv_free(c->read_only_dirs); + c->read_only_dirs = NULL; + + strv_free(c->read_write_dirs); + c->read_write_dirs = NULL; + + strv_free(c->inaccessible_dirs); + c->inaccessible_dirs = NULL; + + if (c->cpuset) + CPU_FREE(c->cpuset); + + free(c->utmp_id); + c->utmp_id = NULL; +} + +void exec_command_done(ExecCommand *c) { + assert(c); + + free(c->path); + c->path = NULL; + + strv_free(c->argv); + c->argv = NULL; +} + +void exec_command_done_array(ExecCommand *c, unsigned n) { + unsigned i; + + for (i = 0; i < n; i++) + exec_command_done(c+i); +} + +void exec_command_free_list(ExecCommand *c) { + ExecCommand *i; + + while ((i = c)) { + LIST_REMOVE(ExecCommand, command, c, i); + exec_command_done(i); + free(i); + } +} + +void exec_command_free_array(ExecCommand **c, unsigned n) { + unsigned i; + + for (i = 0; i < n; i++) { + exec_command_free_list(c[i]); + c[i] = NULL; + } +} + +int exec_context_load_environment(const ExecContext *c, char ***l) { + char **i, **r = NULL; + + assert(c); + assert(l); + + STRV_FOREACH(i, c->environment_files) { + char *fn; + int k; + bool ignore = false; + char **p; + + fn = *i; + + if (fn[0] == '-') { + ignore = true; + fn ++; + } + + if (!path_is_absolute(fn)) { + + if (ignore) + continue; + + strv_free(r); + return -EINVAL; + } + + if ((k = load_env_file(fn, &p)) < 0) { + + if (ignore) + continue; + + strv_free(r); + return k; + } + + if (r == NULL) + r = p; + else { + char **m; + + m = strv_env_merge(2, r, p); + strv_free(r); + strv_free(p); + + if (!m) + return -ENOMEM; + + r = m; + } + } + + *l = r; + + return 0; +} + +static void strv_fprintf(FILE *f, char **l) { + char **g; + + assert(f); + + STRV_FOREACH(g, l) + fprintf(f, " %s", *g); +} + +void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { + char ** e; + unsigned i; + + assert(c); + assert(f); + + if (!prefix) + prefix = ""; + + fprintf(f, + "%sUMask: %04o\n" + "%sWorkingDirectory: %s\n" + "%sRootDirectory: %s\n" + "%sNonBlocking: %s\n" + "%sPrivateTmp: %s\n" + "%sControlGroupModify: %s\n" + "%sControlGroupPersistent: %s\n" + "%sPrivateNetwork: %s\n", + prefix, c->umask, + prefix, c->working_directory ? c->working_directory : "/", + prefix, c->root_directory ? c->root_directory : "/", + prefix, yes_no(c->non_blocking), + prefix, yes_no(c->private_tmp), + prefix, yes_no(c->control_group_modify), + prefix, yes_no(c->control_group_persistent), + prefix, yes_no(c->private_network)); + + STRV_FOREACH(e, c->environment) + fprintf(f, "%sEnvironment: %s\n", prefix, *e); + + STRV_FOREACH(e, c->environment_files) + fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e); + + if (c->tcpwrap_name) + fprintf(f, + "%sTCPWrapName: %s\n", + prefix, c->tcpwrap_name); + + if (c->nice_set) + fprintf(f, + "%sNice: %i\n", + prefix, c->nice); + + if (c->oom_score_adjust_set) + fprintf(f, + "%sOOMScoreAdjust: %i\n", + prefix, c->oom_score_adjust); + + for (i = 0; i < RLIM_NLIMITS; i++) + if (c->rlimit[i]) + fprintf(f, "%s%s: %llu\n", prefix, rlimit_to_string(i), (unsigned long long) c->rlimit[i]->rlim_max); + + if (c->ioprio_set) + fprintf(f, + "%sIOSchedulingClass: %s\n" + "%sIOPriority: %i\n", + prefix, ioprio_class_to_string(IOPRIO_PRIO_CLASS(c->ioprio)), + prefix, (int) IOPRIO_PRIO_DATA(c->ioprio)); + + if (c->cpu_sched_set) + fprintf(f, + "%sCPUSchedulingPolicy: %s\n" + "%sCPUSchedulingPriority: %i\n" + "%sCPUSchedulingResetOnFork: %s\n", + prefix, sched_policy_to_string(c->cpu_sched_policy), + prefix, c->cpu_sched_priority, + prefix, yes_no(c->cpu_sched_reset_on_fork)); + + if (c->cpuset) { + fprintf(f, "%sCPUAffinity:", prefix); + for (i = 0; i < c->cpuset_ncpus; i++) + if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset)) + fprintf(f, " %i", i); + fputs("\n", f); + } + + if (c->timer_slack_nsec_set) + fprintf(f, "%sTimerSlackNSec: %lu\n", prefix, c->timer_slack_nsec); + + fprintf(f, + "%sStandardInput: %s\n" + "%sStandardOutput: %s\n" + "%sStandardError: %s\n", + prefix, exec_input_to_string(c->std_input), + prefix, exec_output_to_string(c->std_output), + prefix, exec_output_to_string(c->std_error)); + + if (c->tty_path) + fprintf(f, + "%sTTYPath: %s\n" + "%sTTYReset: %s\n" + "%sTTYVHangup: %s\n" + "%sTTYVTDisallocate: %s\n", + prefix, c->tty_path, + prefix, yes_no(c->tty_reset), + prefix, yes_no(c->tty_vhangup), + prefix, yes_no(c->tty_vt_disallocate)); + + if (c->std_output == EXEC_OUTPUT_SYSLOG || c->std_output == EXEC_OUTPUT_KMSG || c->std_output == EXEC_OUTPUT_JOURNAL || + c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE || + c->std_error == EXEC_OUTPUT_SYSLOG || c->std_error == EXEC_OUTPUT_KMSG || c->std_error == EXEC_OUTPUT_JOURNAL || + c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) + fprintf(f, + "%sSyslogFacility: %s\n" + "%sSyslogLevel: %s\n", + prefix, log_facility_unshifted_to_string(c->syslog_priority >> 3), + prefix, log_level_to_string(LOG_PRI(c->syslog_priority))); + + if (c->capabilities) { + char *t; + if ((t = cap_to_text(c->capabilities, NULL))) { + fprintf(f, "%sCapabilities: %s\n", + prefix, t); + cap_free(t); + } + } + + if (c->secure_bits) + fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n", + prefix, + (c->secure_bits & SECURE_KEEP_CAPS) ? " keep-caps" : "", + (c->secure_bits & SECURE_KEEP_CAPS_LOCKED) ? " keep-caps-locked" : "", + (c->secure_bits & SECURE_NO_SETUID_FIXUP) ? " no-setuid-fixup" : "", + (c->secure_bits & SECURE_NO_SETUID_FIXUP_LOCKED) ? " no-setuid-fixup-locked" : "", + (c->secure_bits & SECURE_NOROOT) ? " noroot" : "", + (c->secure_bits & SECURE_NOROOT_LOCKED) ? "noroot-locked" : ""); + + if (c->capability_bounding_set_drop) { + unsigned long l; + fprintf(f, "%sCapabilityBoundingSet:", prefix); + + for (l = 0; l <= cap_last_cap(); l++) + if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l))) { + char *t; + + if ((t = cap_to_name(l))) { + fprintf(f, " %s", t); + cap_free(t); + } + } + + fputs("\n", f); + } + + if (c->user) + fprintf(f, "%sUser: %s\n", prefix, c->user); + if (c->group) + fprintf(f, "%sGroup: %s\n", prefix, c->group); + + if (strv_length(c->supplementary_groups) > 0) { + fprintf(f, "%sSupplementaryGroups:", prefix); + strv_fprintf(f, c->supplementary_groups); + fputs("\n", f); + } + + if (c->pam_name) + fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name); + + if (strv_length(c->read_write_dirs) > 0) { + fprintf(f, "%sReadWriteDirs:", prefix); + strv_fprintf(f, c->read_write_dirs); + fputs("\n", f); + } + + if (strv_length(c->read_only_dirs) > 0) { + fprintf(f, "%sReadOnlyDirs:", prefix); + strv_fprintf(f, c->read_only_dirs); + fputs("\n", f); + } + + if (strv_length(c->inaccessible_dirs) > 0) { + fprintf(f, "%sInaccessibleDirs:", prefix); + strv_fprintf(f, c->inaccessible_dirs); + fputs("\n", f); + } + + fprintf(f, + "%sKillMode: %s\n" + "%sKillSignal: SIG%s\n" + "%sSendSIGKILL: %s\n" + "%sIgnoreSIGPIPE: %s\n", + prefix, kill_mode_to_string(c->kill_mode), + prefix, signal_to_string(c->kill_signal), + prefix, yes_no(c->send_sigkill), + prefix, yes_no(c->ignore_sigpipe)); + + if (c->utmp_id) + fprintf(f, + "%sUtmpIdentifier: %s\n", + prefix, c->utmp_id); +} + +void exec_status_start(ExecStatus *s, pid_t pid) { + assert(s); + + zero(*s); + s->pid = pid; + dual_timestamp_get(&s->start_timestamp); +} + +void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) { + assert(s); + + if (s->pid && s->pid != pid) + zero(*s); + + s->pid = pid; + dual_timestamp_get(&s->exit_timestamp); + + s->code = code; + s->status = status; + + if (context) { + if (context->utmp_id) + utmp_put_dead_process(context->utmp_id, pid, code, status); + + exec_context_tty_reset(context); + } +} + +void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) { + char buf[FORMAT_TIMESTAMP_MAX]; + + assert(s); + assert(f); + + if (!prefix) + prefix = ""; + + if (s->pid <= 0) + return; + + fprintf(f, + "%sPID: %lu\n", + prefix, (unsigned long) s->pid); + + if (s->start_timestamp.realtime > 0) + fprintf(f, + "%sStart Timestamp: %s\n", + prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp.realtime)); + + if (s->exit_timestamp.realtime > 0) + fprintf(f, + "%sExit Timestamp: %s\n" + "%sExit Code: %s\n" + "%sExit Status: %i\n", + prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime), + prefix, sigchld_code_to_string(s->code), + prefix, s->status); +} + +char *exec_command_line(char **argv) { + size_t k; + char *n, *p, **a; + bool first = true; + + assert(argv); + + k = 1; + STRV_FOREACH(a, argv) + k += strlen(*a)+3; + + if (!(n = new(char, k))) + return NULL; + + p = n; + STRV_FOREACH(a, argv) { + + if (!first) + *(p++) = ' '; + else + first = false; + + if (strpbrk(*a, WHITESPACE)) { + *(p++) = '\''; + p = stpcpy(p, *a); + *(p++) = '\''; + } else + p = stpcpy(p, *a); + + } + + *p = 0; + + /* FIXME: this doesn't really handle arguments that have + * spaces and ticks in them */ + + return n; +} + +void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) { + char *p2; + const char *prefix2; + + char *cmd; + + assert(c); + assert(f); + + if (!prefix) + prefix = ""; + p2 = strappend(prefix, "\t"); + prefix2 = p2 ? p2 : prefix; + + cmd = exec_command_line(c->argv); + + fprintf(f, + "%sCommand Line: %s\n", + prefix, cmd ? cmd : strerror(ENOMEM)); + + free(cmd); + + exec_status_dump(&c->exec_status, f, prefix2); + + free(p2); +} + +void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) { + assert(f); + + if (!prefix) + prefix = ""; + + LIST_FOREACH(command, c, c) + exec_command_dump(c, f, prefix); +} + +void exec_command_append_list(ExecCommand **l, ExecCommand *e) { + ExecCommand *end; + + assert(l); + assert(e); + + if (*l) { + /* It's kind of important, that we keep the order here */ + LIST_FIND_TAIL(ExecCommand, command, *l, end); + LIST_INSERT_AFTER(ExecCommand, command, *l, end, e); + } else + *l = e; +} + +int exec_command_set(ExecCommand *c, const char *path, ...) { + va_list ap; + char **l, *p; + + assert(c); + assert(path); + + va_start(ap, path); + l = strv_new_ap(path, ap); + va_end(ap); + + if (!l) + return -ENOMEM; + + if (!(p = strdup(path))) { + strv_free(l); + return -ENOMEM; + } + + free(c->path); + c->path = p; + + strv_free(c->argv); + c->argv = l; + + return 0; +} + +static const char* const exec_input_table[_EXEC_INPUT_MAX] = { + [EXEC_INPUT_NULL] = "null", + [EXEC_INPUT_TTY] = "tty", + [EXEC_INPUT_TTY_FORCE] = "tty-force", + [EXEC_INPUT_TTY_FAIL] = "tty-fail", + [EXEC_INPUT_SOCKET] = "socket" +}; + +DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput); + +static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = { + [EXEC_OUTPUT_INHERIT] = "inherit", + [EXEC_OUTPUT_NULL] = "null", + [EXEC_OUTPUT_TTY] = "tty", + [EXEC_OUTPUT_SYSLOG] = "syslog", + [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console", + [EXEC_OUTPUT_KMSG] = "kmsg", + [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console", + [EXEC_OUTPUT_JOURNAL] = "journal", + [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console", + [EXEC_OUTPUT_SOCKET] = "socket" +}; + +DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput); + +static const char* const kill_mode_table[_KILL_MODE_MAX] = { + [KILL_CONTROL_GROUP] = "control-group", + [KILL_PROCESS] = "process", + [KILL_NONE] = "none" +}; + +DEFINE_STRING_TABLE_LOOKUP(kill_mode, KillMode); + +static const char* const kill_who_table[_KILL_WHO_MAX] = { + [KILL_MAIN] = "main", + [KILL_CONTROL] = "control", + [KILL_ALL] = "all" +}; + +DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho); diff --git a/src/execute.h b/src/execute.h new file mode 100644 index 0000000..0d7e7dd --- /dev/null +++ b/src/execute.h @@ -0,0 +1,233 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooexecutehfoo +#define fooexecutehfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct ExecStatus ExecStatus; +typedef struct ExecCommand ExecCommand; +typedef struct ExecContext ExecContext; + +#include +#include +#include +#include +#include +#include +#include + +struct CGroupBonding; +struct CGroupAttribute; + +#include "list.h" +#include "util.h" + +typedef enum KillMode { + KILL_CONTROL_GROUP = 0, + KILL_PROCESS, + KILL_NONE, + _KILL_MODE_MAX, + _KILL_MODE_INVALID = -1 +} KillMode; + +typedef enum KillWho { + KILL_MAIN, + KILL_CONTROL, + KILL_ALL, + _KILL_WHO_MAX, + _KILL_WHO_INVALID = -1 +} KillWho; + +typedef enum ExecInput { + EXEC_INPUT_NULL, + EXEC_INPUT_TTY, + EXEC_INPUT_TTY_FORCE, + EXEC_INPUT_TTY_FAIL, + EXEC_INPUT_SOCKET, + _EXEC_INPUT_MAX, + _EXEC_INPUT_INVALID = -1 +} ExecInput; + +typedef enum ExecOutput { + EXEC_OUTPUT_INHERIT, + EXEC_OUTPUT_NULL, + EXEC_OUTPUT_TTY, + EXEC_OUTPUT_SYSLOG, + EXEC_OUTPUT_SYSLOG_AND_CONSOLE, + EXEC_OUTPUT_KMSG, + EXEC_OUTPUT_KMSG_AND_CONSOLE, + EXEC_OUTPUT_JOURNAL, + EXEC_OUTPUT_JOURNAL_AND_CONSOLE, + EXEC_OUTPUT_SOCKET, + _EXEC_OUTPUT_MAX, + _EXEC_OUTPUT_INVALID = -1 +} ExecOutput; + +struct ExecStatus { + dual_timestamp start_timestamp; + dual_timestamp exit_timestamp; + pid_t pid; + int code; /* as in siginfo_t::si_code */ + int status; /* as in sigingo_t::si_status */ +}; + +struct ExecCommand { + char *path; + char **argv; + ExecStatus exec_status; + LIST_FIELDS(ExecCommand, command); /* useful for chaining commands */ + bool ignore; +}; + +struct ExecContext { + char **environment; + char **environment_files; + + struct rlimit *rlimit[RLIMIT_NLIMITS]; + char *working_directory, *root_directory; + + mode_t umask; + int oom_score_adjust; + int nice; + int ioprio; + int cpu_sched_policy; + int cpu_sched_priority; + + cpu_set_t *cpuset; + unsigned cpuset_ncpus; + + ExecInput std_input; + ExecOutput std_output; + ExecOutput std_error; + + unsigned long timer_slack_nsec; + + char *tcpwrap_name; + + char *tty_path; + + bool tty_reset; + bool tty_vhangup; + bool tty_vt_disallocate; + + bool ignore_sigpipe; + + /* Since resolving these names might might involve socket + * connections and we don't want to deadlock ourselves these + * names are resolved on execution only and in the child + * process. */ + char *user; + char *group; + char **supplementary_groups; + + char *pam_name; + + char *utmp_id; + + char **read_write_dirs, **read_only_dirs, **inaccessible_dirs; + unsigned long mount_flags; + + uint64_t capability_bounding_set_drop; + + /* Not relevant for spawning processes, just for killing */ + KillMode kill_mode; + int kill_signal; + bool send_sigkill; + + cap_t capabilities; + int secure_bits; + + int syslog_priority; + char *syslog_identifier; + bool syslog_level_prefix; + + bool cpu_sched_reset_on_fork; + bool non_blocking; + bool private_tmp; + bool private_network; + + bool control_group_modify; + int control_group_persistent; + + /* This is not exposed to the user but available + * internally. We need it to make sure that whenever we spawn + * /bin/mount it is run in the same process group as us so + * that the autofs logic detects that it belongs to us and we + * don't enter a trigger loop. */ + bool same_pgrp; + + bool oom_score_adjust_set:1; + bool nice_set:1; + bool ioprio_set:1; + bool cpu_sched_set:1; + bool timer_slack_nsec_set:1; +}; + +int exec_spawn(ExecCommand *command, + char **argv, + const ExecContext *context, + int fds[], unsigned n_fds, + char **environment, + bool apply_permissions, + bool apply_chroot, + bool apply_tty_stdin, + bool confirm_spawn, + struct CGroupBonding *cgroup_bondings, + struct CGroupAttribute *cgroup_attributes, + pid_t *ret); + +void exec_command_done(ExecCommand *c); +void exec_command_done_array(ExecCommand *c, unsigned n); + +void exec_command_free_list(ExecCommand *c); +void exec_command_free_array(ExecCommand **c, unsigned n); + +char *exec_command_line(char **argv); + +void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix); +void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix); +void exec_command_append_list(ExecCommand **l, ExecCommand *e); +int exec_command_set(ExecCommand *c, const char *path, ...); + +void exec_context_init(ExecContext *c); +void exec_context_done(ExecContext *c); +void exec_context_dump(ExecContext *c, FILE* f, const char *prefix); +void exec_context_tty_reset(const ExecContext *context); + +int exec_context_load_environment(const ExecContext *c, char ***l); + +void exec_status_start(ExecStatus *s, pid_t pid); +void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status); +void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix); + +const char* exec_output_to_string(ExecOutput i); +ExecOutput exec_output_from_string(const char *s); + +const char* exec_input_to_string(ExecInput i); +ExecInput exec_input_from_string(const char *s); + +const char *kill_mode_to_string(KillMode k); +KillMode kill_mode_from_string(const char *s); + +const char *kill_who_to_string(KillWho k); +KillWho kill_who_from_string(const char *s); + +#endif diff --git a/src/exit-status.c b/src/exit-status.c new file mode 100644 index 0000000..ab8907d --- /dev/null +++ b/src/exit-status.c @@ -0,0 +1,180 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "exit-status.h" + +const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level) { + + /* We cast to int here, so that -Wenum doesn't complain that + * EXIT_SUCCESS/EXIT_FAILURE aren't in the enum */ + + switch ((int) status) { + + case EXIT_SUCCESS: + return "SUCCESS"; + + case EXIT_FAILURE: + return "FAILURE"; + } + + + if (level == EXIT_STATUS_SYSTEMD || level == EXIT_STATUS_LSB) { + switch ((int) status) { + + case EXIT_CHDIR: + return "CHDIR"; + + case EXIT_NICE: + return "NICE"; + + case EXIT_FDS: + return "FDS"; + + case EXIT_EXEC: + return "EXEC"; + + case EXIT_MEMORY: + return "MEMORY"; + + case EXIT_LIMITS: + return "LIMITS"; + + case EXIT_OOM_ADJUST: + return "OOM_ADJUST"; + + case EXIT_SIGNAL_MASK: + return "SIGNAL_MASK"; + + case EXIT_STDIN: + return "STDIN"; + + case EXIT_STDOUT: + return "STDOUT"; + + case EXIT_CHROOT: + return "CHROOT"; + + case EXIT_IOPRIO: + return "IOPRIO"; + + case EXIT_TIMERSLACK: + return "TIMERSLACK"; + + case EXIT_SECUREBITS: + return "SECUREBITS"; + + case EXIT_SETSCHEDULER: + return "SETSCHEDULER"; + + case EXIT_CPUAFFINITY: + return "CPUAFFINITY"; + + case EXIT_GROUP: + return "GROUP"; + + case EXIT_USER: + return "USER"; + + case EXIT_CAPABILITIES: + return "CAPABILITIES"; + + case EXIT_CGROUP: + return "CGROUP"; + + case EXIT_SETSID: + return "SETSID"; + + case EXIT_CONFIRM: + return "CONFIRM"; + + case EXIT_STDERR: + return "STDERR"; + + case EXIT_TCPWRAP: + return "TCPWRAP"; + + case EXIT_PAM: + return "PAM"; + + case EXIT_NETWORK: + return "NETWORK"; + + case EXIT_NAMESPACE: + return "NAMESPACE"; + } + } + + if (level == EXIT_STATUS_LSB) { + switch ((int) status) { + + case EXIT_INVALIDARGUMENT: + return "INVALIDARGUMENT"; + + case EXIT_NOTIMPLEMENTED: + return "NOTIMPLEMENTED"; + + case EXIT_NOPERMISSION: + return "NOPERMISSION"; + + case EXIT_NOTINSTALLED: + return "NOTINSSTALLED"; + + case EXIT_NOTCONFIGURED: + return "NOTCONFIGURED"; + + case EXIT_NOTRUNNING: + return "NOTRUNNING"; + } + } + + return NULL; +} + + +bool is_clean_exit(int code, int status) { + + if (code == CLD_EXITED) + return status == 0; + + /* If a daemon does not implement handlers for some of the + * signals that's not considered an unclean shutdown */ + if (code == CLD_KILLED) + return + status == SIGHUP || + status == SIGINT || + status == SIGTERM || + status == SIGPIPE; + + return false; +} + +bool is_clean_exit_lsb(int code, int status) { + + if (is_clean_exit(code, status)) + return true; + + return + code == CLD_EXITED && + (status == EXIT_NOTINSTALLED || status == EXIT_NOTCONFIGURED); +} diff --git a/src/exit-status.h b/src/exit-status.h new file mode 100644 index 0000000..44ef879 --- /dev/null +++ b/src/exit-status.h @@ -0,0 +1,85 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooexitstatushfoo +#define fooexitstatushfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +typedef enum ExitStatus { + /* EXIT_SUCCESS defined by libc */ + /* EXIT_FAILURE defined by libc */ + EXIT_INVALIDARGUMENT = 2, + EXIT_NOTIMPLEMENTED = 3, + EXIT_NOPERMISSION = 4, + EXIT_NOTINSTALLED = 5, + EXIT_NOTCONFIGURED = 6, + EXIT_NOTRUNNING = 7, + + /* The LSB suggests that error codes >= 200 are "reserved". We + * use them here under the assumption that they hence are + * unused by init scripts. + * + * http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html */ + + EXIT_CHDIR = 200, + EXIT_NICE, + EXIT_FDS, + EXIT_EXEC, + EXIT_MEMORY, + EXIT_LIMITS, + EXIT_OOM_ADJUST, + EXIT_SIGNAL_MASK, + EXIT_STDIN, + EXIT_STDOUT, + EXIT_CHROOT, /* 210 */ + EXIT_IOPRIO, + EXIT_TIMERSLACK, + EXIT_SECUREBITS, + EXIT_SETSCHEDULER, + EXIT_CPUAFFINITY, + EXIT_GROUP, + EXIT_USER, + EXIT_CAPABILITIES, + EXIT_CGROUP, + EXIT_SETSID, /* 220 */ + EXIT_CONFIRM, + EXIT_STDERR, + EXIT_TCPWRAP, + EXIT_PAM, + EXIT_NETWORK, + EXIT_NAMESPACE + +} ExitStatus; + +typedef enum ExitStatusLevel { + EXIT_STATUS_MINIMAL, + EXIT_STATUS_SYSTEMD, + EXIT_STATUS_LSB, + EXIT_STATUS_FULL = EXIT_STATUS_LSB +} ExitStatusLevel; + +const char* exit_status_to_string(ExitStatus status, ExitStatusLevel level); + +bool is_clean_exit(int code, int status); +bool is_clean_exit_lsb(int code, int status); + +#endif diff --git a/src/fdset.c b/src/fdset.c new file mode 100644 index 0000000..e67fe6f --- /dev/null +++ b/src/fdset.c @@ -0,0 +1,167 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "set.h" +#include "util.h" +#include "macro.h" +#include "fdset.h" + +#define MAKE_SET(s) ((Set*) s) +#define MAKE_FDSET(s) ((FDSet*) s) + +/* Make sure we can distuingish fd 0 and NULL */ +#define FD_TO_PTR(fd) INT_TO_PTR((fd)+1) +#define PTR_TO_FD(p) (PTR_TO_INT(p)-1) + +FDSet *fdset_new(void) { + return MAKE_FDSET(set_new(trivial_hash_func, trivial_compare_func)); +} + +void fdset_free(FDSet *s) { + void *p; + + while ((p = set_steal_first(MAKE_SET(s)))) { + /* Valgrind's fd might have ended up in this set here, + * due to fdset_new_fill(). We'll ignore all failures + * here, so that the EBADFD that valgrind will return + * us on close() doesn't influence us */ + + /* When reloading duplicates of the private bus + * connection fds and suchlike are closed here, which + * has no effect at all, since they are only + * duplicates. So don't be surprised about these log + * messages. */ + + log_debug("Closing left-over fd %i", PTR_TO_FD(p)); + close_nointr(PTR_TO_FD(p)); + } + + set_free(MAKE_SET(s)); +} + +int fdset_put(FDSet *s, int fd) { + assert(s); + assert(fd >= 0); + + return set_put(MAKE_SET(s), FD_TO_PTR(fd)); +} + +int fdset_put_dup(FDSet *s, int fd) { + int copy, r; + + assert(s); + assert(fd >= 0); + + if ((copy = fcntl(fd, F_DUPFD_CLOEXEC, 3)) < 0) + return -errno; + + if ((r = fdset_put(s, copy)) < 0) { + close_nointr_nofail(copy); + return r; + } + + return copy; +} + +bool fdset_contains(FDSet *s, int fd) { + assert(s); + assert(fd >= 0); + + return !!set_get(MAKE_SET(s), FD_TO_PTR(fd)); +} + +int fdset_remove(FDSet *s, int fd) { + assert(s); + assert(fd >= 0); + + return set_remove(MAKE_SET(s), FD_TO_PTR(fd)) ? fd : -ENOENT; +} + +int fdset_new_fill(FDSet **_s) { + DIR *d; + struct dirent *de; + int r = 0; + FDSet *s; + + assert(_s); + + /* Creates an fdsets and fills in all currently open file + * descriptors. */ + + if (!(d = opendir("/proc/self/fd"))) + return -errno; + + if (!(s = fdset_new())) { + r = -ENOMEM; + goto finish; + } + + while ((de = readdir(d))) { + int fd = -1; + + if (ignore_file(de->d_name)) + continue; + + if ((r = safe_atoi(de->d_name, &fd)) < 0) + goto finish; + + if (fd < 3) + continue; + + if (fd == dirfd(d)) + continue; + + if ((r = fdset_put(s, fd)) < 0) + goto finish; + } + + r = 0; + *_s = s; + s = NULL; + +finish: + closedir(d); + + /* We won't close the fds here! */ + if (s) + set_free(MAKE_SET(s)); + + return r; +} + +int fdset_cloexec(FDSet *fds, bool b) { + Iterator i; + void *p; + int r; + + assert(fds); + + SET_FOREACH(p, MAKE_SET(fds), i) + if ((r = fd_cloexec(PTR_TO_FD(p), b)) < 0) + return r; + + return 0; +} diff --git a/src/fdset.h b/src/fdset.h new file mode 100644 index 0000000..044a9e6 --- /dev/null +++ b/src/fdset.h @@ -0,0 +1,40 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foofdsethfoo +#define foofdsethfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct FDSet FDSet; + +FDSet* fdset_new(void); +void fdset_free(FDSet *s); + +int fdset_put(FDSet *s, int fd); +int fdset_put_dup(FDSet *s, int fd); + +bool fdset_contains(FDSet *s, int fd); +int fdset_remove(FDSet *s, int fd); + +int fdset_new_fill(FDSet **_s); + +int fdset_cloexec(FDSet *fds, bool b); + +#endif diff --git a/src/fsck.c b/src/fsck.c new file mode 100644 index 0000000..d3ac83c --- /dev/null +++ b/src/fsck.c @@ -0,0 +1,406 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "util.h" +#include "dbus-common.h" +#include "special.h" +#include "bus-errors.h" +#include "virt.h" + +static bool arg_skip = false; +static bool arg_force = false; +static bool arg_show_progress = false; + +static void start_target(const char *target, bool isolate) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + const char *mode, *basic_target = "basic.target"; + DBusConnection *bus = NULL; + + assert(target); + + dbus_error_init(&error); + + if (bus_connect(DBUS_BUS_SYSTEM, &bus, NULL, &error) < 0) { + log_error("Failed to get D-Bus connection: %s", bus_error_message(&error)); + goto finish; + } + + if (isolate) + mode = "isolate"; + else + mode = "replace"; + + log_info("Running request %s/start/%s", target, mode); + + if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnitReplace"))) { + log_error("Could not allocate message."); + goto finish; + } + + /* Start these units only if we can replace base.target with it */ + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &basic_target, + DBUS_TYPE_STRING, &target, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)) { + log_error("Could not attach target and flag information to message."); + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + + /* Don't print a warning if we aren't called during + * startup */ + if (!dbus_error_has_name(&error, BUS_ERROR_NO_SUCH_JOB)) + log_error("Failed to start unit: %s", bus_error_message(&error)); + + goto finish; + } + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + dbus_error_free(&error); +} + +static int parse_proc_cmdline(void) { + char *line, *w, *state; + int r; + size_t l; + + if (detect_container(NULL) > 0) + return 0; + + if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) { + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return 0; + } + + FOREACH_WORD_QUOTED(w, l, line, state) { + + if (strneq(w, "fsck.mode=auto", l)) + arg_force = arg_skip = false; + else if (strneq(w, "fsck.mode=force", l)) + arg_force = true; + else if (strneq(w, "fsck.mode=skip", l)) + arg_skip = true; + else if (startswith(w, "fsck.mode")) + log_warning("Invalid fsck.mode= parameter. Ignoring."); +#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA) + else if (strneq(w, "fastboot", l)) + arg_skip = true; + else if (strneq(w, "forcefsck", l)) + arg_force = true; +#endif + } + + free(line); + return 0; +} + +static void test_files(void) { + if (access("/fastboot", F_OK) >= 0) + arg_skip = true; + + if (access("/forcefsck", F_OK) >= 0) + arg_force = true; + + if (access("/run/systemd/show-status", F_OK) >= 0 || plymouth_running()) + arg_show_progress = true; +} + +static double percent(int pass, unsigned long cur, unsigned long max) { + /* Values stolen from e2fsck */ + + static const int pass_table[] = { + 0, 70, 90, 92, 95, 100 + }; + + if (pass <= 0) + return 0.0; + + if ((unsigned) pass >= ELEMENTSOF(pass_table) || max == 0) + return 100.0; + + return (double) pass_table[pass-1] + + ((double) pass_table[pass] - (double) pass_table[pass-1]) * + (double) cur / (double) max; +} + +static int process_progress(int fd) { + FILE *f, *console; + usec_t last = 0; + bool locked = false; + int clear = 0; + + f = fdopen(fd, "r"); + if (!f) { + close_nointr_nofail(fd); + return -errno; + } + + console = fopen("/dev/console", "w"); + if (!console) { + fclose(f); + return -ENOMEM; + } + + while (!feof(f)) { + int pass, m; + unsigned long cur, max; + char *device; + double p; + usec_t t; + + if (fscanf(f, "%i %lu %lu %ms", &pass, &cur, &max, &device) != 4) + break; + + /* Only show one progress counter at max */ + if (!locked) { + if (flock(fileno(console), LOCK_EX|LOCK_NB) < 0) { + free(device); + continue; + } + + locked = true; + } + + /* Only update once every 50ms */ + t = now(CLOCK_MONOTONIC); + if (last + 50 * USEC_PER_MSEC > t) { + free(device); + continue; + } + + last = t; + + p = percent(pass, cur, max); + fprintf(console, "\r%s: fsck %3.1f%% complete...\r%n", device, p, &m); + fflush(console); + + free(device); + + if (m > clear) + clear = m; + } + + if (clear > 0) { + unsigned j; + + fputc('\r', console); + for (j = 0; j < (unsigned) clear; j++) + fputc(' ', console); + fputc('\r', console); + fflush(console); + } + + fclose(f); + fclose(console); + return 0; +} + +int main(int argc, char *argv[]) { + const char *cmdline[9]; + int i = 0, r = EXIT_FAILURE, q; + pid_t pid; + siginfo_t status; + struct udev *udev = NULL; + struct udev_device *udev_device = NULL; + const char *device; + bool root_directory; + int progress_pipe[2] = { -1, -1 }; + char dash_c[2+10+1]; + + if (argc > 2) { + log_error("This program expects one or no arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + parse_proc_cmdline(); + test_files(); + + if (!arg_force && arg_skip) + return 0; + + if (argc > 1) { + device = argv[1]; + root_directory = false; + } else { + struct stat st; + struct timespec times[2]; + + /* Find root device */ + + if (stat("/", &st) < 0) { + log_error("Failed to stat() the root directory: %m"); + goto finish; + } + + /* Virtual root devices don't need an fsck */ + if (major(st.st_dev) == 0) + return 0; + + /* check if we are already writable */ + times[0] = st.st_atim; + times[1] = st.st_mtim; + if (utimensat(AT_FDCWD, "/", times, 0) == 0) { + log_info("Root directory is writable, skipping check."); + return 0; + } + + if (!(udev = udev_new())) { + log_error("Out of memory"); + goto finish; + } + + if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev))) { + log_error("Failed to detect root device."); + goto finish; + } + + if (!(device = udev_device_get_devnode(udev_device))) { + log_error("Failed to detect device node of root directory."); + goto finish; + } + + root_directory = true; + } + + if (arg_show_progress) + if (pipe(progress_pipe) < 0) { + log_error("pipe(): %m"); + goto finish; + } + + cmdline[i++] = "/sbin/fsck"; + cmdline[i++] = "-a"; + cmdline[i++] = "-T"; + cmdline[i++] = "-l"; + + if (!root_directory) + cmdline[i++] = "-M"; + + if (arg_force) + cmdline[i++] = "-f"; + + if (progress_pipe[1] >= 0) { + snprintf(dash_c, sizeof(dash_c), "-C%i", progress_pipe[1]); + char_array_0(dash_c); + cmdline[i++] = dash_c; + } + + cmdline[i++] = device; + cmdline[i++] = NULL; + + pid = fork(); + if (pid < 0) { + log_error("fork(): %m"); + goto finish; + } else if (pid == 0) { + /* Child */ + if (progress_pipe[0] >= 0) + close_nointr_nofail(progress_pipe[0]); + execv(cmdline[0], (char**) cmdline); + _exit(8); /* Operational error */ + } + + if (progress_pipe[1] >= 0) { + close_nointr_nofail(progress_pipe[1]); + progress_pipe[1] = -1; + } + + if (progress_pipe[0] >= 0) { + process_progress(progress_pipe[0]); + progress_pipe[0] = -1; + } + + q = wait_for_terminate(pid, &status); + if (q < 0) { + log_error("waitid(): %s", strerror(-q)); + goto finish; + } + + if (status.si_code != CLD_EXITED || (status.si_status & ~1)) { + + if (status.si_code == CLD_KILLED || status.si_code == CLD_DUMPED) + log_error("fsck terminated by signal %s.", signal_to_string(status.si_status)); + else if (status.si_code == CLD_EXITED) + log_error("fsck failed with error code %i.", status.si_status); + else + log_error("fsck failed due to unknown reason."); + + if (status.si_code == CLD_EXITED && (status.si_status & 2) && root_directory) + /* System should be rebooted. */ + start_target(SPECIAL_REBOOT_TARGET, false); + else if (status.si_code == CLD_EXITED && (status.si_status & 6)) + /* Some other problem */ + start_target(SPECIAL_EMERGENCY_TARGET, true); + else { + r = EXIT_SUCCESS; + log_warning("Ignoring error."); + } + + } else + r = EXIT_SUCCESS; + + if (status.si_code == CLD_EXITED && (status.si_status & 1)) + touch("/run/systemd/quotacheck"); + +finish: + if (udev_device) + udev_device_unref(udev_device); + + if (udev) + udev_unref(udev); + + close_pipe(progress_pipe); + + return r; +} diff --git a/src/getty-generator.c b/src/getty-generator.c new file mode 100644 index 0000000..1263785 --- /dev/null +++ b/src/getty-generator.c @@ -0,0 +1,182 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "unit-name.h" +#include "virt.h" + +const char *arg_dest = "/tmp"; + +static int add_symlink(const char *fservice, const char *tservice) { + char *from = NULL, *to = NULL; + int r; + + assert(fservice); + assert(tservice); + + asprintf(&from, SYSTEM_DATA_UNIT_PATH "/%s", fservice); + asprintf(&to, "%s/getty.target.wants/%s", arg_dest, tservice); + + if (!from || !to) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + mkdir_parents(to, 0755); + + r = symlink(from, to); + if (r < 0) { + if (errno == EEXIST) + /* In case console=hvc0 is passed this will very likely result in EEXIST */ + r = 0; + else { + log_error("Failed to create symlink from %s to %s: %m", from, to); + r = -errno; + } + } + +finish: + + free(from); + free(to); + + return r; +} + +static int add_serial_getty(const char *tty) { + char *n; + int r; + + assert(tty); + + log_debug("Automatically adding serial getty for /dev/%s.", tty); + + n = unit_name_replace_instance("serial-getty@.service", tty); + if (!n) { + log_error("Out of memory"); + return -ENOMEM; + } + + r = add_symlink("serial-getty@.service", n); + free(n); + + return r; +} + +int main(int argc, char *argv[]) { + + static const char virtualization_consoles[] = + "hvc0\0" + "xvc0\0" + "hvsi0\0"; + + int r = EXIT_SUCCESS; + char *active; + const char *j; + + if (argc > 2) { + log_error("This program takes one or no arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc > 1) + arg_dest = argv[1]; + + if (detect_container(NULL) > 0) { + log_debug("Automatically adding console shell."); + + if (add_symlink("console-shell.service", "console-shell.service") < 0) + r = EXIT_FAILURE; + + /* Don't add any further magic if we are in a container */ + goto finish; + } + + if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) { + const char *tty; + + tty = strrchr(active, ' '); + if (tty) + tty ++; + else + tty = active; + + /* Automatically add in a serial getty on the kernel + * console */ + if (tty_is_vc(tty)) + free(active); + else { + int k; + + /* We assume that gettys on virtual terminals are + * started via manual configuration and do this magic + * only for non-VC terminals. */ + + k = add_serial_getty(tty); + free(active); + + if (k < 0) { + r = EXIT_FAILURE; + goto finish; + } + } + } + + /* Automatically add in a serial getty on the first + * virtualizer console */ + NULSTR_FOREACH(j, virtualization_consoles) { + char *p; + int k; + + if (asprintf(&p, "/sys/class/tty/%s", j) < 0) { + log_error("Out of memory"); + r = EXIT_FAILURE; + goto finish; + } + + k = access(p, F_OK); + free(p); + + if (k < 0) + continue; + + k = add_serial_getty(j); + if (k < 0) { + r = EXIT_FAILURE; + goto finish; + } + } + +finish: + return r; +} diff --git a/src/gnome-ask-password-agent.c b/src/gnome-ask-password-agent.c new file mode 100644 index 0000000..fb49f22 --- /dev/null +++ b/src/gnome-ask-password-agent.c @@ -0,0 +1,1509 @@ +/* gnome-ask-password-agent.c generated by valac 0.14.0, the Vala compiler + * generated from gnome-ask-password-agent.vala, do not modify */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define TYPE_PASSWORD_DIALOG (password_dialog_get_type ()) +#define PASSWORD_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PASSWORD_DIALOG, PasswordDialog)) +#define PASSWORD_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_PASSWORD_DIALOG, PasswordDialogClass)) +#define IS_PASSWORD_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PASSWORD_DIALOG)) +#define IS_PASSWORD_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_PASSWORD_DIALOG)) +#define PASSWORD_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_PASSWORD_DIALOG, PasswordDialogClass)) + +typedef struct _PasswordDialog PasswordDialog; +typedef struct _PasswordDialogClass PasswordDialogClass; +typedef struct _PasswordDialogPrivate PasswordDialogPrivate; +#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) + +#define TYPE_MY_STATUS_ICON (my_status_icon_get_type ()) +#define MY_STATUS_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MY_STATUS_ICON, MyStatusIcon)) +#define MY_STATUS_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MY_STATUS_ICON, MyStatusIconClass)) +#define IS_MY_STATUS_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MY_STATUS_ICON)) +#define IS_MY_STATUS_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MY_STATUS_ICON)) +#define MY_STATUS_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MY_STATUS_ICON, MyStatusIconClass)) + +typedef struct _MyStatusIcon MyStatusIcon; +typedef struct _MyStatusIconClass MyStatusIconClass; +typedef struct _MyStatusIconPrivate MyStatusIconPrivate; +#define _g_free0(var) (var = (g_free (var), NULL)) +#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) +#define _g_key_file_free0(var) ((var == NULL) ? NULL : (var = (g_key_file_free (var), NULL))) + +struct _PasswordDialog { + GtkDialog parent_instance; + PasswordDialogPrivate * priv; + GtkEntry* entry; +}; + +struct _PasswordDialogClass { + GtkDialogClass parent_class; +}; + +struct _MyStatusIcon { + GtkStatusIcon parent_instance; + MyStatusIconPrivate * priv; +}; + +struct _MyStatusIconClass { + GtkStatusIconClass parent_class; +}; + +struct _MyStatusIconPrivate { + GFile* directory; + GFile* current; + GFileMonitor* file_monitor; + gchar* message; + gchar* icon; + gchar* socket; + PasswordDialog* password_dialog; +}; + + +static gpointer password_dialog_parent_class = NULL; +static gpointer my_status_icon_parent_class = NULL; + +gint clock_gettime (gint id, struct timespec* ts); +GType password_dialog_get_type (void) G_GNUC_CONST; +enum { + PASSWORD_DIALOG_DUMMY_PROPERTY +}; +PasswordDialog* password_dialog_new (const gchar* message, const gchar* icon); +PasswordDialog* password_dialog_construct (GType object_type, const gchar* message, const gchar* icon); +void password_dialog_on_entry_activated (PasswordDialog* self); +static void _password_dialog_on_entry_activated_gtk_entry_activate (GtkEntry* _sender, gpointer self); +static void password_dialog_finalize (GObject* obj); +GType my_status_icon_get_type (void) G_GNUC_CONST; +#define MY_STATUS_ICON_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_MY_STATUS_ICON, MyStatusIconPrivate)) +enum { + MY_STATUS_ICON_DUMMY_PROPERTY +}; +MyStatusIcon* my_status_icon_new (GError** error); +MyStatusIcon* my_status_icon_construct (GType object_type, GError** error); +static void my_status_icon_file_monitor_changed (MyStatusIcon* self, GFile* file, GFile* other_file, GFileMonitorEvent event_type); +static void _my_status_icon_file_monitor_changed_g_file_monitor_changed (GFileMonitor* _sender, GFile* file, GFile* other_file, GFileMonitorEvent event_type, gpointer self); +static void my_status_icon_look_for_password (MyStatusIcon* self, GError** error); +static void my_status_icon_status_icon_activate (MyStatusIcon* self); +static void _my_status_icon_status_icon_activate_gtk_status_icon_activate (GtkStatusIcon* _sender, gpointer self); +void show_error (const gchar* e); +static gboolean my_status_icon_load_password (MyStatusIcon* self, GError** error); +static void my_status_icon_finalize (GObject* obj); +gint _vala_main (gchar** args, int args_length1); +static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func); +static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func); + +const GOptionEntry entries[1] = {{NULL}}; + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ +static gpointer _g_object_ref0 (gpointer self) { +#line 43 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return self ? g_object_ref (self) : NULL; +#line 129 "gnome-ask-password-agent.c" +} + + +static void _password_dialog_on_entry_activated_gtk_entry_activate (GtkEntry* _sender, gpointer self) { +#line 63 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + password_dialog_on_entry_activated (self); +#line 136 "gnome-ask-password-agent.c" +} + + +PasswordDialog* password_dialog_construct (GType object_type, const gchar* message, const gchar* icon) { + PasswordDialog * self = NULL; + const gchar* _tmp0_; + GtkWidget* _tmp1_ = NULL; + GtkContainer* _tmp2_; + GtkContainer* content; + GtkHBox* _tmp3_; + GtkBox* _tmp4_; + GtkBox* hbox; + const gchar* _tmp5_; + GtkImage* _tmp6_; + GtkImage* _tmp7_; + GtkImage* image; + GtkVBox* _tmp8_; + GtkBox* _tmp9_; + GtkBox* vbox; + const gchar* _tmp10_; + GtkLabel* _tmp11_; + GtkLabel* _tmp12_; + GtkLabel* label; + GtkEntry* _tmp13_; + GtkEntry* _tmp14_; + GtkEntry* _tmp15_; + GtkEntry* _tmp16_; + GtkEntry* _tmp17_; + GtkEntry* _tmp18_; +#line 33 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_return_val_if_fail (message != NULL, NULL); +#line 33 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_return_val_if_fail (icon != NULL, NULL); +#line 33 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self = (PasswordDialog*) g_object_new (object_type, NULL); +#line 34 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_window_set_title ((GtkWindow*) self, "System Password"); +#line 35 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_dialog_set_has_separator ((GtkDialog*) self, FALSE); +#line 36 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_container_set_border_width ((GtkContainer*) self, (guint) 8); +#line 37 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_dialog_set_default_response ((GtkDialog*) self, (gint) GTK_RESPONSE_OK); +#line 38 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp0_ = icon; +#line 38 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_window_set_icon_name ((GtkWindow*) self, _tmp0_); +#line 40 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_dialog_add_button ((GtkDialog*) self, GTK_STOCK_CANCEL, (gint) GTK_RESPONSE_CANCEL); +#line 41 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_dialog_add_button ((GtkDialog*) self, GTK_STOCK_OK, (gint) GTK_RESPONSE_OK); +#line 43 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp1_ = gtk_dialog_get_content_area ((GtkDialog*) self); +#line 43 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp2_ = _g_object_ref0 (GTK_CONTAINER (_tmp1_)); +#line 43 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + content = _tmp2_; +#line 45 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp3_ = (GtkHBox*) gtk_hbox_new (FALSE, 16); +#line 45 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp4_ = (GtkBox*) g_object_ref_sink (_tmp3_); +#line 45 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + hbox = _tmp4_; +#line 46 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_container_set_border_width ((GtkContainer*) hbox, (guint) 8); +#line 47 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_container_add (content, (GtkWidget*) hbox); +#line 49 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp5_ = icon; +#line 49 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp6_ = (GtkImage*) gtk_image_new_from_icon_name (_tmp5_, GTK_ICON_SIZE_DIALOG); +#line 49 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp7_ = g_object_ref_sink (_tmp6_); +#line 49 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + image = _tmp7_; +#line 50 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_box_pack_start (hbox, (GtkWidget*) image, FALSE, FALSE, (guint) 0); +#line 52 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp8_ = (GtkVBox*) gtk_vbox_new (FALSE, 8); +#line 52 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp9_ = (GtkBox*) g_object_ref_sink (_tmp8_); +#line 52 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + vbox = _tmp9_; +#line 53 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_box_pack_start (hbox, (GtkWidget*) vbox, TRUE, TRUE, (guint) 0); +#line 55 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp10_ = message; +#line 55 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp11_ = (GtkLabel*) gtk_label_new (_tmp10_); +#line 55 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp12_ = g_object_ref_sink (_tmp11_); +#line 55 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + label = _tmp12_; +#line 56 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_box_pack_start (vbox, (GtkWidget*) label, FALSE, FALSE, (guint) 0); +#line 58 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp13_ = (GtkEntry*) gtk_entry_new (); +#line 58 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp14_ = g_object_ref_sink (_tmp13_); +#line 58 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self->entry); +#line 58 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->entry = _tmp14_; +#line 59 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp15_ = self->entry; +#line 59 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_entry_set_visibility (_tmp15_, FALSE); +#line 60 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp16_ = self->entry; +#line 60 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_entry_set_activates_default (_tmp16_, TRUE); +#line 61 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp17_ = self->entry; +#line 61 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_box_pack_start (vbox, (GtkWidget*) _tmp17_, FALSE, FALSE, (guint) 0); +#line 63 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp18_ = self->entry; +#line 63 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_signal_connect_object (_tmp18_, "activate", (GCallback) _password_dialog_on_entry_activated_gtk_entry_activate, self, 0); +#line 65 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_widget_show_all ((GtkWidget*) self); +#line 33 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (label); +#line 33 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (vbox); +#line 33 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (image); +#line 33 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (hbox); +#line 33 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (content); +#line 33 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return self; +#line 270 "gnome-ask-password-agent.c" +} + + +PasswordDialog* password_dialog_new (const gchar* message, const gchar* icon) { +#line 33 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return password_dialog_construct (TYPE_PASSWORD_DIALOG, message, icon); +#line 277 "gnome-ask-password-agent.c" +} + + +void password_dialog_on_entry_activated (PasswordDialog* self) { +#line 68 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_return_if_fail (self != NULL); +#line 69 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_dialog_response ((GtkDialog*) self, (gint) GTK_RESPONSE_OK); +#line 286 "gnome-ask-password-agent.c" +} + + +static void password_dialog_class_init (PasswordDialogClass * klass) { +#line 29 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + password_dialog_parent_class = g_type_class_peek_parent (klass); +#line 29 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + G_OBJECT_CLASS (klass)->finalize = password_dialog_finalize; +#line 295 "gnome-ask-password-agent.c" +} + + +static void password_dialog_instance_init (PasswordDialog * self) { +} + + +static void password_dialog_finalize (GObject* obj) { + PasswordDialog * self; +#line 29 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self = PASSWORD_DIALOG (obj); +#line 31 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self->entry); +#line 29 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + G_OBJECT_CLASS (password_dialog_parent_class)->finalize (obj); +#line 311 "gnome-ask-password-agent.c" +} + + +GType password_dialog_get_type (void) { + static volatile gsize password_dialog_type_id__volatile = 0; + if (g_once_init_enter (&password_dialog_type_id__volatile)) { + static const GTypeInfo g_define_type_info = { sizeof (PasswordDialogClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) password_dialog_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (PasswordDialog), 0, (GInstanceInitFunc) password_dialog_instance_init, NULL }; + GType password_dialog_type_id; + password_dialog_type_id = g_type_register_static (GTK_TYPE_DIALOG, "PasswordDialog", &g_define_type_info, 0); + g_once_init_leave (&password_dialog_type_id__volatile, password_dialog_type_id); + } + return password_dialog_type_id__volatile; +} + + +static void _my_status_icon_file_monitor_changed_g_file_monitor_changed (GFileMonitor* _sender, GFile* file, GFile* other_file, GFileMonitorEvent event_type, gpointer self) { +#line 91 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + my_status_icon_file_monitor_changed (self, file, other_file, event_type); +#line 330 "gnome-ask-password-agent.c" +} + + +static void _my_status_icon_status_icon_activate_gtk_status_icon_activate (GtkStatusIcon* _sender, gpointer self) { +#line 96 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + my_status_icon_status_icon_activate (self); +#line 337 "gnome-ask-password-agent.c" +} + + +MyStatusIcon* my_status_icon_construct (GType object_type, GError** error) { + MyStatusIcon * self = NULL; + GFile* _tmp0_ = NULL; + GFile* _tmp1_; + GFileMonitor* _tmp2_ = NULL; + GFileMonitor* _tmp3_; + GFileMonitor* _tmp4_; + GError * _inner_error_ = NULL; +#line 86 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self = (MyStatusIcon*) g_object_new (object_type, "icon-name", "dialog-password", NULL); +#line 87 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_status_icon_set_title ((GtkStatusIcon*) self, "System Password Request"); +#line 89 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp0_ = g_file_new_for_path ("/run/systemd/ask-password/"); +#line 89 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self->priv->directory); +#line 89 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->priv->directory = _tmp0_; +#line 90 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp1_ = self->priv->directory; +#line 90 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp2_ = g_file_monitor_directory (_tmp1_, 0, NULL, &_inner_error_); +#line 90 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp3_ = _tmp2_; +#line 90 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 90 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_propagate_error (error, _inner_error_); +#line 90 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self); +#line 90 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return NULL; +#line 373 "gnome-ask-password-agent.c" + } +#line 90 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self->priv->file_monitor); +#line 90 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->priv->file_monitor = _tmp3_; +#line 91 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp4_ = self->priv->file_monitor; +#line 91 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_signal_connect_object (_tmp4_, "changed", (GCallback) _my_status_icon_file_monitor_changed_g_file_monitor_changed, self, 0); +#line 93 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self->priv->current); +#line 93 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->priv->current = NULL; +#line 94 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + my_status_icon_look_for_password (self, &_inner_error_); +#line 94 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 94 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_propagate_error (error, _inner_error_); +#line 94 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self); +#line 94 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return NULL; +#line 397 "gnome-ask-password-agent.c" + } +#line 96 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_signal_connect_object ((GtkStatusIcon*) self, "activate", (GCallback) _my_status_icon_status_icon_activate_gtk_status_icon_activate, self, 0); +#line 85 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return self; +#line 403 "gnome-ask-password-agent.c" +} + + +MyStatusIcon* my_status_icon_new (GError** error) { +#line 85 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return my_status_icon_construct (TYPE_MY_STATUS_ICON, error); +#line 410 "gnome-ask-password-agent.c" +} + + +static void my_status_icon_file_monitor_changed (MyStatusIcon* self, GFile* file, GFile* other_file, GFileMonitorEvent event_type) { + GFile* _tmp0_; + gchar* _tmp1_ = NULL; + gchar* _tmp2_; + gboolean _tmp3_ = FALSE; + gboolean _tmp4_; + gboolean _tmp5_ = FALSE; + GFileMonitorEvent _tmp6_; + gboolean _tmp8_; + GError * _inner_error_ = NULL; +#line 99 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_return_if_fail (self != NULL); +#line 99 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_return_if_fail (file != NULL); +#line 101 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp0_ = file; +#line 101 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp1_ = g_file_get_basename (_tmp0_); +#line 101 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp2_ = _tmp1_; +#line 101 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp3_ = g_str_has_prefix (_tmp2_, "ask."); +#line 101 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp4_ = !_tmp3_; +#line 101 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (_tmp2_); +#line 101 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp4_) { +#line 102 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return; +#line 444 "gnome-ask-password-agent.c" + } +#line 104 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp6_ = event_type; +#line 104 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp6_ == G_FILE_MONITOR_EVENT_CREATED) { +#line 104 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp5_ = TRUE; +#line 452 "gnome-ask-password-agent.c" + } else { + GFileMonitorEvent _tmp7_; +#line 105 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp7_ = event_type; +#line 105 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp5_ = _tmp7_ == G_FILE_MONITOR_EVENT_DELETED; +#line 459 "gnome-ask-password-agent.c" + } +#line 104 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp8_ = _tmp5_; +#line 104 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp8_) { +#line 465 "gnome-ask-password-agent.c" + { +#line 107 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + my_status_icon_look_for_password (self, &_inner_error_); +#line 107 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 471 "gnome-ask-password-agent.c" + goto __catch0_g_error; + } + } + goto __finally0; + __catch0_g_error: + { + GError* e = NULL; + GError* _tmp9_; + const gchar* _tmp10_; +#line 106 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + e = _inner_error_; +#line 106 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _inner_error_ = NULL; +#line 109 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp9_ = e; +#line 109 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp10_ = _tmp9_->message; +#line 109 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + show_error (_tmp10_); +#line 106 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_error_free0 (e); +#line 493 "gnome-ask-password-agent.c" + } + __finally0: +#line 106 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 106 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 106 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_clear_error (&_inner_error_); +#line 106 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return; +#line 504 "gnome-ask-password-agent.c" + } + } +} + + +static void my_status_icon_look_for_password (MyStatusIcon* self, GError** error) { + GFile* _tmp0_; + GFile* _tmp5_; + GFile* _tmp21_; + GError * _inner_error_ = NULL; +#line 114 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_return_if_fail (self != NULL); +#line 116 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp0_ = self->priv->current; +#line 116 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp0_ != NULL) { +#line 521 "gnome-ask-password-agent.c" + GFile* _tmp1_; + gboolean _tmp2_ = FALSE; +#line 117 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp1_ = self->priv->current; +#line 117 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp2_ = g_file_query_exists (_tmp1_, NULL); +#line 117 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (!_tmp2_) { +#line 530 "gnome-ask-password-agent.c" + PasswordDialog* _tmp3_; +#line 118 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self->priv->current); +#line 118 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->priv->current = NULL; +#line 119 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp3_ = self->priv->password_dialog; +#line 119 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp3_ != NULL) { +#line 540 "gnome-ask-password-agent.c" + PasswordDialog* _tmp4_; +#line 120 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp4_ = self->priv->password_dialog; +#line 120 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_dialog_response ((GtkDialog*) _tmp4_, (gint) GTK_RESPONSE_REJECT); +#line 546 "gnome-ask-password-agent.c" + } + } + } +#line 124 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp5_ = self->priv->current; +#line 124 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp5_ == NULL) { +#line 554 "gnome-ask-password-agent.c" + GFile* _tmp6_; + GFileEnumerator* _tmp7_ = NULL; + GFileEnumerator* enumerator; + GFileInfo* i = NULL; +#line 125 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp6_ = self->priv->directory; +#line 125 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp7_ = g_file_enumerate_children (_tmp6_, "standard::name", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &_inner_error_); +#line 125 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + enumerator = _tmp7_; +#line 125 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 125 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_propagate_error (error, _inner_error_); +#line 125 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return; +#line 571 "gnome-ask-password-agent.c" + } +#line 128 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + while (TRUE) { +#line 575 "gnome-ask-password-agent.c" + GFileEnumerator* _tmp8_; + GFileInfo* _tmp9_ = NULL; + GFileInfo* _tmp10_; + GFileInfo* _tmp11_; + GFileInfo* _tmp12_; + const gchar* _tmp13_ = NULL; + gboolean _tmp14_ = FALSE; + GFile* _tmp15_; + GFileInfo* _tmp16_; + const gchar* _tmp17_ = NULL; + GFile* _tmp18_ = NULL; + gboolean _tmp19_ = FALSE; + gboolean _tmp20_; +#line 128 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp8_ = enumerator; +#line 128 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp9_ = g_file_enumerator_next_file (_tmp8_, NULL, &_inner_error_); +#line 128 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp10_ = _tmp9_; +#line 128 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 128 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_propagate_error (error, _inner_error_); +#line 128 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (i); +#line 128 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (enumerator); +#line 128 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return; +#line 605 "gnome-ask-password-agent.c" + } +#line 128 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (i); +#line 128 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + i = _tmp10_; +#line 128 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp11_ = i; +#line 128 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (!(_tmp11_ != NULL)) { +#line 128 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + break; +#line 617 "gnome-ask-password-agent.c" + } +#line 129 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp12_ = i; +#line 129 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp13_ = g_file_info_get_name (_tmp12_); +#line 129 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp14_ = g_str_has_prefix (_tmp13_, "ask."); +#line 129 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (!_tmp14_) { +#line 130 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + continue; +#line 629 "gnome-ask-password-agent.c" + } +#line 132 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp15_ = self->priv->directory; +#line 132 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp16_ = i; +#line 132 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp17_ = g_file_info_get_name (_tmp16_); +#line 132 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp18_ = g_file_get_child (_tmp15_, _tmp17_); +#line 132 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self->priv->current); +#line 132 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->priv->current = _tmp18_; +#line 134 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp19_ = my_status_icon_load_password (self, &_inner_error_); +#line 134 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp20_ = _tmp19_; +#line 134 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 134 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_propagate_error (error, _inner_error_); +#line 134 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (i); +#line 134 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (enumerator); +#line 134 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return; +#line 657 "gnome-ask-password-agent.c" + } +#line 134 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp20_) { +#line 135 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + break; +#line 663 "gnome-ask-password-agent.c" + } +#line 137 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self->priv->current); +#line 137 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->priv->current = NULL; +#line 669 "gnome-ask-password-agent.c" + } +#line 124 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (i); +#line 124 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (enumerator); +#line 675 "gnome-ask-password-agent.c" + } +#line 141 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp21_ = self->priv->current; +#line 141 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp21_ == NULL) { +#line 142 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_status_icon_set_visible ((GtkStatusIcon*) self, FALSE); +#line 683 "gnome-ask-password-agent.c" + } +} + + +static gboolean my_status_icon_load_password (MyStatusIcon* self, GError** error) { + gboolean result = FALSE; + GKeyFile* _tmp0_; + GKeyFile* key_file; + const gchar* _tmp28_; + const gchar* _tmp33_; + const gchar* _tmp34_; + const gchar* _tmp35_; + const gchar* _tmp36_; + const gchar* _tmp37_; + NotifyNotification* _tmp38_; + NotifyNotification* n; + NotifyNotification* _tmp39_; + NotifyNotification* _tmp40_; + GError * _inner_error_ = NULL; +#line 145 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_return_val_if_fail (self != NULL, FALSE); +#line 147 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp0_ = g_key_file_new (); +#line 147 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + key_file = _tmp0_; +#line 709 "gnome-ask-password-agent.c" + { + struct timespec ts = {0}; + GKeyFile* _tmp1_; + GFile* _tmp2_; + gchar* _tmp3_ = NULL; + gchar* _tmp4_; + GKeyFile* _tmp5_; + gchar* _tmp6_ = NULL; + gchar* not_after_as_string; + struct timespec _tmp7_ = {0}; + struct timespec _tmp8_; + time_t _tmp9_; + struct timespec _tmp10_; + glong _tmp11_; + guint64 now; + guint64 not_after = 0ULL; + const gchar* _tmp12_; + gint _tmp13_ = 0; + gboolean _tmp14_ = FALSE; + guint64 _tmp15_; + gboolean _tmp18_; + GKeyFile* _tmp19_; + gchar* _tmp20_ = NULL; + gchar* _tmp21_; +#line 152 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp1_ = key_file; +#line 152 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp2_ = self->priv->current; +#line 152 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp3_ = g_file_get_path (_tmp2_); +#line 152 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp4_ = _tmp3_; +#line 152 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_key_file_load_from_file (_tmp1_, _tmp4_, G_KEY_FILE_NONE, &_inner_error_); +#line 152 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (_tmp4_); +#line 152 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 748 "gnome-ask-password-agent.c" + goto __catch1_g_error; + } +#line 154 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp5_ = key_file; +#line 154 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp6_ = g_key_file_get_string (_tmp5_, "Ask", "NotAfter", &_inner_error_); +#line 154 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + not_after_as_string = _tmp6_; +#line 154 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 759 "gnome-ask-password-agent.c" + goto __catch1_g_error; + } +#line 156 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + clock_gettime (1, &_tmp7_); +#line 156 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + ts = _tmp7_; +#line 157 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp8_ = ts; +#line 157 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp9_ = _tmp8_.tv_sec; +#line 157 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp10_ = ts; +#line 157 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp11_ = _tmp10_.tv_nsec; +#line 157 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + now = (guint64) ((_tmp9_ * 1000000) + (_tmp11_ / 1000)); +#line 160 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp12_ = not_after_as_string; +#line 160 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp13_ = sscanf (_tmp12_, "%llu", ¬_after); +#line 160 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp13_ != 1) { +#line 161 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + result = FALSE; +#line 161 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (not_after_as_string); +#line 161 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_key_file_free0 (key_file); +#line 161 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return result; +#line 790 "gnome-ask-password-agent.c" + } +#line 163 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp15_ = not_after; +#line 163 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp15_ > ((guint64) 0)) { +#line 796 "gnome-ask-password-agent.c" + guint64 _tmp16_; + guint64 _tmp17_; +#line 163 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp16_ = not_after; +#line 163 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp17_ = now; +#line 163 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp14_ = _tmp16_ < _tmp17_; +#line 805 "gnome-ask-password-agent.c" + } else { +#line 163 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp14_ = FALSE; +#line 809 "gnome-ask-password-agent.c" + } +#line 163 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp18_ = _tmp14_; +#line 163 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp18_) { +#line 164 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + result = FALSE; +#line 164 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (not_after_as_string); +#line 164 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_key_file_free0 (key_file); +#line 164 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return result; +#line 823 "gnome-ask-password-agent.c" + } +#line 166 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp19_ = key_file; +#line 166 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp20_ = g_key_file_get_string (_tmp19_, "Ask", "Socket", &_inner_error_); +#line 166 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp21_ = _tmp20_; +#line 166 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 166 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (not_after_as_string); +#line 835 "gnome-ask-password-agent.c" + goto __catch1_g_error; + } +#line 166 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (self->priv->socket); +#line 166 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->priv->socket = _tmp21_; +#line 149 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (not_after_as_string); +#line 844 "gnome-ask-password-agent.c" + } + goto __finally1; + __catch1_g_error: + { + GError* e = NULL; +#line 149 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + e = _inner_error_; +#line 149 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _inner_error_ = NULL; +#line 168 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + result = FALSE; +#line 168 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_error_free0 (e); +#line 168 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_key_file_free0 (key_file); +#line 168 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return result; +#line 862 "gnome-ask-password-agent.c" + } + __finally1: +#line 149 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 149 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_propagate_error (error, _inner_error_); +#line 149 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_key_file_free0 (key_file); +#line 149 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return FALSE; +#line 873 "gnome-ask-password-agent.c" + } + { + GKeyFile* _tmp22_; + gchar* _tmp23_ = NULL; + gchar* _tmp24_; + gchar* _tmp25_; + gchar* _tmp26_ = NULL; +#line 172 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp22_ = key_file; +#line 172 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp23_ = g_key_file_get_string (_tmp22_, "Ask", "Message", &_inner_error_); +#line 172 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp24_ = _tmp23_; +#line 172 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 889 "gnome-ask-password-agent.c" + goto __catch2_g_error; + } +#line 172 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp25_ = _tmp24_; +#line 172 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp26_ = g_strcompress (_tmp25_); +#line 172 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (self->priv->message); +#line 172 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->priv->message = _tmp26_; +#line 172 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (_tmp25_); +#line 902 "gnome-ask-password-agent.c" + } + goto __finally2; + __catch2_g_error: + { + GError* e = NULL; + gchar* _tmp27_; +#line 171 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + e = _inner_error_; +#line 171 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _inner_error_ = NULL; +#line 174 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp27_ = g_strdup ("Please Enter System Password!"); +#line 174 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (self->priv->message); +#line 174 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->priv->message = _tmp27_; +#line 171 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_error_free0 (e); +#line 921 "gnome-ask-password-agent.c" + } + __finally2: +#line 171 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 171 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_propagate_error (error, _inner_error_); +#line 171 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_key_file_free0 (key_file); +#line 171 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return FALSE; +#line 932 "gnome-ask-password-agent.c" + } +#line 177 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp28_ = self->priv->message; +#line 177 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_status_icon_set_tooltip_text ((GtkStatusIcon*) self, _tmp28_); +#line 938 "gnome-ask-password-agent.c" + { + GKeyFile* _tmp29_; + gchar* _tmp30_ = NULL; + gchar* _tmp31_; +#line 180 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp29_ = key_file; +#line 180 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp30_ = g_key_file_get_string (_tmp29_, "Ask", "Icon", &_inner_error_); +#line 180 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp31_ = _tmp30_; +#line 180 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 951 "gnome-ask-password-agent.c" + goto __catch3_g_error; + } +#line 180 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (self->priv->icon); +#line 180 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->priv->icon = _tmp31_; +#line 958 "gnome-ask-password-agent.c" + } + goto __finally3; + __catch3_g_error: + { + GError* e = NULL; + gchar* _tmp32_; +#line 179 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + e = _inner_error_; +#line 179 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _inner_error_ = NULL; +#line 182 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp32_ = g_strdup ("dialog-password"); +#line 182 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (self->priv->icon); +#line 182 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->priv->icon = _tmp32_; +#line 179 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_error_free0 (e); +#line 977 "gnome-ask-password-agent.c" + } + __finally3: +#line 179 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 179 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_propagate_error (error, _inner_error_); +#line 179 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_key_file_free0 (key_file); +#line 179 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return FALSE; +#line 988 "gnome-ask-password-agent.c" + } +#line 184 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp33_ = self->priv->icon; +#line 184 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_status_icon_set_from_icon_name ((GtkStatusIcon*) self, _tmp33_); +#line 186 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_status_icon_set_visible ((GtkStatusIcon*) self, TRUE); +#line 188 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp34_ = gtk_status_icon_get_title ((GtkStatusIcon*) self); +#line 188 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp35_ = _tmp34_; +#line 188 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp36_ = self->priv->message; +#line 188 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp37_ = self->priv->icon; +#line 188 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp38_ = notify_notification_new (_tmp35_, _tmp36_, _tmp37_); +#line 188 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + n = _tmp38_; +#line 189 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp39_ = n; +#line 189 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + notify_notification_set_timeout (_tmp39_, 5000); +#line 190 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp40_ = n; +#line 190 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + notify_notification_show (_tmp40_, &_inner_error_); +#line 190 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 190 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_propagate_error (error, _inner_error_); +#line 190 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (n); +#line 190 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_key_file_free0 (key_file); +#line 190 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return FALSE; +#line 1026 "gnome-ask-password-agent.c" + } +#line 192 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + result = TRUE; +#line 192 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (n); +#line 192 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_key_file_free0 (key_file); +#line 192 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return result; +#line 1036 "gnome-ask-password-agent.c" +} + + +static guint8* string_get_data (const gchar* self, int* result_length1) { + guint8* result; + guint8* res; + gint res_length1; + gint _res_size_; + gint _tmp0_; + gint _tmp1_; + gint _tmp2_; + guint8* _tmp3_; + gint _tmp3__length1; + guint8* _tmp4_; + gint _tmp4__length1; +#line 1404 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + g_return_val_if_fail (self != NULL, NULL); +#line 1405 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + res = (guint8*) self; +#line 1405 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + res_length1 = -1; +#line 1405 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + _res_size_ = res_length1; +#line 1406 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + _tmp0_ = strlen (self); +#line 1406 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + _tmp1_ = _tmp0_; +#line 1406 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + res_length1 = (gint) _tmp1_; +#line 1406 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + _tmp2_ = res_length1; +#line 1407 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + _tmp3_ = res; +#line 1407 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + _tmp3__length1 = res_length1; +#line 1407 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + _tmp4_ = _tmp3_; +#line 1407 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + _tmp4__length1 = _tmp3__length1; +#line 1407 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + if (result_length1) { +#line 1407 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + *result_length1 = _tmp4__length1; +#line 1080 "gnome-ask-password-agent.c" + } +#line 1407 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + result = _tmp4_; +#line 1407 "/usr/share/vala-0.14/vapi/glib-2.0.vapi" + return result; +#line 1086 "gnome-ask-password-agent.c" +} + + +static void my_status_icon_status_icon_activate (MyStatusIcon* self) { + GFile* _tmp0_; + PasswordDialog* _tmp1_; + const gchar* _tmp3_; + const gchar* _tmp4_; + PasswordDialog* _tmp5_; + PasswordDialog* _tmp6_; + PasswordDialog* _tmp7_; + gint _tmp8_ = 0; + gint _result_; + PasswordDialog* _tmp9_; + GtkEntry* _tmp10_; + const gchar* _tmp11_ = NULL; + gchar* _tmp12_; + gchar* password; + PasswordDialog* _tmp13_; + gboolean _tmp14_ = FALSE; + gint _tmp15_; + gboolean _tmp17_; + gint to_process = 0; + GError * _inner_error_ = NULL; +#line 195 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_return_if_fail (self != NULL); +#line 197 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp0_ = self->priv->current; +#line 197 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp0_ == NULL) { +#line 198 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return; +#line 1119 "gnome-ask-password-agent.c" + } +#line 200 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp1_ = self->priv->password_dialog; +#line 200 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp1_ != NULL) { +#line 1125 "gnome-ask-password-agent.c" + PasswordDialog* _tmp2_; +#line 201 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp2_ = self->priv->password_dialog; +#line 201 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_window_present ((GtkWindow*) _tmp2_); +#line 202 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return; +#line 1133 "gnome-ask-password-agent.c" + } +#line 205 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp3_ = self->priv->message; +#line 205 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp4_ = self->priv->icon; +#line 205 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp5_ = password_dialog_new (_tmp3_, _tmp4_); +#line 205 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp6_ = g_object_ref_sink (_tmp5_); +#line 205 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self->priv->password_dialog); +#line 205 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->priv->password_dialog = _tmp6_; +#line 207 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp7_ = self->priv->password_dialog; +#line 207 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp8_ = gtk_dialog_run ((GtkDialog*) _tmp7_); +#line 207 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _result_ = _tmp8_; +#line 208 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp9_ = self->priv->password_dialog; +#line 208 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp10_ = _tmp9_->entry; +#line 208 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp11_ = gtk_entry_get_text (_tmp10_); +#line 208 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp12_ = g_strdup (_tmp11_); +#line 208 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + password = _tmp12_; +#line 210 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp13_ = self->priv->password_dialog; +#line 210 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_object_destroy ((GtkObject*) _tmp13_); +#line 211 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self->priv->password_dialog); +#line 211 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->priv->password_dialog = NULL; +#line 213 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp15_ = _result_; +#line 213 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp15_ == ((gint) GTK_RESPONSE_REJECT)) { +#line 213 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp14_ = TRUE; +#line 1177 "gnome-ask-password-agent.c" + } else { + gint _tmp16_; +#line 214 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp16_ = _result_; +#line 214 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp14_ = _tmp16_ == ((gint) GTK_RESPONSE_DELETE_EVENT); +#line 1184 "gnome-ask-password-agent.c" + } +#line 213 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp17_ = _tmp14_; +#line 213 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp17_) { +#line 215 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (password); +#line 215 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return; +#line 1194 "gnome-ask-password-agent.c" + } + { + const gchar* _tmp18_ = NULL; + gint _tmp19_; + gchar* _tmp20_; + gchar* _tmp21_; + const gchar* _tmp22_; + gchar* _tmp23_; + const gchar* _tmp24_; + gchar* _tmp25_; + gchar** _tmp26_ = NULL; + gchar** _tmp27_; + gint _tmp27__length1; + gint _tmp28_ = 0; + gint _tmp29_; + GUnixOutputStream* _tmp30_; + GOutputStream* stream; + GOutputStream* _tmp31_; + const gchar* _tmp32_; + guint8* _tmp33_; + gint _tmp33__length1; + guint8* _tmp34_; + gint _tmp34__length1; +#line 222 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp19_ = _result_; +#line 222 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_tmp19_ == ((gint) GTK_RESPONSE_OK)) { +#line 222 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp18_ = "1"; +#line 1224 "gnome-ask-password-agent.c" + } else { +#line 222 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp18_ = "0"; +#line 1228 "gnome-ask-password-agent.c" + } +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp20_ = g_strdup ("/usr/bin/pkexec"); +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp21_ = g_strdup ("/lib/systemd/systemd-reply-password"); +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp22_ = _tmp18_; +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp23_ = g_strdup (_tmp22_); +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp24_ = self->priv->socket; +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp25_ = g_strdup (_tmp24_); +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp26_ = g_new0 (gchar*, 4 + 1); +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp26_[0] = _tmp20_; +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp26_[1] = _tmp21_; +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp26_[2] = _tmp23_; +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp26_[3] = _tmp25_; +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp27_ = _tmp26_; +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp27__length1 = 4; +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_spawn_async_with_pipes (NULL, _tmp27_, NULL, 0, NULL, NULL, NULL, &_tmp28_, NULL, NULL, &_inner_error_); +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + to_process = _tmp28_; +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp27_ = (_vala_array_free (_tmp27_, _tmp27__length1, (GDestroyNotify) g_free), NULL); +#line 220 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 1264 "gnome-ask-password-agent.c" + goto __catch4_g_error; + } +#line 231 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp29_ = to_process; +#line 231 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp30_ = (GUnixOutputStream*) g_unix_output_stream_new (_tmp29_, TRUE); +#line 231 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + stream = (GOutputStream*) _tmp30_; +#line 233 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp31_ = stream; +#line 233 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp32_ = password; +#line 233 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp33_ = string_get_data (_tmp32_, &_tmp33__length1); +#line 233 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp34_ = _tmp33_; +#line 233 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp34__length1 = _tmp33__length1; +#line 233 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_output_stream_write (_tmp31_, _tmp34_, (gsize) _tmp34__length1, NULL, &_inner_error_); +#line 233 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 233 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (stream); +#line 1289 "gnome-ask-password-agent.c" + goto __catch4_g_error; + } +#line 219 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (stream); +#line 1294 "gnome-ask-password-agent.c" + } + goto __finally4; + __catch4_g_error: + { + GError* e = NULL; + GError* _tmp35_; + const gchar* _tmp36_; +#line 219 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + e = _inner_error_; +#line 219 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _inner_error_ = NULL; +#line 238 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp35_ = e; +#line 238 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp36_ = _tmp35_->message; +#line 238 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + show_error (_tmp36_); +#line 219 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_error_free0 (e); +#line 1314 "gnome-ask-password-agent.c" + } + __finally4: +#line 219 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 219 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (password); +#line 219 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 219 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_clear_error (&_inner_error_); +#line 219 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return; +#line 1327 "gnome-ask-password-agent.c" + } +#line 195 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (password); +#line 1331 "gnome-ask-password-agent.c" +} + + +static void my_status_icon_class_init (MyStatusIconClass * klass) { +#line 73 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + my_status_icon_parent_class = g_type_class_peek_parent (klass); +#line 73 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_type_class_add_private (klass, sizeof (MyStatusIconPrivate)); +#line 73 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + G_OBJECT_CLASS (klass)->finalize = my_status_icon_finalize; +#line 1342 "gnome-ask-password-agent.c" +} + + +static void my_status_icon_instance_init (MyStatusIcon * self) { +#line 73 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self->priv = MY_STATUS_ICON_GET_PRIVATE (self); +#line 1349 "gnome-ask-password-agent.c" +} + + +static void my_status_icon_finalize (GObject* obj) { + MyStatusIcon * self; +#line 73 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + self = MY_STATUS_ICON (obj); +#line 75 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self->priv->directory); +#line 76 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self->priv->current); +#line 77 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self->priv->file_monitor); +#line 79 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (self->priv->message); +#line 80 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (self->priv->icon); +#line 81 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_free0 (self->priv->socket); +#line 83 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (self->priv->password_dialog); +#line 73 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + G_OBJECT_CLASS (my_status_icon_parent_class)->finalize (obj); +#line 1373 "gnome-ask-password-agent.c" +} + + +GType my_status_icon_get_type (void) { + static volatile gsize my_status_icon_type_id__volatile = 0; + if (g_once_init_enter (&my_status_icon_type_id__volatile)) { + static const GTypeInfo g_define_type_info = { sizeof (MyStatusIconClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) my_status_icon_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (MyStatusIcon), 0, (GInstanceInitFunc) my_status_icon_instance_init, NULL }; + GType my_status_icon_type_id; + my_status_icon_type_id = g_type_register_static (GTK_TYPE_STATUS_ICON, "MyStatusIcon", &g_define_type_info, 0); + g_once_init_leave (&my_status_icon_type_id__volatile, my_status_icon_type_id); + } + return my_status_icon_type_id__volatile; +} + + +void show_error (const gchar* e) { + const gchar* _tmp0_; + GtkMessageDialog* _tmp1_; + GtkMessageDialog* _tmp2_; + GtkMessageDialog* m; +#line 247 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_return_if_fail (e != NULL); +#line 248 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp0_ = e; +#line 248 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp1_ = (GtkMessageDialog*) gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", _tmp0_); +#line 248 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp2_ = g_object_ref_sink (_tmp1_); +#line 248 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + m = _tmp2_; +#line 249 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_dialog_run ((GtkDialog*) m); +#line 250 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_object_destroy ((GtkObject*) m); +#line 247 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (m); +#line 1410 "gnome-ask-password-agent.c" +} + + +gint _vala_main (gchar** args, int args_length1) { + gint result = 0; + GError * _inner_error_ = NULL; + { + MyStatusIcon* _tmp0_; + MyStatusIcon* i; +#line 255 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_init_with_args (&args_length1, &args, "[OPTION...]", entries, "systemd-ask-password-agent", &_inner_error_); +#line 255 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 1424 "gnome-ask-password-agent.c" + goto __catch5_g_error; + } +#line 256 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + notify_init ("Password Agent"); +#line 258 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp0_ = my_status_icon_new (&_inner_error_); +#line 258 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + i = _tmp0_; +#line 258 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 1435 "gnome-ask-password-agent.c" + goto __catch5_g_error; + } +#line 259 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + gtk_main (); +#line 254 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_object_unref0 (i); +#line 1442 "gnome-ask-password-agent.c" + } + goto __finally5; + __catch5_g_error: + { + GError* e = NULL; + GError* _tmp1_; + const gchar* _tmp2_; +#line 254 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + e = _inner_error_; +#line 254 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _inner_error_ = NULL; +#line 262 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp1_ = e; +#line 262 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _tmp2_ = _tmp1_->message; +#line 262 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + show_error (_tmp2_); +#line 254 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + _g_error_free0 (e); +#line 1462 "gnome-ask-password-agent.c" + } + __finally5: +#line 254 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + if (_inner_error_ != NULL) { +#line 254 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 254 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_clear_error (&_inner_error_); +#line 254 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return 0; +#line 1473 "gnome-ask-password-agent.c" + } +#line 265 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + result = 0; +#line 265 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return result; +#line 1479 "gnome-ask-password-agent.c" +} + + +int main (int argc, char ** argv) { +#line 253 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + g_type_init (); +#line 253 "/home/lennart/projects/systemd/src/gnome-ask-password-agent.vala" + return _vala_main (argv, argc); +#line 1488 "gnome-ask-password-agent.c" +} + + +static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) { + if ((array != NULL) && (destroy_func != NULL)) { + int i; + for (i = 0; i < array_length; i = i + 1) { + if (((gpointer*) array)[i] != NULL) { + destroy_func (((gpointer*) array)[i]); + } + } + } +} + + +static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) { + _vala_array_destroy (array, array_length, destroy_func); + g_free (array); +} + + + diff --git a/src/gnome-ask-password-agent.vala b/src/gnome-ask-password-agent.vala new file mode 100644 index 0000000..e23aedb --- /dev/null +++ b/src/gnome-ask-password-agent.vala @@ -0,0 +1,266 @@ +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +using Gtk; +using GLib; +using Linux; +using Posix; +using Notify; + +[CCode (cheader_filename = "time.h")] +extern int clock_gettime(int id, out timespec ts); + +public class PasswordDialog : Dialog { + + public Entry entry; + + public PasswordDialog(string message, string icon) { + set_title("System Password"); + set_has_separator(false); + set_border_width(8); + set_default_response(ResponseType.OK); + set_icon_name(icon); + + add_button(Stock.CANCEL, ResponseType.CANCEL); + add_button(Stock.OK, ResponseType.OK); + + Container content = (Container) get_content_area(); + + Box hbox = new HBox(false, 16); + hbox.set_border_width(8); + content.add(hbox); + + Image image = new Image.from_icon_name(icon, IconSize.DIALOG); + hbox.pack_start(image, false, false); + + Box vbox = new VBox(false, 8); + hbox.pack_start(vbox, true, true); + + Label label = new Label(message); + vbox.pack_start(label, false, false); + + entry = new Entry(); + entry.set_visibility(false); + entry.set_activates_default(true); + vbox.pack_start(entry, false, false); + + entry.activate.connect(on_entry_activated); + + show_all(); + } + + public void on_entry_activated() { + response(ResponseType.OK); + } +} + +public class MyStatusIcon : StatusIcon { + + File directory; + File current; + FileMonitor file_monitor; + + string message; + string icon; + string socket; + + PasswordDialog password_dialog; + + public MyStatusIcon() throws GLib.Error { + GLib.Object(icon_name : "dialog-password"); + set_title("System Password Request"); + + directory = File.new_for_path("/run/systemd/ask-password/"); + file_monitor = directory.monitor_directory(0); + file_monitor.changed.connect(file_monitor_changed); + + current = null; + look_for_password(); + + activate.connect(status_icon_activate); + } + + void file_monitor_changed(GLib.File file, GLib.File? other_file, GLib.FileMonitorEvent event_type) { + + if (!file.get_basename().has_prefix("ask.")) + return; + + if (event_type == FileMonitorEvent.CREATED || + event_type == FileMonitorEvent.DELETED) { + try { + look_for_password(); + } catch (Error e) { + show_error(e.message); + } + } + } + + void look_for_password() throws GLib.Error { + + if (current != null) { + if (!current.query_exists()) { + current = null; + if (password_dialog != null) + password_dialog.response(ResponseType.REJECT); + } + } + + if (current == null) { + FileEnumerator enumerator = directory.enumerate_children("standard::name", FileQueryInfoFlags.NOFOLLOW_SYMLINKS); + + FileInfo i; + while ((i = enumerator.next_file()) != null) { + if (!i.get_name().has_prefix("ask.")) + continue; + + current = directory.get_child(i.get_name()); + + if (load_password()) + break; + + current = null; + } + } + + if (current == null) + set_visible(false); + } + + bool load_password() throws GLib.Error { + + KeyFile key_file = new KeyFile(); + + try { + timespec ts; + + key_file.load_from_file(current.get_path(), KeyFileFlags.NONE); + + string not_after_as_string = key_file.get_string("Ask", "NotAfter"); + + clock_gettime(1, out ts); + uint64 now = (ts.tv_sec * 1000000) + (ts.tv_nsec / 1000); + + uint64 not_after; + if (not_after_as_string.scanf("%llu", out not_after) != 1) + return false; + + if (not_after > 0 && not_after < now) + return false; + + socket = key_file.get_string("Ask", "Socket"); + } catch (GLib.Error e) { + return false; + } + + try { + message = key_file.get_string("Ask", "Message").compress(); + } catch (GLib.Error e) { + message = "Please Enter System Password!"; + } + + set_tooltip_text(message); + + try { + icon = key_file.get_string("Ask", "Icon"); + } catch (GLib.Error e) { + icon = "dialog-password"; + } + set_from_icon_name(icon); + + set_visible(true); + + Notification n = new Notification(title, message, icon); + n.set_timeout(5000); + n.show(); + + return true; + } + + void status_icon_activate() { + + if (current == null) + return; + + if (password_dialog != null) { + password_dialog.present(); + return; + } + + password_dialog = new PasswordDialog(message, icon); + + int result = password_dialog.run(); + string password = password_dialog.entry.get_text(); + + password_dialog.destroy(); + password_dialog = null; + + if (result == ResponseType.REJECT || + result == ResponseType.DELETE_EVENT) + return; + + int to_process; + + try { + Process.spawn_async_with_pipes( + null, + { "/usr/bin/pkexec", "/lib/systemd/systemd-reply-password", result == ResponseType.OK ? "1" : "0", socket }, + null, + 0, + null, + null, + out to_process, + null, + null); + + OutputStream stream = new UnixOutputStream(to_process, true); +#if VALA_0_12 + stream.write(password.data, null); +#else + stream.write(password, password.length, null); +#endif + } catch (Error e) { + show_error(e.message); + } + } +} + +static const OptionEntry entries[] = { + { null } +}; + +void show_error(string e) { + var m = new MessageDialog(null, 0, MessageType.ERROR, ButtonsType.CLOSE, "%s", e); + m.run(); + m.destroy(); +} + +int main(string[] args) { + try { + Gtk.init_with_args(ref args, "[OPTION...]", entries, "systemd-ask-password-agent"); + Notify.init("Password Agent"); + + MyStatusIcon i = new MyStatusIcon(); + Gtk.main(); + + } catch (GLib.Error e) { + show_error(e.message); + } + + return 0; +} diff --git a/src/hashmap.c b/src/hashmap.c new file mode 100644 index 0000000..7ef8097 --- /dev/null +++ b/src/hashmap.c @@ -0,0 +1,731 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "hashmap.h" +#include "macro.h" + +#define NBUCKETS 127 + +struct hashmap_entry { + const void *key; + void *value; + struct hashmap_entry *bucket_next, *bucket_previous; + struct hashmap_entry *iterate_next, *iterate_previous; +}; + +struct Hashmap { + hash_func_t hash_func; + compare_func_t compare_func; + + struct hashmap_entry *iterate_list_head, *iterate_list_tail; + unsigned n_entries; + + bool from_pool; +}; + +#define BY_HASH(h) ((struct hashmap_entry**) ((uint8_t*) (h) + ALIGN(sizeof(Hashmap)))) + +struct pool { + struct pool *next; + unsigned n_tiles; + unsigned n_used; +}; + +struct pool *first_hashmap_pool = NULL; +static void *first_hashmap_tile = NULL; + +struct pool *first_entry_pool = NULL; +static void *first_entry_tile = NULL; + +static void* allocate_tile(struct pool **first_pool, void **first_tile, size_t tile_size) { + unsigned i; + + if (*first_tile) { + void *r; + + r = *first_tile; + *first_tile = * (void**) (*first_tile); + return r; + } + + if (_unlikely_(!*first_pool) || _unlikely_((*first_pool)->n_used >= (*first_pool)->n_tiles)) { + unsigned n; + size_t size; + struct pool *p; + + n = *first_pool ? (*first_pool)->n_tiles : 0; + n = MAX(512U, n * 2); + size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*tile_size); + n = (size - ALIGN(sizeof(struct pool))) / tile_size; + + p = malloc(size); + if (!p) + return NULL; + + p->next = *first_pool; + p->n_tiles = n; + p->n_used = 0; + + *first_pool = p; + } + + i = (*first_pool)->n_used++; + + return ((uint8_t*) (*first_pool)) + ALIGN(sizeof(struct pool)) + i*tile_size; +} + +static void deallocate_tile(void **first_tile, void *p) { + * (void**) p = *first_tile; + *first_tile = p; +} + +#ifndef __OPTIMIZE__ + +static void drop_pool(struct pool *p) { + while (p) { + struct pool *n; + n = p->next; + free(p); + p = n; + } +} + +__attribute__((destructor)) static void cleanup_pool(void) { + /* Be nice to valgrind */ + + drop_pool(first_hashmap_pool); + drop_pool(first_entry_pool); +} + +#endif + +unsigned string_hash_func(const void *p) { + unsigned hash = 5381; + const signed char *c; + + /* DJB's hash function */ + + for (c = p; *c; c++) + hash = (hash << 5) + hash + (unsigned) *c; + + return hash; +} + +int string_compare_func(const void *a, const void *b) { + return strcmp(a, b); +} + +unsigned trivial_hash_func(const void *p) { + return PTR_TO_UINT(p); +} + +int trivial_compare_func(const void *a, const void *b) { + return a < b ? -1 : (a > b ? 1 : 0); +} + +Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func) { + bool b; + Hashmap *h; + size_t size; + + b = is_main_thread(); + + size = ALIGN(sizeof(Hashmap)) + NBUCKETS * sizeof(struct hashmap_entry*); + + if (b) { + h = allocate_tile(&first_hashmap_pool, &first_hashmap_tile, size); + if (!h) + return NULL; + + memset(h, 0, size); + } else { + h = malloc0(size); + + if (!h) + return NULL; + } + + h->hash_func = hash_func ? hash_func : trivial_hash_func; + h->compare_func = compare_func ? compare_func : trivial_compare_func; + + h->n_entries = 0; + h->iterate_list_head = h->iterate_list_tail = NULL; + + h->from_pool = b; + + return h; +} + +int hashmap_ensure_allocated(Hashmap **h, hash_func_t hash_func, compare_func_t compare_func) { + assert(h); + + if (*h) + return 0; + + if (!(*h = hashmap_new(hash_func, compare_func))) + return -ENOMEM; + + return 0; +} + +static void link_entry(Hashmap *h, struct hashmap_entry *e, unsigned hash) { + assert(h); + assert(e); + + /* Insert into hash table */ + e->bucket_next = BY_HASH(h)[hash]; + e->bucket_previous = NULL; + if (BY_HASH(h)[hash]) + BY_HASH(h)[hash]->bucket_previous = e; + BY_HASH(h)[hash] = e; + + /* Insert into iteration list */ + e->iterate_previous = h->iterate_list_tail; + e->iterate_next = NULL; + if (h->iterate_list_tail) { + assert(h->iterate_list_head); + h->iterate_list_tail->iterate_next = e; + } else { + assert(!h->iterate_list_head); + h->iterate_list_head = e; + } + h->iterate_list_tail = e; + + h->n_entries++; + assert(h->n_entries >= 1); +} + +static void unlink_entry(Hashmap *h, struct hashmap_entry *e, unsigned hash) { + assert(h); + assert(e); + + /* Remove from iteration list */ + if (e->iterate_next) + e->iterate_next->iterate_previous = e->iterate_previous; + else + h->iterate_list_tail = e->iterate_previous; + + if (e->iterate_previous) + e->iterate_previous->iterate_next = e->iterate_next; + else + h->iterate_list_head = e->iterate_next; + + /* Remove from hash table bucket list */ + if (e->bucket_next) + e->bucket_next->bucket_previous = e->bucket_previous; + + if (e->bucket_previous) + e->bucket_previous->bucket_next = e->bucket_next; + else + BY_HASH(h)[hash] = e->bucket_next; + + assert(h->n_entries >= 1); + h->n_entries--; +} + +static void remove_entry(Hashmap *h, struct hashmap_entry *e) { + unsigned hash; + + assert(h); + assert(e); + + hash = h->hash_func(e->key) % NBUCKETS; + + unlink_entry(h, e, hash); + + if (h->from_pool) + deallocate_tile(&first_entry_tile, e); + else + free(e); +} + +void hashmap_free(Hashmap*h) { + + if (!h) + return; + + hashmap_clear(h); + + if (h->from_pool) + deallocate_tile(&first_hashmap_tile, h); + else + free(h); +} + +void hashmap_free_free(Hashmap *h) { + void *p; + + while ((p = hashmap_steal_first(h))) + free(p); + + hashmap_free(h); +} + +void hashmap_clear(Hashmap *h) { + if (!h) + return; + + while (h->iterate_list_head) + remove_entry(h, h->iterate_list_head); +} + +static struct hashmap_entry *hash_scan(Hashmap *h, unsigned hash, const void *key) { + struct hashmap_entry *e; + assert(h); + assert(hash < NBUCKETS); + + for (e = BY_HASH(h)[hash]; e; e = e->bucket_next) + if (h->compare_func(e->key, key) == 0) + return e; + + return NULL; +} + +int hashmap_put(Hashmap *h, const void *key, void *value) { + struct hashmap_entry *e; + unsigned hash; + + assert(h); + + hash = h->hash_func(key) % NBUCKETS; + + if ((e = hash_scan(h, hash, key))) { + + if (e->value == value) + return 0; + + return -EEXIST; + } + + if (h->from_pool) + e = allocate_tile(&first_entry_pool, &first_entry_tile, sizeof(struct hashmap_entry)); + else + e = new(struct hashmap_entry, 1); + + if (!e) + return -ENOMEM; + + e->key = key; + e->value = value; + + link_entry(h, e, hash); + + return 1; +} + +int hashmap_replace(Hashmap *h, const void *key, void *value) { + struct hashmap_entry *e; + unsigned hash; + + assert(h); + + hash = h->hash_func(key) % NBUCKETS; + + if ((e = hash_scan(h, hash, key))) { + e->key = key; + e->value = value; + return 0; + } + + return hashmap_put(h, key, value); +} + +void* hashmap_get(Hashmap *h, const void *key) { + unsigned hash; + struct hashmap_entry *e; + + if (!h) + return NULL; + + hash = h->hash_func(key) % NBUCKETS; + + if (!(e = hash_scan(h, hash, key))) + return NULL; + + return e->value; +} + +void* hashmap_remove(Hashmap *h, const void *key) { + struct hashmap_entry *e; + unsigned hash; + void *data; + + if (!h) + return NULL; + + hash = h->hash_func(key) % NBUCKETS; + + if (!(e = hash_scan(h, hash, key))) + return NULL; + + data = e->value; + remove_entry(h, e); + + return data; +} + +int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value) { + struct hashmap_entry *e; + unsigned old_hash, new_hash; + + if (!h) + return -ENOENT; + + old_hash = h->hash_func(old_key) % NBUCKETS; + if (!(e = hash_scan(h, old_hash, old_key))) + return -ENOENT; + + new_hash = h->hash_func(new_key) % NBUCKETS; + if (hash_scan(h, new_hash, new_key)) + return -EEXIST; + + unlink_entry(h, e, old_hash); + + e->key = new_key; + e->value = value; + + link_entry(h, e, new_hash); + + return 0; +} + +int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value) { + struct hashmap_entry *e, *k; + unsigned old_hash, new_hash; + + if (!h) + return -ENOENT; + + old_hash = h->hash_func(old_key) % NBUCKETS; + if (!(e = hash_scan(h, old_hash, old_key))) + return -ENOENT; + + new_hash = h->hash_func(new_key) % NBUCKETS; + + if ((k = hash_scan(h, new_hash, new_key))) + if (e != k) + remove_entry(h, k); + + unlink_entry(h, e, old_hash); + + e->key = new_key; + e->value = value; + + link_entry(h, e, new_hash); + + return 0; +} + +void* hashmap_remove_value(Hashmap *h, const void *key, void *value) { + struct hashmap_entry *e; + unsigned hash; + + if (!h) + return NULL; + + hash = h->hash_func(key) % NBUCKETS; + + if (!(e = hash_scan(h, hash, key))) + return NULL; + + if (e->value != value) + return NULL; + + remove_entry(h, e); + + return value; +} + +void *hashmap_iterate(Hashmap *h, Iterator *i, const void **key) { + struct hashmap_entry *e; + + assert(i); + + if (!h) + goto at_end; + + if (*i == ITERATOR_LAST) + goto at_end; + + if (*i == ITERATOR_FIRST && !h->iterate_list_head) + goto at_end; + + e = *i == ITERATOR_FIRST ? h->iterate_list_head : (struct hashmap_entry*) *i; + + if (e->iterate_next) + *i = (Iterator) e->iterate_next; + else + *i = ITERATOR_LAST; + + if (key) + *key = e->key; + + return e->value; + +at_end: + *i = ITERATOR_LAST; + + if (key) + *key = NULL; + + return NULL; +} + +void *hashmap_iterate_backwards(Hashmap *h, Iterator *i, const void **key) { + struct hashmap_entry *e; + + assert(i); + + if (!h) + goto at_beginning; + + if (*i == ITERATOR_FIRST) + goto at_beginning; + + if (*i == ITERATOR_LAST && !h->iterate_list_tail) + goto at_beginning; + + e = *i == ITERATOR_LAST ? h->iterate_list_tail : (struct hashmap_entry*) *i; + + if (e->iterate_previous) + *i = (Iterator) e->iterate_previous; + else + *i = ITERATOR_FIRST; + + if (key) + *key = e->key; + + return e->value; + +at_beginning: + *i = ITERATOR_FIRST; + + if (key) + *key = NULL; + + return NULL; +} + +void *hashmap_iterate_skip(Hashmap *h, const void *key, Iterator *i) { + unsigned hash; + struct hashmap_entry *e; + + if (!h) + return NULL; + + hash = h->hash_func(key) % NBUCKETS; + + if (!(e = hash_scan(h, hash, key))) + return NULL; + + *i = (Iterator) e; + + return e->value; +} + +void* hashmap_first(Hashmap *h) { + + if (!h) + return NULL; + + if (!h->iterate_list_head) + return NULL; + + return h->iterate_list_head->value; +} + +void* hashmap_first_key(Hashmap *h) { + + if (!h) + return NULL; + + if (!h->iterate_list_head) + return NULL; + + return (void*) h->iterate_list_head->key; +} + +void* hashmap_last(Hashmap *h) { + + if (!h) + return NULL; + + if (!h->iterate_list_tail) + return NULL; + + return h->iterate_list_tail->value; +} + +void* hashmap_steal_first(Hashmap *h) { + void *data; + + if (!h) + return NULL; + + if (!h->iterate_list_head) + return NULL; + + data = h->iterate_list_head->value; + remove_entry(h, h->iterate_list_head); + + return data; +} + +void* hashmap_steal_first_key(Hashmap *h) { + void *key; + + if (!h) + return NULL; + + if (!h->iterate_list_head) + return NULL; + + key = (void*) h->iterate_list_head->key; + remove_entry(h, h->iterate_list_head); + + return key; +} + +unsigned hashmap_size(Hashmap *h) { + + if (!h) + return 0; + + return h->n_entries; +} + +bool hashmap_isempty(Hashmap *h) { + + if (!h) + return true; + + return h->n_entries == 0; +} + +int hashmap_merge(Hashmap *h, Hashmap *other) { + struct hashmap_entry *e; + + assert(h); + + if (!other) + return 0; + + for (e = other->iterate_list_head; e; e = e->iterate_next) { + int r; + + if ((r = hashmap_put(h, e->key, e->value)) < 0) + if (r != -EEXIST) + return r; + } + + return 0; +} + +void hashmap_move(Hashmap *h, Hashmap *other) { + struct hashmap_entry *e, *n; + + assert(h); + + /* The same as hashmap_merge(), but every new item from other + * is moved to h. This function is guaranteed to succeed. */ + + if (!other) + return; + + for (e = other->iterate_list_head; e; e = n) { + unsigned h_hash, other_hash; + + n = e->iterate_next; + + h_hash = h->hash_func(e->key) % NBUCKETS; + + if (hash_scan(h, h_hash, e->key)) + continue; + + other_hash = other->hash_func(e->key) % NBUCKETS; + + unlink_entry(other, e, other_hash); + link_entry(h, e, h_hash); + } +} + +int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) { + unsigned h_hash, other_hash; + struct hashmap_entry *e; + + if (!other) + return 0; + + assert(h); + + h_hash = h->hash_func(key) % NBUCKETS; + if (hash_scan(h, h_hash, key)) + return -EEXIST; + + other_hash = other->hash_func(key) % NBUCKETS; + if (!(e = hash_scan(other, other_hash, key))) + return -ENOENT; + + unlink_entry(other, e, other_hash); + link_entry(h, e, h_hash); + + return 0; +} + +Hashmap *hashmap_copy(Hashmap *h) { + Hashmap *copy; + + assert(h); + + if (!(copy = hashmap_new(h->hash_func, h->compare_func))) + return NULL; + + if (hashmap_merge(copy, h) < 0) { + hashmap_free(copy); + return NULL; + } + + return copy; +} + +char **hashmap_get_strv(Hashmap *h) { + char **sv; + Iterator it; + char *item; + int n; + + sv = new(char*, h->n_entries+1); + if (!sv) + return NULL; + + n = 0; + HASHMAP_FOREACH(item, h, it) + sv[n++] = item; + sv[n] = NULL; + + return sv; +} diff --git a/src/hashmap.h b/src/hashmap.h new file mode 100644 index 0000000..ab4363a --- /dev/null +++ b/src/hashmap.h @@ -0,0 +1,91 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foohashmaphfoo +#define foohashmaphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +/* Pretty straightforward hash table implementation. As a minor + * optimization a NULL hashmap object will be treated as empty hashmap + * for all read operations. That way it is not necessary to + * instantiate an object for each Hashmap use. */ + +typedef struct Hashmap Hashmap; +typedef struct _IteratorStruct _IteratorStruct; +typedef _IteratorStruct* Iterator; + +#define ITERATOR_FIRST ((Iterator) 0) +#define ITERATOR_LAST ((Iterator) -1) + +typedef unsigned (*hash_func_t)(const void *p); +typedef int (*compare_func_t)(const void *a, const void *b); + +unsigned string_hash_func(const void *p); +int string_compare_func(const void *a, const void *b); + +unsigned trivial_hash_func(const void *p); +int trivial_compare_func(const void *a, const void *b); + +Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func); +void hashmap_free(Hashmap *h); +void hashmap_free_free(Hashmap *h); +Hashmap *hashmap_copy(Hashmap *h); +int hashmap_ensure_allocated(Hashmap **h, hash_func_t hash_func, compare_func_t compare_func); + +int hashmap_put(Hashmap *h, const void *key, void *value); +int hashmap_replace(Hashmap *h, const void *key, void *value); +void* hashmap_get(Hashmap *h, const void *key); +void* hashmap_remove(Hashmap *h, const void *key); +void* hashmap_remove_value(Hashmap *h, const void *key, void *value); +int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value); +int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value); + +int hashmap_merge(Hashmap *h, Hashmap *other); +void hashmap_move(Hashmap *h, Hashmap *other); +int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key); + +unsigned hashmap_size(Hashmap *h); +bool hashmap_isempty(Hashmap *h); + +void *hashmap_iterate(Hashmap *h, Iterator *i, const void **key); +void *hashmap_iterate_backwards(Hashmap *h, Iterator *i, const void **key); +void *hashmap_iterate_skip(Hashmap *h, const void *key, Iterator *i); + +void hashmap_clear(Hashmap *h); +void *hashmap_steal_first(Hashmap *h); +void *hashmap_steal_first_key(Hashmap *h); +void* hashmap_first(Hashmap *h); +void* hashmap_first_key(Hashmap *h); +void* hashmap_last(Hashmap *h); + +char **hashmap_get_strv(Hashmap *h); + +#define HASHMAP_FOREACH(e, h, i) \ + for ((i) = ITERATOR_FIRST, (e) = hashmap_iterate((h), &(i), NULL); (e); (e) = hashmap_iterate((h), &(i), NULL)) + +#define HASHMAP_FOREACH_KEY(e, k, h, i) \ + for ((i) = ITERATOR_FIRST, (e) = hashmap_iterate((h), &(i), (const void**) &(k)); (e); (e) = hashmap_iterate((h), &(i), (const void**) &(k))) + +#define HASHMAP_FOREACH_BACKWARDS(e, h, i) \ + for ((i) = ITERATOR_LAST, (e) = hashmap_iterate_backwards((h), &(i), NULL); (e); (e) = hashmap_iterate_backwards((h), &(i), NULL)) + +#endif diff --git a/src/hostname-setup.c b/src/hostname-setup.c new file mode 100644 index 0000000..2c2f10c --- /dev/null +++ b/src/hostname-setup.c @@ -0,0 +1,187 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "hostname-setup.h" +#include "macro.h" +#include "util.h" +#include "log.h" + +#if defined(TARGET_FEDORA) || defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MEEGO) || defined(TARGET_MAGEIA) +#define FILENAME "/etc/sysconfig/network" +#elif defined(TARGET_SUSE) || defined(TARGET_SLACKWARE) +#define FILENAME "/etc/HOSTNAME" +#elif defined(TARGET_ARCH) +#define FILENAME "/etc/rc.conf" +#elif defined(TARGET_GENTOO) +#define FILENAME "/etc/conf.d/hostname" +#endif + +static int read_and_strip_hostname(const char *path, char **hn) { + char *s; + int r; + + assert(path); + assert(hn); + + if ((r = read_one_line_file(path, &s)) < 0) + return r; + + hostname_cleanup(s); + + if (isempty(s)) { + free(s); + return -ENOENT; + } + + *hn = s; + + return 0; +} + +static int read_distro_hostname(char **hn) { + +#if defined(TARGET_FEDORA) || defined(TARGET_ARCH) || defined(TARGET_GENTOO) || defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MEEGO) || defined(TARGET_MAGEIA) + int r; + FILE *f; + + assert(hn); + + if (!(f = fopen(FILENAME, "re"))) + return -errno; + + for (;;) { + char line[LINE_MAX]; + char *s, *k; + + if (!fgets(line, sizeof(line), f)) { + if (feof(f)) + break; + + r = -errno; + goto finish; + } + + s = strstrip(line); + + if (!startswith_no_case(s, "HOSTNAME=")) + continue; + + if (!(k = strdup(s+9))) { + r = -ENOMEM; + goto finish; + } + + hostname_cleanup(k); + + if (isempty(k)) { + free(k); + r = -ENOENT; + goto finish; + } + + *hn = k; + r = 0; + goto finish; + } + + r = -ENOENT; + +finish: + fclose(f); + return r; + +#elif defined(TARGET_SUSE) || defined(TARGET_SLACKWARE) + return read_and_strip_hostname(FILENAME, hn); +#else + return -ENOENT; +#endif +} + +static int read_hostname(char **hn) { + int r; + + assert(hn); + + /* First, try to load the generic hostname configuration file, + * that we support on all distributions */ + + if ((r = read_and_strip_hostname("/etc/hostname", hn)) < 0) { + + if (r == -ENOENT) + return read_distro_hostname(hn); + + return r; + } + + return 0; +} + +int hostname_setup(void) { + int r; + char *b = NULL; + const char *hn = NULL; + + if ((r = read_hostname(&b)) < 0) { + if (r == -ENOENT) + log_info("No hostname configured."); + else + log_warning("Failed to read configured hostname: %s", strerror(-r)); + + hn = NULL; + } else + hn = b; + + if (!hn) { + /* Don't override the hostname if it is unset and not + * explicitly configured */ + + char *old_hostname = NULL; + + if ((old_hostname = gethostname_malloc())) { + bool already_set; + + already_set = old_hostname[0] != 0; + free(old_hostname); + + if (already_set) + goto finish; + } + + hn = "localhost"; + } + + if (sethostname(hn, strlen(hn)) < 0) { + log_warning("Failed to set hostname to <%s>: %m", hn); + r = -errno; + } else + log_info("Set hostname to <%s>.", hn); + +finish: + free(b); + + return r; +} diff --git a/src/hostname-setup.h b/src/hostname-setup.h new file mode 100644 index 0000000..ff11df9 --- /dev/null +++ b/src/hostname-setup.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foohostnamesetuphfoo +#define foohostnamesetuphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +int hostname_setup(void); + +#endif diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c new file mode 100644 index 0000000..ad72440 --- /dev/null +++ b/src/hostname/hostnamed.c @@ -0,0 +1,629 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include +#include +#include +#include + +#include "util.h" +#include "strv.h" +#include "dbus-common.h" +#include "polkit.h" +#include "def.h" +#include "virt.h" + +#define INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + BUS_PEER_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.hostname1\0" + +const char hostname_interface[] _introspect_("hostname1") = INTERFACE; + +enum { + PROP_HOSTNAME, + PROP_STATIC_HOSTNAME, + PROP_PRETTY_HOSTNAME, + PROP_ICON_NAME, + _PROP_MAX +}; + +static char *data[_PROP_MAX] = { + NULL, + NULL, + NULL, + NULL +}; + +static usec_t remain_until = 0; + +static void free_data(void) { + int p; + + for (p = 0; p < _PROP_MAX; p++) { + free(data[p]); + data[p] = NULL; + } +} + +static int read_data(void) { + int r; + + free_data(); + + data[PROP_HOSTNAME] = gethostname_malloc(); + if (!data[PROP_HOSTNAME]) + return -ENOMEM; + + r = read_one_line_file("/etc/hostname", &data[PROP_STATIC_HOSTNAME]); + if (r < 0 && r != -ENOENT) + return r; + + r = parse_env_file("/etc/machine-info", NEWLINE, + "PRETTY_HOSTNAME", &data[PROP_PRETTY_HOSTNAME], + "ICON_NAME", &data[PROP_ICON_NAME], + NULL); + if (r < 0 && r != -ENOENT) + return r; + + return 0; +} + +static bool check_nss(void) { + + void *dl; + + if ((dl = dlopen("libnss_myhostname.so.2", RTLD_LAZY))) { + dlclose(dl); + return true; + } + + return false; +} + +static const char* fallback_icon_name(void) { + +#if defined(__i386__) || defined(__x86_64__) + int r; + char *type; + unsigned t; +#endif + + if (detect_virtualization(NULL) > 0) + return "computer-vm"; + +#if defined(__i386__) || defined(__x86_64__) + r = read_one_line_file("/sys/class/dmi/id/chassis_type", &type); + if (r < 0) + return NULL; + + r = safe_atou(type, &t); + free(type); + + if (r < 0) + return NULL; + + /* We only list the really obvious cases here. The DMI data is + unreliable enough, so let's not do any additional guesswork + on top of that. + + See the SMBIOS Specification 2.7.1 section 7.4.1 for + details about the values listed here: + + http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf + */ + + switch (t) { + + case 0x3: + case 0x4: + case 0x6: + case 0x7: + return "computer-desktop"; + + case 0x9: + case 0xA: + case 0xE: + return "computer-laptop"; + + case 0x11: + case 0x1C: + return "computer-server"; + } + +#endif + return NULL; +} + +static int write_data_hostname(void) { + const char *hn; + + if (isempty(data[PROP_HOSTNAME])) + hn = "localhost"; + else + hn = data[PROP_HOSTNAME]; + + if (sethostname(hn, strlen(hn)) < 0) + return -errno; + + return 0; +} + +static int write_data_static_hostname(void) { + + if (isempty(data[PROP_STATIC_HOSTNAME])) { + + if (unlink("/etc/hostname") < 0) + return errno == ENOENT ? 0 : -errno; + + return 0; + } + + return write_one_line_file_atomic("/etc/hostname", data[PROP_STATIC_HOSTNAME]); +} + +static int write_data_other(void) { + + static const char * const name[_PROP_MAX] = { + [PROP_PRETTY_HOSTNAME] = "PRETTY_HOSTNAME", + [PROP_ICON_NAME] = "ICON_NAME" + }; + + char **l = NULL; + int r, p; + + r = load_env_file("/etc/machine-info", &l); + if (r < 0 && r != -ENOENT) + return r; + + for (p = 2; p < _PROP_MAX; p++) { + char *t, **u; + + assert(name[p]); + + if (isempty(data[p])) { + strv_env_unset(l, name[p]); + continue; + } + + if (asprintf(&t, "%s=%s", name[p], strempty(data[p])) < 0) { + strv_free(l); + return -ENOMEM; + } + + u = strv_env_set(l, t); + free(t); + strv_free(l); + + if (!u) + return -ENOMEM; + l = u; + } + + if (strv_isempty(l)) { + + if (unlink("/etc/machine-info") < 0) + return errno == ENOENT ? 0 : -errno; + + return 0; + } + + r = write_env_file("/etc/machine-info", l); + strv_free(l); + + return r; +} + +static int bus_hostname_append_icon_name(DBusMessageIter *i, const char *property, void *userdata) { + const char *name; + + assert(i); + assert(property); + + if (isempty(data[PROP_ICON_NAME])) + name = fallback_icon_name(); + else + name = data[PROP_ICON_NAME]; + + return bus_property_append_string(i, property, (void*) name); +} + +static const BusProperty bus_hostname_properties[] = { + { "Hostname", bus_property_append_string, "s", sizeof(data[0])*PROP_HOSTNAME, true }, + { "StaticHostname", bus_property_append_string, "s", sizeof(data[0])*PROP_STATIC_HOSTNAME, true }, + { "PrettyHostname", bus_property_append_string, "s", sizeof(data[0])*PROP_PRETTY_HOSTNAME, true }, + { "IconName", bus_hostname_append_icon_name, "s", sizeof(data[0])*PROP_ICON_NAME, true }, + { NULL, } +}; + +static const BusBoundProperties bps[] = { + { "org.freedesktop.hostname1", bus_hostname_properties, data }, + { NULL, } +}; + +static DBusHandlerResult hostname_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + + DBusMessage *reply = NULL, *changed = NULL; + DBusError error; + int r; + + assert(connection); + assert(message); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetHostname")) { + const char *name; + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(name)) + name = data[PROP_STATIC_HOSTNAME]; + + if (isempty(name)) + name = "localhost"; + + if (!hostname_is_valid(name)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + if (!streq_ptr(name, data[PROP_HOSTNAME])) { + char *h; + + r = verify_polkit(connection, message, "org.freedesktop.hostname1.set-hostname", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + h = strdup(name); + if (!h) + goto oom; + + free(data[PROP_HOSTNAME]); + data[PROP_HOSTNAME] = h; + + r = write_data_hostname(); + if (r < 0) { + log_error("Failed to set host name: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + log_info("Changed host name to '%s'", strempty(data[PROP_HOSTNAME])); + + changed = bus_properties_changed_new( + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + "Hostname\0"); + if (!changed) + goto oom; + } + + } else if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetStaticHostname")) { + const char *name; + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(name)) + name = NULL; + + if (!streq_ptr(name, data[PROP_STATIC_HOSTNAME])) { + + r = verify_polkit(connection, message, "org.freedesktop.hostname1.set-static-hostname", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (isempty(name)) { + free(data[PROP_STATIC_HOSTNAME]); + data[PROP_STATIC_HOSTNAME] = NULL; + } else { + char *h; + + if (!hostname_is_valid(name)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + h = strdup(name); + if (!h) + goto oom; + + free(data[PROP_STATIC_HOSTNAME]); + data[PROP_STATIC_HOSTNAME] = h; + } + + r = write_data_static_hostname(); + if (r < 0) { + log_error("Failed to write static host name: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + log_info("Changed static host name to '%s'", strempty(data[PROP_STATIC_HOSTNAME])); + + changed = bus_properties_changed_new( + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + "StaticHostname\0"); + if (!changed) + goto oom; + } + + } else if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetPrettyHostname") || + dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetIconName")) { + + const char *name; + dbus_bool_t interactive; + int k; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(name)) + name = NULL; + + k = streq(dbus_message_get_member(message), "SetPrettyHostname") ? PROP_PRETTY_HOSTNAME : PROP_ICON_NAME; + + if (!streq_ptr(name, data[k])) { + + /* Since the pretty hostname should always be + * changed at the same time as the static one, + * use the same policy action for both... */ + + r = verify_polkit(connection, message, k == PROP_PRETTY_HOSTNAME ? + "org.freedesktop.hostname1.set-static-hostname" : + "org.freedesktop.hostname1.set-machine-info", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (isempty(name)) { + free(data[k]); + data[k] = NULL; + } else { + char *h; + + h = strdup(name); + if (!h) + goto oom; + + free(data[k]); + data[k] = h; + } + + r = write_data_other(); + if (r < 0) { + log_error("Failed to write machine info: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + log_info("Changed %s to '%s'", k == PROP_PRETTY_HOSTNAME ? "pretty host name" : "icon name", strempty(data[k])); + + changed = bus_properties_changed_new( + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + k == PROP_PRETTY_HOSTNAME ? "PrettyHostname\0" : "IconName\0"); + if (!changed) + goto oom; + } + + } else + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + reply = NULL; + + if (changed) { + + if (!dbus_connection_send(connection, changed, NULL)) + goto oom; + + dbus_message_unref(changed); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + if (changed) + dbus_message_unref(changed); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static int connect_bus(DBusConnection **_bus) { + static const DBusObjectPathVTable hostname_vtable = { + .message_function = hostname_message_handler + }; + DBusError error; + DBusConnection *bus = NULL; + int r; + + assert(_bus); + + dbus_error_init(&error); + + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!bus) { + log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error)); + r = -ECONNREFUSED; + goto fail; + } + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + if (!dbus_connection_register_object_path(bus, "/org/freedesktop/hostname1", &hostname_vtable, NULL) || + !dbus_connection_add_filter(bus, bus_exit_idle_filter, &remain_until, NULL)) { + log_error("Not enough memory"); + r = -ENOMEM; + goto fail; + } + + r = dbus_bus_request_name(bus, "org.freedesktop.hostname1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to register name on bus: %s", bus_error_message(&error)); + r = -EEXIST; + goto fail; + } + + if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + log_error("Failed to acquire name."); + r = -EEXIST; + goto fail; + } + + if (_bus) + *_bus = bus; + + return 0; + +fail: + dbus_connection_close(bus); + dbus_connection_unref(bus); + + dbus_error_free(&error); + + return r; +} + +int main(int argc, char *argv[]) { + int r; + DBusConnection *bus = NULL; + bool exiting = false; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc == 2 && streq(argv[1], "--introspect")) { + fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + "\n", stdout); + fputs(hostname_interface, stdout); + fputs("\n", stdout); + return 0; + } + + if (argc != 1) { + log_error("This program takes no arguments."); + r = -EINVAL; + goto finish; + } + + if (!check_nss()) + log_warning("Warning: nss-myhostname is not installed. Changing the local hostname might make it unresolveable. Please install nss-myhostname!"); + + r = read_data(); + if (r < 0) { + log_error("Failed to read hostname data: %s", strerror(-r)); + goto finish; + } + + r = connect_bus(&bus); + if (r < 0) + goto finish; + + remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC; + for (;;) { + + if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC))) + break; + + if (!exiting && remain_until < now(CLOCK_MONOTONIC)) { + exiting = true; + bus_async_unregister_and_exit(bus, "org.freedesktop.hostname1"); + } + } + + r = 0; + +finish: + free_data(); + + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/hostname/org.freedesktop.hostname1.conf b/src/hostname/org.freedesktop.hostname1.conf new file mode 100644 index 0000000..eb241c0 --- /dev/null +++ b/src/hostname/org.freedesktop.hostname1.conf @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/hostname/org.freedesktop.hostname1.policy.in b/src/hostname/org.freedesktop.hostname1.policy.in new file mode 100644 index 0000000..7d56b22 --- /dev/null +++ b/src/hostname/org.freedesktop.hostname1.policy.in @@ -0,0 +1,49 @@ + + + + + + + + The systemd Project + http://www.freedesktop.org/wiki/Software/systemd + + + <_description>Set host name + <_message>Authentication is required to set the local host name. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Set static host name + <_message>Authentication is required to set the statically configured local host name, as well as the pretty host name. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Set machine information + <_message>Authentication is required to set local machine information. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + diff --git a/src/hostname/org.freedesktop.hostname1.service b/src/hostname/org.freedesktop.hostname1.service new file mode 100644 index 0000000..42e4adb --- /dev/null +++ b/src/hostname/org.freedesktop.hostname1.service @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# systemd 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. + +[D-BUS Service] +Name=org.freedesktop.hostname1 +Exec=/bin/false +User=root +SystemdService=dbus-org.freedesktop.hostname1.service diff --git a/src/initctl.c b/src/initctl.c new file mode 100644 index 0000000..53d03a9 --- /dev/null +++ b/src/initctl.c @@ -0,0 +1,451 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "util.h" +#include "log.h" +#include "list.h" +#include "initreq.h" +#include "special.h" +#include "dbus-common.h" +#include "def.h" + +#define SERVER_FD_MAX 16 +#define TIMEOUT_MSEC ((int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC)) + +typedef struct Fifo Fifo; + +typedef struct Server { + int epoll_fd; + + LIST_HEAD(Fifo, fifos); + unsigned n_fifos; + + DBusConnection *bus; + + bool quit; +} Server; + +struct Fifo { + Server *server; + + int fd; + + struct init_request buffer; + size_t bytes_read; + + LIST_FIELDS(Fifo, fifo); +}; + +static const char *translate_runlevel(int runlevel, bool *isolate) { + static const struct { + const int runlevel; + const char *special; + bool isolate; + } table[] = { + { '0', SPECIAL_POWEROFF_TARGET, false }, + { '1', SPECIAL_RESCUE_TARGET, true }, + { 's', SPECIAL_RESCUE_TARGET, true }, + { 'S', SPECIAL_RESCUE_TARGET, true }, + { '2', SPECIAL_RUNLEVEL2_TARGET, true }, + { '3', SPECIAL_RUNLEVEL3_TARGET, true }, + { '4', SPECIAL_RUNLEVEL4_TARGET, true }, + { '5', SPECIAL_RUNLEVEL5_TARGET, true }, + { '6', SPECIAL_REBOOT_TARGET, false }, + }; + + unsigned i; + + assert(isolate); + + for (i = 0; i < ELEMENTSOF(table); i++) + if (table[i].runlevel == runlevel) { + *isolate = table[i].isolate; + if (runlevel == '6' && kexec_loaded()) + return SPECIAL_KEXEC_TARGET; + return table[i].special; + } + + return NULL; +} + +static void change_runlevel(Server *s, int runlevel) { + const char *target; + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + const char *mode; + bool isolate = false; + + assert(s); + + dbus_error_init(&error); + + if (!(target = translate_runlevel(runlevel, &isolate))) { + log_warning("Got request for unknown runlevel %c, ignoring.", runlevel); + goto finish; + } + + if (isolate) + mode = "isolate"; + else + mode = "replace"; + + log_debug("Running request %s/start/%s", target, mode); + + if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit"))) { + log_error("Could not allocate message."); + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &target, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)) { + log_error("Could not attach target and flag information to message."); + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(s->bus, m, -1, &error))) { + log_error("Failed to start unit: %s", bus_error_message(&error)); + goto finish; + } + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); +} + +static void request_process(Server *s, const struct init_request *req) { + assert(s); + assert(req); + + if (req->magic != INIT_MAGIC) { + log_error("Got initctl request with invalid magic. Ignoring."); + return; + } + + switch (req->cmd) { + + case INIT_CMD_RUNLVL: + if (!isprint(req->runlevel)) + log_error("Got invalid runlevel. Ignoring."); + else + switch (req->runlevel) { + + /* we are async anyway, so just use kill for reexec/reload */ + case 'u': + case 'U': + if (kill(1, SIGTERM) < 0) + log_error("kill() failed: %m"); + + /* The bus connection will be + * terminated if PID 1 is reexecuted, + * hence let's just exit here, and + * rely on that we'll be restarted on + * the next request */ + s->quit = true; + break; + + case 'q': + case 'Q': + if (kill(1, SIGHUP) < 0) + log_error("kill() failed: %m"); + break; + + default: + change_runlevel(s, req->runlevel); + } + return; + + case INIT_CMD_POWERFAIL: + case INIT_CMD_POWERFAILNOW: + case INIT_CMD_POWEROK: + log_warning("Received UPS/power initctl request. This is not implemented in systemd. Upgrade your UPS daemon!"); + return; + + case INIT_CMD_CHANGECONS: + log_warning("Received console change initctl request. This is not implemented in systemd."); + return; + + case INIT_CMD_SETENV: + case INIT_CMD_UNSETENV: + log_warning("Received environment initctl request. This is not implemented in systemd."); + return; + + default: + log_warning("Received unknown initctl request. Ignoring."); + return; + } +} + +static int fifo_process(Fifo *f) { + ssize_t l; + + assert(f); + + errno = EIO; + if ((l = read(f->fd, ((uint8_t*) &f->buffer) + f->bytes_read, sizeof(f->buffer) - f->bytes_read)) <= 0) { + + if (errno == EAGAIN) + return 0; + + log_warning("Failed to read from fifo: %s", strerror(errno)); + return -1; + } + + f->bytes_read += l; + assert(f->bytes_read <= sizeof(f->buffer)); + + if (f->bytes_read == sizeof(f->buffer)) { + request_process(f->server, &f->buffer); + f->bytes_read = 0; + } + + return 0; +} + +static void fifo_free(Fifo *f) { + assert(f); + + if (f->server) { + assert(f->server->n_fifos > 0); + f->server->n_fifos--; + LIST_REMOVE(Fifo, fifo, f->server->fifos, f); + } + + if (f->fd >= 0) { + if (f->server) + epoll_ctl(f->server->epoll_fd, EPOLL_CTL_DEL, f->fd, NULL); + + close_nointr_nofail(f->fd); + } + + free(f); +} + +static void server_done(Server *s) { + assert(s); + + while (s->fifos) + fifo_free(s->fifos); + + if (s->epoll_fd >= 0) + close_nointr_nofail(s->epoll_fd); + + if (s->bus) { + dbus_connection_flush(s->bus); + dbus_connection_close(s->bus); + dbus_connection_unref(s->bus); + } +} + +static int server_init(Server *s, unsigned n_sockets) { + int r; + unsigned i; + DBusError error; + + assert(s); + assert(n_sockets > 0); + + dbus_error_init(&error); + + zero(*s); + + if ((s->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0) { + r = -errno; + log_error("Failed to create epoll object: %s", strerror(errno)); + goto fail; + } + + for (i = 0; i < n_sockets; i++) { + struct epoll_event ev; + Fifo *f; + int fd; + + fd = SD_LISTEN_FDS_START+i; + + if ((r = sd_is_fifo(fd, NULL)) < 0) { + log_error("Failed to determine file descriptor type: %s", strerror(-r)); + goto fail; + } + + if (!r) { + log_error("Wrong file descriptor type."); + r = -EINVAL; + goto fail; + } + + if (!(f = new0(Fifo, 1))) { + r = -ENOMEM; + log_error("Failed to create fifo object: %s", strerror(errno)); + goto fail; + } + + f->fd = -1; + + zero(ev); + ev.events = EPOLLIN; + ev.data.ptr = f; + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) { + r = -errno; + fifo_free(f); + log_error("Failed to add fifo fd to epoll object: %s", strerror(errno)); + goto fail; + } + + f->fd = fd; + LIST_PREPEND(Fifo, fifo, s->fifos, f); + f->server = s; + s->n_fifos ++; + } + + if (bus_connect(DBUS_BUS_SYSTEM, &s->bus, NULL, &error) < 0) { + log_error("Failed to get D-Bus connection: %s", bus_error_message(&error)); + goto fail; + } + + return 0; + +fail: + server_done(s); + + dbus_error_free(&error); + return r; +} + +static int process_event(Server *s, struct epoll_event *ev) { + int r; + Fifo *f; + + assert(s); + + if (!(ev->events & EPOLLIN)) { + log_info("Got invalid event from epoll. (3)"); + return -EIO; + } + + f = (Fifo*) ev->data.ptr; + + if ((r = fifo_process(f)) < 0) { + log_info("Got error on fifo: %s", strerror(-r)); + fifo_free(f); + return r; + } + + return 0; +} + +int main(int argc, char *argv[]) { + Server server; + int r = EXIT_FAILURE, n; + + if (getppid() != 1) { + log_error("This program should be invoked by init only."); + return EXIT_FAILURE; + } + + if (argc > 1) { + log_error("This program does not take arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if ((n = sd_listen_fds(true)) < 0) { + log_error("Failed to read listening file descriptors from environment: %s", strerror(-r)); + return EXIT_FAILURE; + } + + if (n <= 0 || n > SERVER_FD_MAX) { + log_error("No or too many file descriptors passed."); + return EXIT_FAILURE; + } + + if (server_init(&server, (unsigned) n) < 0) + return EXIT_FAILURE; + + log_debug("systemd-initctl running as pid %lu", (unsigned long) getpid()); + + sd_notify(false, + "READY=1\n" + "STATUS=Processing requests..."); + + while (!server.quit) { + struct epoll_event event; + int k; + + if ((k = epoll_wait(server.epoll_fd, + &event, 1, + TIMEOUT_MSEC)) < 0) { + + if (errno == EINTR) + continue; + + log_error("epoll_wait() failed: %s", strerror(errno)); + goto fail; + } + + if (k <= 0) + break; + + if (process_event(&server, &event) < 0) + goto fail; + } + + r = EXIT_SUCCESS; + + log_debug("systemd-initctl stopped as pid %lu", (unsigned long) getpid()); + +fail: + sd_notify(false, + "STATUS=Shutting down..."); + + server_done(&server); + + dbus_shutdown(); + + return r; +} diff --git a/src/initreq.h b/src/initreq.h new file mode 100644 index 0000000..859042c --- /dev/null +++ b/src/initreq.h @@ -0,0 +1,77 @@ +/* + * initreq.h Interface to talk to init through /dev/initctl. + * + * Copyright (C) 1995-2004 Miquel van Smoorenburg + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * Version: @(#)initreq.h 1.28 31-Mar-2004 MvS + * + */ +#ifndef _INITREQ_H +#define _INITREQ_H + +#include + +#if defined(__FreeBSD_kernel__) +# define INIT_FIFO "/etc/.initctl" +#else +# define INIT_FIFO "/dev/initctl" +#endif + +#define INIT_MAGIC 0x03091969 +#define INIT_CMD_START 0 +#define INIT_CMD_RUNLVL 1 +#define INIT_CMD_POWERFAIL 2 +#define INIT_CMD_POWERFAILNOW 3 +#define INIT_CMD_POWEROK 4 +#define INIT_CMD_BSD 5 +#define INIT_CMD_SETENV 6 +#define INIT_CMD_UNSETENV 7 + +#define INIT_CMD_CHANGECONS 12345 + +#ifdef MAXHOSTNAMELEN +# define INITRQ_HLEN MAXHOSTNAMELEN +#else +# define INITRQ_HLEN 64 +#endif + +/* + * This is what BSD 4.4 uses when talking to init. + * Linux doesn't use this right now. + */ +struct init_request_bsd { + char gen_id[8]; /* Beats me.. telnetd uses "fe" */ + char tty_id[16]; /* Tty name minus /dev/tty */ + char host[INITRQ_HLEN]; /* Hostname */ + char term_type[16]; /* Terminal type */ + int signal; /* Signal to send */ + int pid; /* Process to send to */ + char exec_name[128]; /* Program to execute */ + char reserved[128]; /* For future expansion. */ +}; + + +/* + * Because of legacy interfaces, "runlevel" and "sleeptime" + * aren't in a separate struct in the union. + * + * The weird sizes are because init expects the whole + * struct to be 384 bytes. + */ +struct init_request { + int magic; /* Magic number */ + int cmd; /* What kind of request */ + int runlevel; /* Runlevel to change to */ + int sleeptime; /* Time between TERM and KILL */ + union { + struct init_request_bsd bsd; + char data[368]; + } i; +}; + +#endif diff --git a/src/install.c b/src/install.c new file mode 100644 index 0000000..174d79b --- /dev/null +++ b/src/install.c @@ -0,0 +1,1953 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty . +***/ + +#include +#include +#include +#include +#include + +#include "util.h" +#include "hashmap.h" +#include "set.h" +#include "path-lookup.h" +#include "strv.h" +#include "unit-name.h" +#include "install.h" +#include "conf-parser.h" + +typedef struct { + char *name; + char *path; + + char **aliases; + char **wanted_by; +} InstallInfo; + +typedef struct { + Hashmap *will_install; + Hashmap *have_installed; +} InstallContext; + +static int lookup_paths_init_from_scope(LookupPaths *paths, UnitFileScope scope) { + assert(paths); + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + zero(*paths); + + return lookup_paths_init(paths, + scope == UNIT_FILE_SYSTEM ? MANAGER_SYSTEM : MANAGER_USER, + scope == UNIT_FILE_USER); +} + +static int get_config_path(UnitFileScope scope, bool runtime, const char *root_dir, char **ret) { + char *p = NULL; + int r; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + assert(ret); + + switch (scope) { + + case UNIT_FILE_SYSTEM: + + if (root_dir && runtime) + asprintf(&p, "%s/run/systemd/system", root_dir); + else if (runtime) + p = strdup("/run/systemd/system"); + else if (root_dir) + asprintf(&p, "%s/%s", root_dir, SYSTEM_CONFIG_UNIT_PATH); + else + p = strdup(SYSTEM_CONFIG_UNIT_PATH); + + break; + + case UNIT_FILE_GLOBAL: + + if (root_dir) + return -EINVAL; + + if (runtime) + p = strdup("/run/systemd/user"); + else + p = strdup(USER_CONFIG_UNIT_PATH); + break; + + case UNIT_FILE_USER: + + if (root_dir || runtime) + return -EINVAL; + + r = user_config_home(&p); + if (r <= 0) + return r < 0 ? r : -ENOENT; + + break; + + default: + assert_not_reached("Bad scope"); + } + + if (!p) + return -ENOMEM; + + *ret = p; + return 0; +} + +static int add_file_change( + UnitFileChange **changes, + unsigned *n_changes, + UnitFileChangeType type, + const char *path, + const char *source) { + + UnitFileChange *c; + unsigned i; + + assert(path); + assert(!changes == !n_changes); + + if (!changes) + return 0; + + c = realloc(*changes, (*n_changes + 1) * sizeof(UnitFileChange)); + if (!c) + return -ENOMEM; + + *changes = c; + i = *n_changes; + + c[i].type = type; + c[i].path = strdup(path); + if (!c[i].path) + return -ENOMEM; + + if (source) { + c[i].source = strdup(source); + if (!c[i].source) { + free(c[i].path); + return -ENOMEM; + } + } else + c[i].source = NULL; + + *n_changes = i+1; + return 0; +} + +static int mark_symlink_for_removal( + Set **remove_symlinks_to, + const char *p) { + + char *n; + int r; + + assert(p); + + r = set_ensure_allocated(remove_symlinks_to, string_hash_func, string_compare_func); + if (r < 0) + return r; + + n = strdup(p); + if (!n) + return -ENOMEM; + + path_kill_slashes(n); + + r = set_put(*remove_symlinks_to, n); + if (r < 0) { + free(n); + return r == -EEXIST ? 0 : r; + } + + return 0; +} + +static int remove_marked_symlinks_fd( + Set *remove_symlinks_to, + int fd, + const char *path, + const char *config_path, + bool *deleted, + UnitFileChange **changes, + unsigned *n_changes) { + + int r = 0; + DIR *d; + struct dirent buffer, *de; + + assert(remove_symlinks_to); + assert(fd >= 0); + assert(path); + assert(config_path); + assert(deleted); + + d = fdopendir(fd); + if (!d) { + close_nointr_nofail(fd); + return -errno; + } + + rewinddir(d); + + for (;;) { + int k; + + k = readdir_r(d, &buffer, &de); + if (k != 0) { + r = -errno; + break; + } + + if (!de) + break; + + if (ignore_file(de->d_name)) + continue; + + dirent_ensure_type(d, de); + + if (de->d_type == DT_DIR) { + int nfd, q; + char *p; + + nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); + if (nfd < 0) { + if (errno == ENOENT) + continue; + + if (r == 0) + r = -errno; + continue; + } + + p = path_make_absolute(de->d_name, path); + if (!p) { + close_nointr_nofail(nfd); + r = -ENOMEM; + break; + } + + /* This will close nfd, regardless whether it succeeds or not */ + q = remove_marked_symlinks_fd(remove_symlinks_to, nfd, p, config_path, deleted, changes, n_changes); + free(p); + + if (r == 0) + r = q; + + } else if (de->d_type == DT_LNK) { + char *p, *dest; + int q; + bool found; + + p = path_make_absolute(de->d_name, path); + if (!p) { + r = -ENOMEM; + break; + } + + q = readlink_and_canonicalize(p, &dest); + if (q < 0) { + free(p); + + if (q == -ENOENT) + continue; + + if (r == 0) + r = q; + continue; + } + + found = + set_get(remove_symlinks_to, dest) || + set_get(remove_symlinks_to, file_name_from_path(dest)); + + if (found) { + + if (unlink(p) < 0 && errno != ENOENT) { + + if (r == 0) + r = -errno; + } else { + rmdir_parents(p, config_path); + path_kill_slashes(p); + + add_file_change(changes, n_changes, UNIT_FILE_UNLINK, p, NULL); + + if (!set_get(remove_symlinks_to, p)) { + + q = mark_symlink_for_removal(&remove_symlinks_to, p); + if (q < 0) { + if (r == 0) + r = q; + } else + *deleted = true; + } + } + } + + free(p); + free(dest); + } + } + + closedir(d); + + return r; +} + +static int remove_marked_symlinks( + Set *remove_symlinks_to, + const char *config_path, + UnitFileChange **changes, + unsigned *n_changes) { + + int fd, r = 0; + bool deleted; + + assert(config_path); + + if (set_size(remove_symlinks_to) <= 0) + return 0; + + fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); + if (fd < 0) + return -errno; + + do { + int q, cfd; + deleted = false; + + cfd = dup(fd); + if (cfd < 0) { + r = -errno; + break; + } + + /* This takes possession of cfd and closes it */ + q = remove_marked_symlinks_fd(remove_symlinks_to, cfd, config_path, config_path, &deleted, changes, n_changes); + if (r == 0) + r = q; + } while (deleted); + + close_nointr_nofail(fd); + + return r; +} + +static int find_symlinks_fd( + const char *name, + int fd, + const char *path, + const char *config_path, + bool *same_name_link) { + + int r = 0; + DIR *d; + struct dirent buffer, *de; + + assert(name); + assert(fd >= 0); + assert(path); + assert(config_path); + assert(same_name_link); + + d = fdopendir(fd); + if (!d) { + close_nointr_nofail(fd); + return -errno; + } + + for (;;) { + int k; + + k = readdir_r(d, &buffer, &de); + if (k != 0) { + r = -errno; + break; + } + + if (!de) + break; + + if (ignore_file(de->d_name)) + continue; + + dirent_ensure_type(d, de); + + if (de->d_type == DT_DIR) { + int nfd, q; + char *p; + + nfd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); + if (nfd < 0) { + if (errno == ENOENT) + continue; + + if (r == 0) + r = -errno; + continue; + } + + p = path_make_absolute(de->d_name, path); + if (!p) { + close_nointr_nofail(nfd); + r = -ENOMEM; + break; + } + + /* This will close nfd, regardless whether it succeeds or not */ + q = find_symlinks_fd(name, nfd, p, config_path, same_name_link); + free(p); + + if (q > 0) { + r = 1; + break; + } + + if (r == 0) + r = q; + + } else if (de->d_type == DT_LNK) { + char *p, *dest; + bool found_path, found_dest, b = false; + int q; + + /* Acquire symlink name */ + p = path_make_absolute(de->d_name, path); + if (!p) { + r = -ENOMEM; + break; + } + + /* Acquire symlink destination */ + q = readlink_and_canonicalize(p, &dest); + if (q < 0) { + free(p); + + if (q == -ENOENT) + continue; + + if (r == 0) + r = q; + continue; + } + + /* Check if the symlink itself matches what we + * are looking for */ + if (path_is_absolute(name)) + found_path = path_equal(p, name); + else + found_path = streq(de->d_name, name); + + /* Check if what the symlink points to + * matches what we are looking for */ + if (path_is_absolute(name)) + found_dest = path_equal(dest, name); + else + found_dest = streq(file_name_from_path(dest), name); + + free(dest); + + if (found_path && found_dest) { + char *t; + + /* Filter out same name links in the main + * config path */ + t = path_make_absolute(name, config_path); + if (!t) { + free(p); + r = -ENOMEM; + break; + } + + b = path_equal(t, p); + free(t); + } + + free(p); + + if (b) + *same_name_link = true; + else if (found_path || found_dest) { + r = 1; + break; + } + } + } + + closedir(d); + + return r; +} + +static int find_symlinks( + const char *name, + const char *config_path, + bool *same_name_link) { + + int fd; + + assert(name); + assert(config_path); + assert(same_name_link); + + fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW); + if (fd < 0) + return -errno; + + /* This takes possession of fd and closes it */ + return find_symlinks_fd(name, fd, config_path, config_path, same_name_link); +} + +static int find_symlinks_in_scope( + UnitFileScope scope, + const char *root_dir, + const char *name, + UnitFileState *state) { + + int r; + char *path; + bool same_name_link_runtime = false, same_name_link = false; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + assert(name); + + if (scope == UNIT_FILE_SYSTEM || scope == UNIT_FILE_GLOBAL) { + + /* First look in runtime config path */ + r = get_config_path(scope, true, root_dir, &path); + if (r < 0) + return r; + + r = find_symlinks(name, path, &same_name_link_runtime); + free(path); + + if (r < 0) + return r; + else if (r > 0) { + *state = UNIT_FILE_ENABLED_RUNTIME; + return r; + } + } + + /* Then look in the normal config path */ + r = get_config_path(scope, false, root_dir, &path); + if (r < 0) + return r; + + r = find_symlinks(name, path, &same_name_link); + free(path); + + if (r < 0) + return r; + else if (r > 0) { + *state = UNIT_FILE_ENABLED; + return r; + } + + /* Hmm, we didn't find it, but maybe we found the same name + * link? */ + if (same_name_link_runtime) { + *state = UNIT_FILE_LINKED_RUNTIME; + return 1; + } else if (same_name_link) { + *state = UNIT_FILE_LINKED; + return 1; + } + + return 0; +} + +int unit_file_mask( + UnitFileScope scope, + bool runtime, + const char *root_dir, + char *files[], + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + char **i, *prefix; + int r; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + r = get_config_path(scope, runtime, root_dir, &prefix); + if (r < 0) + return r; + + STRV_FOREACH(i, files) { + char *path; + + if (!unit_name_is_valid_no_type(*i, true)) { + if (r == 0) + r = -EINVAL; + continue; + } + + path = path_make_absolute(*i, prefix); + if (!path) { + r = -ENOMEM; + break; + } + + if (symlink("/dev/null", path) >= 0) { + add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null"); + + free(path); + continue; + } + + if (errno == EEXIST) { + + if (null_or_empty_path(path) > 0) { + free(path); + continue; + } + + if (force) { + unlink(path); + + if (symlink("/dev/null", path) >= 0) { + + add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL); + add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, "/dev/null"); + + free(path); + continue; + } + } + + if (r == 0) + r = -EEXIST; + } else { + if (r == 0) + r = -errno; + } + + free(path); + } + + free(prefix); + + return r; +} + +int unit_file_unmask( + UnitFileScope scope, + bool runtime, + const char *root_dir, + char *files[], + UnitFileChange **changes, + unsigned *n_changes) { + + char **i, *config_path = NULL; + int r, q; + Set *remove_symlinks_to = NULL; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + r = get_config_path(scope, runtime, root_dir, &config_path); + if (r < 0) + goto finish; + + STRV_FOREACH(i, files) { + char *path; + + if (!unit_name_is_valid_no_type(*i, true)) { + if (r == 0) + r = -EINVAL; + continue; + } + + path = path_make_absolute(*i, config_path); + if (!path) { + r = -ENOMEM; + break; + } + + q = null_or_empty_path(path); + if (q > 0) { + if (unlink(path) >= 0) { + mark_symlink_for_removal(&remove_symlinks_to, path); + add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL); + + free(path); + continue; + } + + q = -errno; + } + + if (q != -ENOENT && r == 0) + r = q; + + free(path); + } + + +finish: + q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes); + if (r == 0) + r = q; + + set_free_free(remove_symlinks_to); + free(config_path); + + return r; +} + +int unit_file_link( + UnitFileScope scope, + bool runtime, + const char *root_dir, + char *files[], + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + LookupPaths paths; + char **i, *config_path = NULL; + int r, q; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + zero(paths); + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + r = get_config_path(scope, runtime, root_dir, &config_path); + if (r < 0) + goto finish; + + STRV_FOREACH(i, files) { + char *path, *fn; + struct stat st; + + fn = file_name_from_path(*i); + + if (!path_is_absolute(*i) || + !unit_name_is_valid_no_type(fn, true)) { + if (r == 0) + r = -EINVAL; + continue; + } + + if (lstat(*i, &st) < 0) { + if (r == 0) + r = -errno; + continue; + } + + if (!S_ISREG(st.st_mode)) { + r = -ENOENT; + continue; + } + + q = in_search_path(*i, paths.unit_path); + if (q < 0) { + r = q; + break; + } + + if (q > 0) + continue; + + path = path_make_absolute(fn, config_path); + if (!path) { + r = -ENOMEM; + break; + } + + if (symlink(*i, path) >= 0) { + add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i); + + free(path); + continue; + } + + if (errno == EEXIST) { + char *dest = NULL; + + q = readlink_and_make_absolute(path, &dest); + + if (q < 0 && errno != ENOENT) { + free(path); + + if (r == 0) + r = q; + + continue; + } + + if (q >= 0 && path_equal(dest, *i)) { + free(dest); + free(path); + continue; + } + + free(dest); + + if (force) { + unlink(path); + + if (symlink(*i, path) >= 0) { + + add_file_change(changes, n_changes, UNIT_FILE_UNLINK, path, NULL); + add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, path, *i); + + free(path); + continue; + } + } + + if (r == 0) + r = -EEXIST; + } else { + if (r == 0) + r = -errno; + } + + free(path); + } + + finish: + lookup_paths_free(&paths); + free(config_path); + + return r; +} + +void unit_file_list_free(Hashmap *h) { + UnitFileList *i; + + while ((i = hashmap_steal_first(h))) { + free(i->path); + free(i); + } + + hashmap_free(h); +} + +void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes) { + unsigned i; + + assert(changes || n_changes == 0); + + if (!changes) + return; + + for (i = 0; i < n_changes; i++) { + free(changes[i].path); + free(changes[i].source); + } + + free(changes); +} + +static void install_info_free(InstallInfo *i) { + assert(i); + + free(i->name); + free(i->path); + strv_free(i->aliases); + strv_free(i->wanted_by); + free(i); +} + +static void install_info_hashmap_free(Hashmap *m) { + InstallInfo *i; + + if (!m) + return; + + while ((i = hashmap_steal_first(m))) + install_info_free(i); + + hashmap_free(m); +} + +static void install_context_done(InstallContext *c) { + assert(c); + + install_info_hashmap_free(c->will_install); + install_info_hashmap_free(c->have_installed); + + c->will_install = c->have_installed = NULL; +} + +static int install_info_add( + InstallContext *c, + const char *name, + const char *path) { + InstallInfo *i = NULL; + int r; + + assert(c); + assert(name || path); + + if (!name) + name = file_name_from_path(path); + + if (!unit_name_is_valid_no_type(name, true)) + return -EINVAL; + + if (hashmap_get(c->have_installed, name) || + hashmap_get(c->will_install, name)) + return 0; + + r = hashmap_ensure_allocated(&c->will_install, string_hash_func, string_compare_func); + if (r < 0) + return r; + + i = new0(InstallInfo, 1); + if (!i) + return -ENOMEM; + + i->name = strdup(name); + if (!i->name) { + r = -ENOMEM; + goto fail; + } + + if (path) { + i->path = strdup(path); + if (!i->path) { + r = -ENOMEM; + goto fail; + } + } + + r = hashmap_put(c->will_install, i->name, i); + if (r < 0) + goto fail; + + return 0; + +fail: + if (i) + install_info_free(i); + + return r; +} + +static int install_info_add_auto( + InstallContext *c, + const char *name_or_path) { + + assert(c); + assert(name_or_path); + + if (path_is_absolute(name_or_path)) + return install_info_add(c, NULL, name_or_path); + else + return install_info_add(c, name_or_path, NULL); +} + +static int config_parse_also( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char *w; + size_t l; + char *state; + InstallContext *c = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char *n; + int r; + + n = strndup(w, l); + if (!n) + return -ENOMEM; + + r = install_info_add(c, n, NULL); + if (r < 0) { + free(n); + return r; + } + + free(n); + } + + return 0; +} + +static int unit_file_load( + InstallContext *c, + InstallInfo *info, + const char *path, + bool allow_symlink) { + + const ConfigTableItem items[] = { + { "Install", "Alias", config_parse_strv, 0, &info->aliases }, + { "Install", "WantedBy", config_parse_strv, 0, &info->wanted_by }, + { "Install", "Also", config_parse_also, 0, c }, + { NULL, NULL, NULL, 0, NULL } + }; + + int fd; + FILE *f; + int r; + + assert(c); + assert(info); + assert(path); + + fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|(allow_symlink ? 0 : O_NOFOLLOW)); + if (fd < 0) + return -errno; + + f = fdopen(fd, "re"); + if (!f) { + close_nointr_nofail(fd); + return -ENOMEM; + } + + r = config_parse(path, f, NULL, config_item_table_lookup, (void*) items, true, info); + fclose(f); + if (r < 0) + return r; + + return strv_length(info->aliases) + strv_length(info->wanted_by); +} + +static int unit_file_search( + InstallContext *c, + InstallInfo *info, + LookupPaths *paths, + const char *root_dir, + bool allow_symlink) { + + char **p; + int r; + + assert(c); + assert(info); + assert(paths); + + if (info->path) + return unit_file_load(c, info, info->path, allow_symlink); + + assert(info->name); + + STRV_FOREACH(p, paths->unit_path) { + char *path = NULL; + + if (isempty(root_dir)) + asprintf(&path, "%s/%s", *p, info->name); + else + asprintf(&path, "%s/%s/%s", root_dir, *p, info->name); + + if (!path) + return -ENOMEM; + + r = unit_file_load(c, info, path, allow_symlink); + + if (r >= 0) + info->path = path; + else + free(path); + + if (r != -ENOENT && r != -ELOOP) + return r; + } + + return -ENOENT; +} + +static int unit_file_can_install( + LookupPaths *paths, + const char *root_dir, + const char *name, + bool allow_symlink) { + + InstallContext c; + InstallInfo *i; + int r; + + assert(paths); + assert(name); + + zero(c); + + r = install_info_add_auto(&c, name); + if (r < 0) + return r; + + assert_se(i = hashmap_first(c.will_install)); + + r = unit_file_search(&c, i, paths, root_dir, allow_symlink); + + if (r >= 0) + r = strv_length(i->aliases) + strv_length(i->wanted_by); + + install_context_done(&c); + + return r; +} + +static int create_symlink( + const char *old_path, + const char *new_path, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + char *dest; + int r; + + assert(old_path); + assert(new_path); + + mkdir_parents(new_path, 0755); + + if (symlink(old_path, new_path) >= 0) { + add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path); + return 0; + } + + if (errno != EEXIST) + return -errno; + + r = readlink_and_make_absolute(new_path, &dest); + if (r < 0) + return r; + + if (path_equal(dest, old_path)) { + free(dest); + return 0; + } + + free(dest); + + if (force) + return -EEXIST; + + unlink(new_path); + + if (symlink(old_path, new_path) >= 0) { + add_file_change(changes, n_changes, UNIT_FILE_UNLINK, new_path, NULL); + add_file_change(changes, n_changes, UNIT_FILE_SYMLINK, new_path, old_path); + return 0; + } + + return -errno; +} + +static int install_info_symlink_alias( + InstallInfo *i, + const char *config_path, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + char **s; + int r = 0, q; + + assert(i); + assert(config_path); + + STRV_FOREACH(s, i->aliases) { + char *alias_path; + + alias_path = path_make_absolute(*s, config_path); + + if (!alias_path) + return -ENOMEM; + + q = create_symlink(i->path, alias_path, force, changes, n_changes); + free(alias_path); + + if (r == 0) + r = q; + } + + return r; +} + +static int install_info_symlink_wants( + InstallInfo *i, + const char *config_path, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + char **s; + int r = 0, q; + + assert(i); + assert(config_path); + + STRV_FOREACH(s, i->wanted_by) { + char *path; + + if (!unit_name_is_valid_no_type(*s, true)) { + r = -EINVAL; + continue; + } + + if (asprintf(&path, "%s/%s.wants/%s", config_path, *s, i->name) < 0) + return -ENOMEM; + + q = create_symlink(i->path, path, force, changes, n_changes); + free(path); + + if (r == 0) + r = q; + } + + return r; +} + +static int install_info_symlink_link( + InstallInfo *i, + LookupPaths *paths, + const char *config_path, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + int r; + char *path; + + assert(i); + assert(paths); + assert(config_path); + assert(i->path); + + r = in_search_path(i->path, paths->unit_path); + if (r != 0) + return r; + + if (asprintf(&path, "%s/%s", config_path, i->name) < 0) + return -ENOMEM; + + r = create_symlink(i->path, path, force, changes, n_changes); + free(path); + + return r; +} + +static int install_info_apply( + InstallInfo *i, + LookupPaths *paths, + const char *config_path, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + int r, q; + + assert(i); + assert(paths); + assert(config_path); + + r = install_info_symlink_alias(i, config_path, force, changes, n_changes); + + q = install_info_symlink_wants(i, config_path, force, changes, n_changes); + if (r == 0) + r = q; + + q = install_info_symlink_link(i, paths, config_path, force, changes, n_changes); + if (r == 0) + r = q; + + return r; +} + +static int install_context_apply( + InstallContext *c, + LookupPaths *paths, + const char *config_path, + const char *root_dir, + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + InstallInfo *i; + int r = 0, q; + + assert(c); + assert(paths); + assert(config_path); + + while ((i = hashmap_first(c->will_install))) { + + q = hashmap_ensure_allocated(&c->have_installed, string_hash_func, string_compare_func); + if (q < 0) + return q; + + assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0); + + q = unit_file_search(c, i, paths, root_dir, false); + if (q < 0) { + if (r >= 0) + r = q; + + return r; + } else if (r >= 0) + r += q; + + q = install_info_apply(i, paths, config_path, force, changes, n_changes); + if (r >= 0 && q < 0) + r = q; + } + + return r; +} + +static int install_context_mark_for_removal( + InstallContext *c, + LookupPaths *paths, + Set **remove_symlinks_to, + const char *config_path, + const char *root_dir) { + + InstallInfo *i; + int r = 0, q; + + assert(c); + assert(paths); + assert(config_path); + + /* Marks all items for removal */ + + while ((i = hashmap_first(c->will_install))) { + + q = hashmap_ensure_allocated(&c->have_installed, string_hash_func, string_compare_func); + if (q < 0) + return q; + + assert_se(hashmap_move_one(c->have_installed, c->will_install, i->name) == 0); + + q = unit_file_search(c, i, paths, root_dir, false); + if (q < 0) { + if (r >= 0) + r = q; + + return r; + } else if (r >= 0) + r += q; + + q = mark_symlink_for_removal(remove_symlinks_to, i->name); + if (r >= 0 && q < 0) + r = q; + } + + return r; +} + +int unit_file_enable( + UnitFileScope scope, + bool runtime, + const char *root_dir, + char *files[], + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + LookupPaths paths; + InstallContext c; + char **i, *config_path = NULL; + int r; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + zero(paths); + zero(c); + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + r = get_config_path(scope, runtime, root_dir, &config_path); + if (r < 0) + goto finish; + + STRV_FOREACH(i, files) { + r = install_info_add_auto(&c, *i); + if (r < 0) + goto finish; + } + + /* This will return the number of symlink rules that were + supposed to be created, not the ones actually created. This is + useful to determine whether the passed files hat any + installation data at all. */ + r = install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes); + +finish: + install_context_done(&c); + lookup_paths_free(&paths); + free(config_path); + + return r; +} + +int unit_file_disable( + UnitFileScope scope, + bool runtime, + const char *root_dir, + char *files[], + UnitFileChange **changes, + unsigned *n_changes) { + + LookupPaths paths; + InstallContext c; + char **i, *config_path = NULL; + Set *remove_symlinks_to = NULL; + int r, q; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + zero(paths); + zero(c); + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + r = get_config_path(scope, runtime, root_dir, &config_path); + if (r < 0) + goto finish; + + STRV_FOREACH(i, files) { + r = install_info_add_auto(&c, *i); + if (r < 0) + goto finish; + } + + r = install_context_mark_for_removal(&c, &paths, &remove_symlinks_to, config_path, root_dir); + + q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes); + if (r == 0) + r = q; + +finish: + install_context_done(&c); + lookup_paths_free(&paths); + set_free_free(remove_symlinks_to); + free(config_path); + + return r; +} + +int unit_file_reenable( + UnitFileScope scope, + bool runtime, + const char *root_dir, + char *files[], + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + LookupPaths paths; + InstallContext c; + char **i, *config_path = NULL; + Set *remove_symlinks_to = NULL; + int r, q; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + zero(paths); + zero(c); + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + r = get_config_path(scope, runtime, root_dir, &config_path); + if (r < 0) + goto finish; + + STRV_FOREACH(i, files) { + r = mark_symlink_for_removal(&remove_symlinks_to, *i); + if (r < 0) + goto finish; + + r = install_info_add_auto(&c, *i); + if (r < 0) + goto finish; + } + + r = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes); + + /* Returns number of symlinks that where supposed to be installed. */ + q = install_context_apply(&c, &paths, config_path, root_dir, force, changes, n_changes); + if (r == 0) + r = q; + +finish: + lookup_paths_free(&paths); + install_context_done(&c); + set_free_free(remove_symlinks_to); + free(config_path); + + return r; +} + +UnitFileState unit_file_get_state( + UnitFileScope scope, + const char *root_dir, + const char *name) { + + LookupPaths paths; + UnitFileState state = _UNIT_FILE_STATE_INVALID; + char **i, *path = NULL; + int r; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + assert(name); + + zero(paths); + + if (root_dir && scope != UNIT_FILE_SYSTEM) + return -EINVAL; + + if (!unit_name_is_valid_no_type(name, true)) + return -EINVAL; + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + STRV_FOREACH(i, paths.unit_path) { + struct stat st; + + free(path); + path = NULL; + + if (root_dir) + asprintf(&path, "%s/%s/%s", root_dir, *i, name); + else + asprintf(&path, "%s/%s", *i, name); + + if (!path) { + r = -ENOMEM; + goto finish; + } + + if (lstat(path, &st) < 0) { + r = -errno; + if (errno == ENOENT) + continue; + + goto finish; + } + + if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) { + r = -ENOENT; + goto finish; + } + + r = null_or_empty_path(path); + if (r < 0 && r != -ENOENT) + goto finish; + else if (r > 0) { + state = path_startswith(*i, "/run") ? + UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED; + r = 0; + goto finish; + } + + r = find_symlinks_in_scope(scope, root_dir, name, &state); + if (r < 0) { + goto finish; + } else if (r > 0) { + r = 0; + goto finish; + } + + r = unit_file_can_install(&paths, root_dir, path, true); + if (r < 0 && errno != -ENOENT) + goto finish; + else if (r > 0) { + state = UNIT_FILE_DISABLED; + r = 0; + goto finish; + } else if (r == 0) { + state = UNIT_FILE_STATIC; + r = 0; + goto finish; + } + } + +finish: + lookup_paths_free(&paths); + free(path); + + return r < 0 ? r : state; +} + +int unit_file_query_preset(UnitFileScope scope, const char *name) { + char **files, **i; + int r; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + assert(name); + + if (scope == UNIT_FILE_SYSTEM) + r = conf_files_list(&files, ".preset", + "/etc/systemd/system.preset", + "/usr/local/lib/systemd/system.preset", + "/usr/lib/systemd/system.preset", + "/lib/systemd/system.preset", + NULL); + else if (scope == UNIT_FILE_GLOBAL) + r = conf_files_list(&files, ".preset", + "/etc/systemd/user.preset", + "/usr/local/lib/systemd/user.preset", + "/usr/lib/systemd/user.preset", + NULL); + else + return 1; + + if (r < 0) + return r; + + STRV_FOREACH(i, files) { + FILE *f; + + f = fopen(*i, "re"); + if (!f) { + if (errno == ENOENT) + continue; + + r = -errno; + goto finish; + } + + for (;;) { + char line[LINE_MAX], *l; + + if (!fgets(line, sizeof(line), f)) + break; + + l = strstrip(line); + if (!*l) + continue; + + if (strchr(COMMENTS, *l)) + continue; + + if (first_word(l, "enable")) { + l += 6; + l += strspn(l, WHITESPACE); + + if (fnmatch(l, name, FNM_NOESCAPE) == 0) { + r = 1; + fclose(f); + goto finish; + } + } else if (first_word(l, "disable")) { + l += 7; + l += strspn(l, WHITESPACE); + + if (fnmatch(l, name, FNM_NOESCAPE) == 0) { + r = 0; + fclose(f); + goto finish; + } + } else + log_debug("Couldn't parse line '%s'", l); + } + + fclose(f); + } + + /* Default is "enable" */ + r = 1; + +finish: + strv_free(files); + + return r; +} + +int unit_file_preset( + UnitFileScope scope, + bool runtime, + const char *root_dir, + char *files[], + bool force, + UnitFileChange **changes, + unsigned *n_changes) { + + LookupPaths paths; + InstallContext plus, minus; + char **i, *config_path = NULL; + Set *remove_symlinks_to = NULL; + int r, q; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + + zero(paths); + zero(plus); + zero(minus); + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + r = get_config_path(scope, runtime, root_dir, &config_path); + if (r < 0) + goto finish; + + STRV_FOREACH(i, files) { + + if (!unit_name_is_valid_no_type(*i, true)) { + r = -EINVAL; + goto finish; + } + + r = unit_file_query_preset(scope, *i); + if (r < 0) + goto finish; + + if (r) + r = install_info_add_auto(&plus, *i); + else + r = install_info_add_auto(&minus, *i); + + if (r < 0) + goto finish; + } + + r = install_context_mark_for_removal(&minus, &paths, &remove_symlinks_to, config_path, root_dir); + + q = remove_marked_symlinks(remove_symlinks_to, config_path, changes, n_changes); + if (r == 0) + r = q; + + /* Returns number of symlinks that where supposed to be installed. */ + q = install_context_apply(&plus, &paths, config_path, root_dir, force, changes, n_changes); + if (r == 0) + r = q; + +finish: + lookup_paths_free(&paths); + install_context_done(&plus); + install_context_done(&minus); + set_free_free(remove_symlinks_to); + free(config_path); + + return r; +} + +int unit_file_get_list( + UnitFileScope scope, + const char *root_dir, + Hashmap *h) { + + LookupPaths paths; + char **i, *buf = NULL; + DIR *d = NULL; + int r; + + assert(scope >= 0); + assert(scope < _UNIT_FILE_SCOPE_MAX); + assert(h); + + zero(paths); + + if (root_dir && scope != UNIT_FILE_SYSTEM) + return -EINVAL; + + r = lookup_paths_init_from_scope(&paths, scope); + if (r < 0) + return r; + + STRV_FOREACH(i, paths.unit_path) { + struct dirent buffer, *de; + const char *units_dir; + + free(buf); + buf = NULL; + + if (root_dir) { + if (asprintf(&buf, "%s/%s", root_dir, *i) < 0) { + r = -ENOMEM; + goto finish; + } + units_dir = buf; + } else + units_dir = *i; + + if (d) + closedir(d); + + d = opendir(units_dir); + if (!d) { + if (errno == ENOENT) + continue; + + r = -errno; + goto finish; + } + + for (;;) { + UnitFileList *f; + + r = readdir_r(d, &buffer, &de); + if (r != 0) { + r = -r; + goto finish; + } + + if (!de) + break; + + if (ignore_file(de->d_name)) + continue; + + if (!unit_name_is_valid_no_type(de->d_name, true)) + continue; + + if (hashmap_get(h, de->d_name)) + continue; + + r = dirent_ensure_type(d, de); + if (r < 0) { + if (errno == ENOENT) + continue; + + goto finish; + } + + if (de->d_type != DT_LNK && de->d_type != DT_REG) + continue; + + f = new0(UnitFileList, 1); + if (!f) { + r = -ENOMEM; + goto finish; + } + + f->path = path_make_absolute(de->d_name, units_dir); + if (!f->path) { + free(f); + r = -ENOMEM; + goto finish; + } + + r = null_or_empty_path(f->path); + if (r < 0 && r != -ENOENT) { + free(f->path); + free(f); + goto finish; + } else if (r > 0) { + f->state = + path_startswith(*i, "/run") ? + UNIT_FILE_MASKED_RUNTIME : UNIT_FILE_MASKED; + goto found; + } + + r = find_symlinks_in_scope(scope, root_dir, de->d_name, &f->state); + if (r < 0) { + free(f->path); + free(f); + goto finish; + } else if (r > 0) + goto found; + + r = unit_file_can_install(&paths, root_dir, f->path, true); + if (r < 0) { + free(f->path); + free(f); + goto finish; + } else if (r > 0) { + f->state = UNIT_FILE_DISABLED; + goto found; + } else { + f->state = UNIT_FILE_STATIC; + goto found; + } + + free(f->path); + free(f); + continue; + + found: + r = hashmap_put(h, file_name_from_path(f->path), f); + if (r < 0) { + free(f->path); + free(f); + goto finish; + } + } + } + +finish: + lookup_paths_free(&paths); + free(buf); + + if (d) + closedir(d); + + return r; +} + +static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = { + [UNIT_FILE_ENABLED] = "enabled", + [UNIT_FILE_ENABLED_RUNTIME] = "enabled-runtie", + [UNIT_FILE_LINKED] = "linked", + [UNIT_FILE_LINKED_RUNTIME] = "linked-runtime", + [UNIT_FILE_MASKED] = "masked", + [UNIT_FILE_MASKED_RUNTIME] = "masked-runtime", + [UNIT_FILE_STATIC] = "static", + [UNIT_FILE_DISABLED] = "disabled" +}; + +DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState); + +static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = { + [UNIT_FILE_SYMLINK] = "symlink", + [UNIT_FILE_UNLINK] = "unlink", +}; + +DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType); diff --git a/src/install.h b/src/install.h new file mode 100644 index 0000000..0505a82 --- /dev/null +++ b/src/install.h @@ -0,0 +1,89 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooinstallhfoo +#define fooinstallhfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "hashmap.h" + +typedef enum UnitFileScope { + UNIT_FILE_SYSTEM, + UNIT_FILE_GLOBAL, + UNIT_FILE_USER, + _UNIT_FILE_SCOPE_MAX, + _UNIT_FILE_SCOPE_INVALID = -1 +} UnitFileScope; + +typedef enum UnitFileState { + UNIT_FILE_ENABLED, + UNIT_FILE_ENABLED_RUNTIME, + UNIT_FILE_LINKED, + UNIT_FILE_LINKED_RUNTIME, + UNIT_FILE_MASKED, + UNIT_FILE_MASKED_RUNTIME, + UNIT_FILE_STATIC, + UNIT_FILE_DISABLED, + _UNIT_FILE_STATE_MAX, + _UNIT_FILE_STATE_INVALID = -1 +} UnitFileState; + +typedef enum UnitFileChangeType { + UNIT_FILE_SYMLINK, + UNIT_FILE_UNLINK, + _UNIT_FILE_CHANGE_TYPE_MAX, + _UNIT_FILE_CHANGE_TYPE_INVALID = -1 +} UnitFileChangeType; + +typedef struct UnitFileChange { + UnitFileChangeType type; + char *path; + char *source; +} UnitFileChange; + +typedef struct UnitFileList { + char *path; + UnitFileState state; +} UnitFileList; + +int unit_file_enable(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes); +int unit_file_disable(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes); +int unit_file_reenable(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes); +int unit_file_link(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes); +int unit_file_preset(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes); +int unit_file_mask(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes); +int unit_file_unmask(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes); + +UnitFileState unit_file_get_state(UnitFileScope scope, const char *root_dir, const char *filename); + +int unit_file_get_list(UnitFileScope scope, const char *root_dir, Hashmap *h); + +void unit_file_list_free(Hashmap *h); +void unit_file_changes_free(UnitFileChange *changes, unsigned n_changes); + +int unit_file_query_preset(UnitFileScope scope, const char *name); + +const char *unit_file_state_to_string(UnitFileState s); +UnitFileState unit_file_state_from_string(const char *s); + +const char *unit_file_change_type_to_string(UnitFileChangeType s); +UnitFileChangeType unit_file_change_type_from_string(const char *s); + +#endif diff --git a/src/ioprio.h b/src/ioprio.h new file mode 100644 index 0000000..9800fc2 --- /dev/null +++ b/src/ioprio.h @@ -0,0 +1,57 @@ +#ifndef IOPRIO_H +#define IOPRIO_H + +/* This is minimal version of Linux' linux/ioprio.h header file, which + * is licensed GPL2 */ + +#include +#include + +/* + * Gives us 8 prio classes with 13-bits of data for each class + */ +#define IOPRIO_BITS (16) +#define IOPRIO_CLASS_SHIFT (13) +#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1) + +#define IOPRIO_PRIO_CLASS(mask) ((mask) >> IOPRIO_CLASS_SHIFT) +#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK) +#define IOPRIO_PRIO_VALUE(class, data) (((class) << IOPRIO_CLASS_SHIFT) | data) + +#define ioprio_valid(mask) (IOPRIO_PRIO_CLASS((mask)) != IOPRIO_CLASS_NONE) + +/* + * These are the io priority groups as implemented by CFQ. RT is the realtime + * class, it always gets premium service. BE is the best-effort scheduling + * class, the default for any process. IDLE is the idle scheduling class, it + * is only served when no one else is using the disk. + */ +enum { + IOPRIO_CLASS_NONE, + IOPRIO_CLASS_RT, + IOPRIO_CLASS_BE, + IOPRIO_CLASS_IDLE, +}; + +/* + * 8 best effort priority levels are supported + */ +#define IOPRIO_BE_NR (8) + +enum { + IOPRIO_WHO_PROCESS = 1, + IOPRIO_WHO_PGRP, + IOPRIO_WHO_USER, +}; + +static inline int ioprio_set(int which, int who, int ioprio) +{ + return syscall(__NR_ioprio_set, which, who, ioprio); +} + +static inline int ioprio_get(int which, int who) +{ + return syscall(__NR_ioprio_get, which, who); +} + +#endif diff --git a/src/job.c b/src/job.c new file mode 100644 index 0000000..e57286f --- /dev/null +++ b/src/job.c @@ -0,0 +1,772 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "set.h" +#include "unit.h" +#include "macro.h" +#include "strv.h" +#include "load-fragment.h" +#include "load-dropin.h" +#include "log.h" +#include "dbus-job.h" + +Job* job_new(Manager *m, JobType type, Unit *unit) { + Job *j; + + assert(m); + assert(type < _JOB_TYPE_MAX); + assert(unit); + + if (!(j = new0(Job, 1))) + return NULL; + + j->manager = m; + j->id = m->current_job_id++; + j->type = type; + j->unit = unit; + + j->timer_watch.type = WATCH_INVALID; + + /* We don't link it here, that's what job_dependency() is for */ + + return j; +} + +void job_free(Job *j) { + assert(j); + + /* Detach from next 'bigger' objects */ + if (j->installed) { + bus_job_send_removed_signal(j); + + if (j->unit->job == j) { + j->unit->job = NULL; + unit_add_to_gc_queue(j->unit); + } + + hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id)); + j->installed = false; + } + + /* Detach from next 'smaller' objects */ + manager_transaction_unlink_job(j->manager, j, true); + + if (j->in_run_queue) + LIST_REMOVE(Job, run_queue, j->manager->run_queue, j); + + if (j->in_dbus_queue) + LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j); + + if (j->timer_watch.type != WATCH_INVALID) { + assert(j->timer_watch.type == WATCH_JOB_TIMER); + assert(j->timer_watch.data.job == j); + assert(j->timer_watch.fd >= 0); + + assert_se(epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_DEL, j->timer_watch.fd, NULL) >= 0); + close_nointr_nofail(j->timer_watch.fd); + } + + free(j->bus_client); + free(j); +} + +JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) { + JobDependency *l; + + assert(object); + + /* Adds a new job link, which encodes that the 'subject' job + * needs the 'object' job in some way. If 'subject' is NULL + * this means the 'anchor' job (i.e. the one the user + * explicitly asked for) is the requester. */ + + if (!(l = new0(JobDependency, 1))) + return NULL; + + l->subject = subject; + l->object = object; + l->matters = matters; + l->conflicts = conflicts; + + if (subject) + LIST_PREPEND(JobDependency, subject, subject->subject_list, l); + else + LIST_PREPEND(JobDependency, subject, object->manager->transaction_anchor, l); + + LIST_PREPEND(JobDependency, object, object->object_list, l); + + return l; +} + +void job_dependency_free(JobDependency *l) { + assert(l); + + if (l->subject) + LIST_REMOVE(JobDependency, subject, l->subject->subject_list, l); + else + LIST_REMOVE(JobDependency, subject, l->object->manager->transaction_anchor, l); + + LIST_REMOVE(JobDependency, object, l->object->object_list, l); + + free(l); +} + +void job_dump(Job *j, FILE*f, const char *prefix) { + assert(j); + assert(f); + + if (!prefix) + prefix = ""; + + fprintf(f, + "%s-> Job %u:\n" + "%s\tAction: %s -> %s\n" + "%s\tState: %s\n" + "%s\tForced: %s\n", + prefix, j->id, + prefix, j->unit->id, job_type_to_string(j->type), + prefix, job_state_to_string(j->state), + prefix, yes_no(j->override)); +} + +bool job_is_anchor(Job *j) { + JobDependency *l; + + assert(j); + + LIST_FOREACH(object, l, j->object_list) + if (!l->subject) + return true; + + return false; +} + +static bool types_match(JobType a, JobType b, JobType c, JobType d) { + return + (a == c && b == d) || + (a == d && b == c); +} + +int job_type_merge(JobType *a, JobType b) { + if (*a == b) + return 0; + + /* Merging is associative! a merged with b merged with c is + * the same as a merged with c merged with b. */ + + /* Mergeability is transitive! if a can be merged with b and b + * with c then a also with c */ + + /* Also, if a merged with b cannot be merged with c, then + * either a or b cannot be merged with c either */ + + if (types_match(*a, b, JOB_START, JOB_VERIFY_ACTIVE)) + *a = JOB_START; + else if (types_match(*a, b, JOB_START, JOB_RELOAD) || + types_match(*a, b, JOB_START, JOB_RELOAD_OR_START) || + types_match(*a, b, JOB_VERIFY_ACTIVE, JOB_RELOAD_OR_START) || + types_match(*a, b, JOB_RELOAD, JOB_RELOAD_OR_START)) + *a = JOB_RELOAD_OR_START; + else if (types_match(*a, b, JOB_START, JOB_RESTART) || + types_match(*a, b, JOB_START, JOB_TRY_RESTART) || + types_match(*a, b, JOB_VERIFY_ACTIVE, JOB_RESTART) || + types_match(*a, b, JOB_RELOAD, JOB_RESTART) || + types_match(*a, b, JOB_RELOAD_OR_START, JOB_RESTART) || + types_match(*a, b, JOB_RELOAD_OR_START, JOB_TRY_RESTART) || + types_match(*a, b, JOB_RESTART, JOB_TRY_RESTART)) + *a = JOB_RESTART; + else if (types_match(*a, b, JOB_VERIFY_ACTIVE, JOB_RELOAD)) + *a = JOB_RELOAD; + else if (types_match(*a, b, JOB_VERIFY_ACTIVE, JOB_TRY_RESTART) || + types_match(*a, b, JOB_RELOAD, JOB_TRY_RESTART)) + *a = JOB_TRY_RESTART; + else + return -EEXIST; + + return 0; +} + +bool job_type_is_mergeable(JobType a, JobType b) { + return job_type_merge(&a, b) >= 0; +} + +bool job_type_is_superset(JobType a, JobType b) { + + /* Checks whether operation a is a "superset" of b in its + * actions */ + + if (a == b) + return true; + + switch (a) { + case JOB_START: + return b == JOB_VERIFY_ACTIVE; + + case JOB_RELOAD: + return + b == JOB_VERIFY_ACTIVE; + + case JOB_RELOAD_OR_START: + return + b == JOB_RELOAD || + b == JOB_START || + b == JOB_VERIFY_ACTIVE; + + case JOB_RESTART: + return + b == JOB_START || + b == JOB_VERIFY_ACTIVE || + b == JOB_RELOAD || + b == JOB_RELOAD_OR_START || + b == JOB_TRY_RESTART; + + case JOB_TRY_RESTART: + return + b == JOB_VERIFY_ACTIVE || + b == JOB_RELOAD; + default: + return false; + + } +} + +bool job_type_is_conflicting(JobType a, JobType b) { + assert(a >= 0 && a < _JOB_TYPE_MAX); + assert(b >= 0 && b < _JOB_TYPE_MAX); + + return (a == JOB_STOP) != (b == JOB_STOP); +} + +bool job_type_is_redundant(JobType a, UnitActiveState b) { + switch (a) { + + case JOB_START: + return + b == UNIT_ACTIVE || + b == UNIT_RELOADING; + + case JOB_STOP: + return + b == UNIT_INACTIVE || + b == UNIT_FAILED; + + case JOB_VERIFY_ACTIVE: + return + b == UNIT_ACTIVE || + b == UNIT_RELOADING; + + case JOB_RELOAD: + return + b == UNIT_RELOADING; + + case JOB_RELOAD_OR_START: + return + b == UNIT_ACTIVATING || + b == UNIT_RELOADING; + + case JOB_RESTART: + return + b == UNIT_ACTIVATING; + + case JOB_TRY_RESTART: + return + b == UNIT_ACTIVATING; + + default: + assert_not_reached("Invalid job type"); + } +} + +bool job_is_runnable(Job *j) { + Iterator i; + Unit *other; + + assert(j); + assert(j->installed); + + /* Checks whether there is any job running for the units this + * job needs to be running after (in the case of a 'positive' + * job type) or before (in the case of a 'negative' job + * type. */ + + /* First check if there is an override */ + if (j->ignore_order) + return true; + + if (j->type == JOB_START || + j->type == JOB_VERIFY_ACTIVE || + j->type == JOB_RELOAD || + j->type == JOB_RELOAD_OR_START) { + + /* Immediate result is that the job is or might be + * started. In this case lets wait for the + * dependencies, regardless whether they are + * starting or stopping something. */ + + SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i) + if (other->job) + return false; + } + + /* Also, if something else is being stopped and we should + * change state after it, then lets wait. */ + + SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i) + if (other->job && + (other->job->type == JOB_STOP || + other->job->type == JOB_RESTART || + other->job->type == JOB_TRY_RESTART)) + return false; + + /* This means that for a service a and a service b where b + * shall be started after a: + * + * start a + start b → 1st step start a, 2nd step start b + * start a + stop b → 1st step stop b, 2nd step start a + * stop a + start b → 1st step stop a, 2nd step start b + * stop a + stop b → 1st step stop b, 2nd step stop a + * + * This has the side effect that restarts are properly + * synchronized too. */ + + return true; +} + +int job_run_and_invalidate(Job *j) { + int r; + uint32_t id; + Manager *m; + + assert(j); + assert(j->installed); + + if (j->in_run_queue) { + LIST_REMOVE(Job, run_queue, j->manager->run_queue, j); + j->in_run_queue = false; + } + + if (j->state != JOB_WAITING) + return 0; + + if (!job_is_runnable(j)) + return -EAGAIN; + + j->state = JOB_RUNNING; + job_add_to_dbus_queue(j); + + /* While we execute this operation the job might go away (for + * example: because it is replaced by a new, conflicting + * job.) To make sure we don't access a freed job later on we + * store the id here, so that we can verify the job is still + * valid. */ + id = j->id; + m = j->manager; + + switch (j->type) { + + case JOB_START: + r = unit_start(j->unit); + + /* If this unit cannot be started, then simply + * wait */ + if (r == -EBADR) + r = 0; + + break; + + case JOB_VERIFY_ACTIVE: { + UnitActiveState t = unit_active_state(j->unit); + if (UNIT_IS_ACTIVE_OR_RELOADING(t)) + r = -EALREADY; + else if (t == UNIT_ACTIVATING) + r = -EAGAIN; + else + r = -ENOEXEC; + break; + } + + case JOB_STOP: + r = unit_stop(j->unit); + + /* If this unit cannot stopped, then simply + * wait. */ + if (r == -EBADR) + r = 0; + break; + + case JOB_RELOAD: + r = unit_reload(j->unit); + break; + + case JOB_RELOAD_OR_START: + if (unit_active_state(j->unit) == UNIT_ACTIVE) { + j->type = JOB_RELOAD; + r = unit_reload(j->unit); + } else { + j->type = JOB_START; + r = unit_start(j->unit); + + if (r == -EBADR) + r = 0; + } + break; + + case JOB_RESTART: { + UnitActiveState t = unit_active_state(j->unit); + if (t == UNIT_INACTIVE || t == UNIT_FAILED || t == UNIT_ACTIVATING) { + j->type = JOB_START; + r = unit_start(j->unit); + } else + r = unit_stop(j->unit); + break; + } + + case JOB_TRY_RESTART: { + UnitActiveState t = unit_active_state(j->unit); + if (t == UNIT_INACTIVE || t == UNIT_FAILED || t == UNIT_DEACTIVATING) + r = -ENOEXEC; + else if (t == UNIT_ACTIVATING) { + j->type = JOB_START; + r = unit_start(j->unit); + } else { + j->type = JOB_RESTART; + r = unit_stop(j->unit); + } + break; + } + + default: + assert_not_reached("Unknown job type"); + } + + if ((j = manager_get_job(m, id))) { + if (r == -EALREADY) + r = job_finish_and_invalidate(j, JOB_DONE); + else if (r == -ENOEXEC) + r = job_finish_and_invalidate(j, JOB_SKIPPED); + else if (r == -EAGAIN) + j->state = JOB_WAITING; + else if (r < 0) + r = job_finish_and_invalidate(j, JOB_FAILED); + } + + return r; +} + +static void job_print_status_message(Unit *u, JobType t, JobResult result) { + assert(u); + + if (t == JOB_START) { + + switch (result) { + + case JOB_DONE: + unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, "Started %s", unit_description(u)); + break; + + case JOB_FAILED: + unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, "Failed to start %s", unit_description(u)); + unit_status_printf(u, NULL, "See 'systemctl status %s' for details.", u->id); + break; + + case JOB_DEPENDENCY: + unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " ABORT" ANSI_HIGHLIGHT_OFF, "Dependency failed. Aborted start of %s", unit_description(u)); + break; + + case JOB_TIMEOUT: + unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out starting %s", unit_description(u)); + break; + + default: + ; + } + + } else if (t == JOB_STOP) { + + switch (result) { + + case JOB_TIMEOUT: + unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out stopping %s", unit_description(u)); + break; + + case JOB_DONE: + case JOB_FAILED: + unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, "Stopped %s", unit_description(u)); + break; + + default: + ; + } + } +} + +int job_finish_and_invalidate(Job *j, JobResult result) { + Unit *u; + Unit *other; + JobType t; + Iterator i; + bool recursed = false; + + assert(j); + assert(j->installed); + + job_add_to_dbus_queue(j); + + /* Patch restart jobs so that they become normal start jobs */ + if (result == JOB_DONE && (j->type == JOB_RESTART || j->type == JOB_TRY_RESTART)) { + + log_debug("Converting job %s/%s -> %s/%s", + j->unit->id, job_type_to_string(j->type), + j->unit->id, job_type_to_string(JOB_START)); + + j->state = JOB_WAITING; + j->type = JOB_START; + + job_add_to_run_queue(j); + + u = j->unit; + goto finish; + } + + j->result = result; + + log_debug("Job %s/%s finished, result=%s", j->unit->id, job_type_to_string(j->type), job_result_to_string(result)); + + if (result == JOB_FAILED) + j->manager->n_failed_jobs ++; + + u = j->unit; + t = j->type; + job_free(j); + + job_print_status_message(u, t, result); + + /* Fail depending jobs on failure */ + if (result != JOB_DONE) { + + if (t == JOB_START || + t == JOB_VERIFY_ACTIVE || + t == JOB_RELOAD_OR_START) { + + SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i) + if (other->job && + (other->job->type == JOB_START || + other->job->type == JOB_VERIFY_ACTIVE || + other->job->type == JOB_RELOAD_OR_START)) { + job_finish_and_invalidate(other->job, JOB_DEPENDENCY); + recursed = true; + } + + SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i) + if (other->job && + (other->job->type == JOB_START || + other->job->type == JOB_VERIFY_ACTIVE || + other->job->type == JOB_RELOAD_OR_START)) { + job_finish_and_invalidate(other->job, JOB_DEPENDENCY); + recursed = true; + } + + SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i) + if (other->job && + !other->job->override && + (other->job->type == JOB_START || + other->job->type == JOB_VERIFY_ACTIVE || + other->job->type == JOB_RELOAD_OR_START)) { + job_finish_and_invalidate(other->job, JOB_DEPENDENCY); + recursed = true; + } + + } else if (t == JOB_STOP) { + + SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i) + if (other->job && + (other->job->type == JOB_START || + other->job->type == JOB_VERIFY_ACTIVE || + other->job->type == JOB_RELOAD_OR_START)) { + job_finish_and_invalidate(other->job, JOB_DEPENDENCY); + recursed = true; + } + } + } + + /* Trigger OnFailure dependencies that are not generated by + * the unit itself. We don't tread JOB_CANCELED as failure in + * this context. And JOB_FAILURE is already handled by the + * unit itself. */ + if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) { + log_notice("Job %s/%s failed with result '%s'.", + u->id, + job_type_to_string(t), + job_result_to_string(result)); + + unit_trigger_on_failure(u); + } + +finish: + /* Try to start the next jobs that can be started */ + SET_FOREACH(other, u->dependencies[UNIT_AFTER], i) + if (other->job) + job_add_to_run_queue(other->job); + SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i) + if (other->job) + job_add_to_run_queue(other->job); + + manager_check_finished(u->manager); + + return recursed; +} + +int job_start_timer(Job *j) { + struct itimerspec its; + struct epoll_event ev; + int fd, r; + assert(j); + + if (j->unit->job_timeout <= 0 || + j->timer_watch.type == WATCH_JOB_TIMER) + return 0; + + assert(j->timer_watch.type == WATCH_INVALID); + + if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) { + r = -errno; + goto fail; + } + + zero(its); + timespec_store(&its.it_value, j->unit->job_timeout); + + if (timerfd_settime(fd, 0, &its, NULL) < 0) { + r = -errno; + goto fail; + } + + zero(ev); + ev.data.ptr = &j->timer_watch; + ev.events = EPOLLIN; + + if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) { + r = -errno; + goto fail; + } + + j->timer_watch.type = WATCH_JOB_TIMER; + j->timer_watch.fd = fd; + j->timer_watch.data.job = j; + + return 0; + +fail: + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +void job_add_to_run_queue(Job *j) { + assert(j); + assert(j->installed); + + if (j->in_run_queue) + return; + + LIST_PREPEND(Job, run_queue, j->manager->run_queue, j); + j->in_run_queue = true; +} + +void job_add_to_dbus_queue(Job *j) { + assert(j); + assert(j->installed); + + if (j->in_dbus_queue) + return; + + /* We don't check if anybody is subscribed here, since this + * job might just have been created and not yet assigned to a + * connection/client. */ + + LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j); + j->in_dbus_queue = true; +} + +char *job_dbus_path(Job *j) { + char *p; + + assert(j); + + if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0) + return NULL; + + return p; +} + +void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w) { + assert(j); + assert(w == &j->timer_watch); + + log_warning("Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type)); + job_finish_and_invalidate(j, JOB_TIMEOUT); +} + +static const char* const job_state_table[_JOB_STATE_MAX] = { + [JOB_WAITING] = "waiting", + [JOB_RUNNING] = "running" +}; + +DEFINE_STRING_TABLE_LOOKUP(job_state, JobState); + +static const char* const job_type_table[_JOB_TYPE_MAX] = { + [JOB_START] = "start", + [JOB_VERIFY_ACTIVE] = "verify-active", + [JOB_STOP] = "stop", + [JOB_RELOAD] = "reload", + [JOB_RELOAD_OR_START] = "reload-or-start", + [JOB_RESTART] = "restart", + [JOB_TRY_RESTART] = "try-restart", +}; + +DEFINE_STRING_TABLE_LOOKUP(job_type, JobType); + +static const char* const job_mode_table[_JOB_MODE_MAX] = { + [JOB_FAIL] = "fail", + [JOB_REPLACE] = "replace", + [JOB_ISOLATE] = "isolate", + [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies", + [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements" +}; + +DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode); + +static const char* const job_result_table[_JOB_RESULT_MAX] = { + [JOB_DONE] = "done", + [JOB_CANCELED] = "canceled", + [JOB_TIMEOUT] = "timeout", + [JOB_FAILED] = "failed", + [JOB_DEPENDENCY] = "dependency", + [JOB_SKIPPED] = "skipped" +}; + +DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult); diff --git a/src/job.h b/src/job.h new file mode 100644 index 0000000..2121426 --- /dev/null +++ b/src/job.h @@ -0,0 +1,179 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foojobhfoo +#define foojobhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +typedef struct Job Job; +typedef struct JobDependency JobDependency; +typedef enum JobType JobType; +typedef enum JobState JobState; +typedef enum JobMode JobMode; +typedef enum JobResult JobResult; + +#include "manager.h" +#include "unit.h" +#include "hashmap.h" +#include "list.h" + +enum JobType { + JOB_START, /* if a unit does not support being started, we'll just wait until it becomes active */ + JOB_VERIFY_ACTIVE, + + JOB_STOP, + + JOB_RELOAD, /* if running reload */ + JOB_RELOAD_OR_START, /* if running reload, if not running start */ + + /* Note that restarts are first treated like JOB_STOP, but + * then instead of finishing are patched to become + * JOB_START. */ + JOB_RESTART, /* if running stop, then start unconditionally */ + JOB_TRY_RESTART, /* if running stop and then start */ + + _JOB_TYPE_MAX, + _JOB_TYPE_INVALID = -1 +}; + +enum JobState { + JOB_WAITING, + JOB_RUNNING, + _JOB_STATE_MAX, + _JOB_STATE_INVALID = -1 +}; + +enum JobMode { + JOB_FAIL, /* Fail if a conflicting job is already queued */ + JOB_REPLACE, /* Replace an existing conflicting job */ + JOB_ISOLATE, /* Start a unit, and stop all others */ + JOB_IGNORE_DEPENDENCIES, /* Ignore both requirement and ordering dependencies */ + JOB_IGNORE_REQUIREMENTS, /* Ignore requirement dependencies */ + _JOB_MODE_MAX, + _JOB_MODE_INVALID = -1 +}; + +enum JobResult { + JOB_DONE, + JOB_CANCELED, + JOB_TIMEOUT, + JOB_FAILED, + JOB_DEPENDENCY, + JOB_SKIPPED, + _JOB_RESULT_MAX, + _JOB_RESULT_INVALID = -1 +}; + +struct JobDependency { + /* Encodes that the 'subject' job needs the 'object' job in + * some way. This structure is used only while building a transaction. */ + Job *subject; + Job *object; + + LIST_FIELDS(JobDependency, subject); + LIST_FIELDS(JobDependency, object); + + bool matters; + bool conflicts; +}; + +struct Job { + Manager *manager; + Unit *unit; + + LIST_FIELDS(Job, transaction); + LIST_FIELDS(Job, run_queue); + LIST_FIELDS(Job, dbus_queue); + + LIST_HEAD(JobDependency, subject_list); + LIST_HEAD(JobDependency, object_list); + + /* Used for graph algs as a "I have been here" marker */ + Job* marker; + unsigned generation; + + uint32_t id; + + JobType type; + JobState state; + + Watch timer_watch; + + /* Note that this bus object is not ref counted here. */ + DBusConnection *bus; + char *bus_client; + + JobResult result; + + bool installed:1; + bool in_run_queue:1; + bool matters_to_anchor:1; + bool override:1; + bool in_dbus_queue:1; + bool sent_dbus_new_signal:1; + bool ignore_order:1; +}; + +Job* job_new(Manager *m, JobType type, Unit *unit); +void job_free(Job *job); +void job_dump(Job *j, FILE*f, const char *prefix); + +JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts); +void job_dependency_free(JobDependency *l); + +bool job_is_anchor(Job *j); + +int job_merge(Job *j, Job *other); + +int job_type_merge(JobType *a, JobType b); +bool job_type_is_mergeable(JobType a, JobType b); +bool job_type_is_superset(JobType a, JobType b); +bool job_type_is_conflicting(JobType a, JobType b); +bool job_type_is_redundant(JobType a, UnitActiveState b); + +bool job_is_runnable(Job *j); + +void job_add_to_run_queue(Job *j); +void job_add_to_dbus_queue(Job *j); + +int job_start_timer(Job *j); +void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w); + +int job_run_and_invalidate(Job *j); +int job_finish_and_invalidate(Job *j, JobResult result); + +char *job_dbus_path(Job *j); + +const char* job_type_to_string(JobType t); +JobType job_type_from_string(const char *s); + +const char* job_state_to_string(JobState t); +JobState job_state_from_string(const char *s); + +const char* job_mode_to_string(JobMode t); +JobMode job_mode_from_string(const char *s); + +const char* job_result_to_string(JobResult t); +JobResult job_result_from_string(const char *s); + +#endif diff --git a/src/journal/cat.c b/src/journal/cat.c new file mode 100644 index 0000000..6745f1c --- /dev/null +++ b/src/journal/cat.c @@ -0,0 +1,181 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "util.h" +#include "build.h" + +static char *arg_identifier = NULL; +static char arg_priority = LOG_INFO; +static bool arg_level_prefix = true; + +static int help(void) { + + printf("%s [OPTIONS...] {COMMAND} ...\n\n" + "Execute process with stdout/stderr connected to the journal.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " -t --identifier=STRING Set syslog identifier\n" + " -p --priority=PRIORITY Set priority value (0..7)\n" + " --level-prefix=BOOL Control whether level prefix shall be parsed\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + ARG_LEVEL_PREFIX + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version" , no_argument, NULL, ARG_VERSION }, + { "identifier", required_argument, NULL, 't' }, + { "priority", required_argument, NULL, 'p' }, + { "level-prefix", required_argument, NULL, ARG_LEVEL_PREFIX }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "+ht:p:", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(DISTRIBUTION); + puts(SYSTEMD_FEATURES); + return 0; + + case 't': + free(arg_identifier); + if (isempty(optarg)) + arg_identifier = NULL; + else { + arg_identifier = strdup(optarg); + if (!arg_identifier) { + log_error("Out of memory."); + return -ENOMEM; + } + } + break; + + case 'p': + arg_priority = log_level_from_string(optarg); + if (arg_priority < 0) { + log_error("Failed to parse priority value."); + return arg_priority; + } + break; + + case ARG_LEVEL_PREFIX: { + int k; + + k = parse_boolean(optarg); + if (k < 0) { + log_error("Failed to parse level prefix value."); + return k; + } + arg_level_prefix = k; + break; + } + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +int main(int argc, char *argv[]) { + int r, fd = -1, saved_stderr = -1; + + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r <= 0) + goto finish; + + fd = sd_journal_stream_fd(arg_identifier, arg_priority, arg_level_prefix); + if (fd < 0) { + log_error("Failed to create stream fd: %s", strerror(fd)); + r = fd; + goto finish; + } + + saved_stderr = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 3); + + if (dup3(fd, STDOUT_FILENO, 0) < 0 || + dup3(fd, STDERR_FILENO, 0) < 0) { + log_error("Failed to duplicate fd: %s", strerror(fd)); + r = -errno; + goto finish; + } + + if (fd >= 3) + close_nointr_nofail(fd); + + fd = -1; + + if (argc <= optind) + execl("/bin/cat", "/bin/cat", NULL); + else + execvp(argv[optind], argv + optind); + + /* Let's try to restore a working stderr, so we can print the error message */ + if (saved_stderr >= 0) + dup3(saved_stderr, STDERR_FILENO, 0); + + log_error("Failed to execute process: %m"); + r = -errno; + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + if (saved_stderr >= 0) + close_nointr_nofail(saved_stderr); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/journal/compress.c b/src/journal/compress.c new file mode 100644 index 0000000..ff90658 --- /dev/null +++ b/src/journal/compress.c @@ -0,0 +1,208 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "compress.h" + +bool compress_blob(const void *src, uint64_t src_size, void *dst, uint64_t *dst_size) { + lzma_stream s = LZMA_STREAM_INIT; + lzma_ret ret; + bool b = false; + + assert(src); + assert(src_size > 0); + assert(dst); + assert(dst_size); + + /* Returns false if we couldn't compress the data or the + * compressed result is longer than the original */ + + ret = lzma_easy_encoder(&s, LZMA_PRESET_DEFAULT, LZMA_CHECK_NONE); + if (ret != LZMA_OK) + return false; + + s.next_in = src; + s.avail_in = src_size; + s.next_out = dst; + s.avail_out = src_size; + + /* Does it fit? */ + if (lzma_code(&s, LZMA_FINISH) != LZMA_STREAM_END) + goto fail; + + /* Is it actually shorter? */ + if (s.avail_out == 0) + goto fail; + + *dst_size = src_size - s.avail_out; + b = true; + +fail: + lzma_end(&s); + + return b; +} + +bool uncompress_blob(const void *src, uint64_t src_size, + void **dst, uint64_t *dst_alloc_size, uint64_t* dst_size) { + + lzma_stream s = LZMA_STREAM_INIT; + lzma_ret ret; + bool b = false; + + assert(src); + assert(src_size > 0); + assert(dst); + assert(dst_alloc_size); + assert(dst_size); + assert(*dst_alloc_size == 0 || *dst); + + ret = lzma_stream_decoder(&s, UINT64_MAX, 0); + if (ret != LZMA_OK) + return false; + + if (*dst_alloc_size <= src_size) { + void *p; + + p = realloc(*dst, src_size*2); + if (!p) + return false; + + *dst = p; + *dst_alloc_size = src_size*2; + } + + s.next_in = src; + s.avail_in = src_size; + + s.next_out = *dst; + s.avail_out = *dst_alloc_size; + + for (;;) { + void *p; + + ret = lzma_code(&s, LZMA_FINISH); + + if (ret == LZMA_STREAM_END) + break; + + if (ret != LZMA_OK) + goto fail; + + p = realloc(*dst, *dst_alloc_size*2); + if (!p) + goto fail; + + s.next_out = (uint8_t*) p + ((uint8_t*) s.next_out - (uint8_t*) *dst); + s.avail_out += *dst_alloc_size; + + *dst = p; + *dst_alloc_size *= 2; + } + + *dst_size = *dst_alloc_size - s.avail_out; + b = true; + +fail: + lzma_end(&s); + + return b; +} + +bool uncompress_startswith(const void *src, uint64_t src_size, + void **buffer, uint64_t *buffer_size, + const void *prefix, uint64_t prefix_len, + uint8_t extra) { + + lzma_stream s = LZMA_STREAM_INIT; + lzma_ret ret; + bool b = false; + + /* Checks whether the uncompressed blob starts with the + * mentioned prefix. The byte extra needs to follow the + * prefix */ + + assert(src); + assert(src_size > 0); + assert(buffer); + assert(buffer_size); + assert(prefix); + assert(*buffer_size == 0 || *buffer); + + ret = lzma_stream_decoder(&s, UINT64_MAX, 0); + if (ret != LZMA_OK) + return false; + + if (*buffer_size <= prefix_len) { + void *p; + + p = realloc(*buffer, prefix_len*2); + if (!p) + return false; + + *buffer = p; + *buffer_size = prefix_len*2; + } + + s.next_in = src; + s.avail_in = src_size; + + s.next_out = *buffer; + s.avail_out = *buffer_size; + + for (;;) { + void *p; + + ret = lzma_code(&s, LZMA_FINISH); + + if (ret != LZMA_STREAM_END && ret != LZMA_OK) + goto fail; + + if ((*buffer_size - s.avail_out > prefix_len) && + memcmp(*buffer, prefix, prefix_len) == 0 && + ((const uint8_t*) *buffer)[prefix_len] == extra) + break; + + if (ret == LZMA_STREAM_END) + goto fail; + + p = realloc(*buffer, *buffer_size*2); + if (!p) + goto fail; + + s.next_out = (uint8_t*) p + ((uint8_t*) s.next_out - (uint8_t*) *buffer); + s.avail_out += *buffer_size; + + *buffer = p; + *buffer_size *= 2; + } + + b = true; + +fail: + lzma_end(&s); + + return b; +} diff --git a/src/journal/compress.h b/src/journal/compress.h new file mode 100644 index 0000000..f187a6e --- /dev/null +++ b/src/journal/compress.h @@ -0,0 +1,38 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foocompresshfoo +#define foocompresshfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +bool compress_blob(const void *src, uint64_t src_size, void *dst, uint64_t *dst_size); + +bool uncompress_blob(const void *src, uint64_t src_size, + void **dst, uint64_t *dst_alloc_size, uint64_t* dst_size); + +bool uncompress_startswith(const void *src, uint64_t src_size, + void **buffer, uint64_t *buffer_size, + const void *prefix, uint64_t prefix_len, + uint8_t extra); + +#endif diff --git a/src/journal/coredump.c b/src/journal/coredump.c new file mode 100644 index 0000000..7dea66e --- /dev/null +++ b/src/journal/coredump.c @@ -0,0 +1,271 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include +#include + +#include "log.h" +#include "util.h" +#include "special.h" + +#define COREDUMP_MAX (24*1024*1024) + +enum { + ARG_PID = 1, + ARG_UID, + ARG_GID, + ARG_SIGNAL, + ARG_TIMESTAMP, + ARG_COMM, + _ARG_MAX +}; + +static int divert_coredump(void) { + FILE *f; + int r; + + log_info("Detected coredump of the journal daemon itself, diverting coredump to /var/lib/systemd/coredump/."); + + mkdir_p("/var/lib/systemd/coredump", 0755); + + f = fopen("/var/lib/systemd/coredump/core.systemd-journald", "we"); + if (!f) { + log_error("Failed to create coredump file: %m"); + return -errno; + } + + for (;;) { + uint8_t buffer[4096]; + size_t l, q; + + l = fread(buffer, 1, sizeof(buffer), stdin); + if (l <= 0) { + if (ferror(f)) { + log_error("Failed to read coredump: %m"); + r = -errno; + goto finish; + } + + r = 0; + break; + } + + q = fwrite(buffer, 1, l, f); + if (q != l) { + log_error("Failed to write coredump: %m"); + r = -errno; + goto finish; + } + } + + fflush(f); + + if (ferror(f)) { + log_error("Failed to write coredump: %m"); + r = -errno; + } + +finish: + fclose(f); + return r; +} + +int main(int argc, char* argv[]) { + int r, j = 0; + char *p = NULL; + ssize_t n; + pid_t pid; + uid_t uid; + gid_t gid; + struct iovec iovec[14]; + char *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL, + *core_timestamp = NULL, *core_comm = NULL, *core_exe = NULL, *core_unit = NULL, + *core_session = NULL, *core_message = NULL, *core_cmdline = NULL, *t; + + prctl(PR_SET_DUMPABLE, 0); + + if (argc != _ARG_MAX) { + log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); + log_open(); + + log_error("Invalid number of arguments passed from kernel."); + r = -EINVAL; + goto finish; + } + + r = parse_pid(argv[ARG_PID], &pid); + if (r < 0) { + log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); + log_open(); + + log_error("Failed to parse PID."); + goto finish; + } + + if (sd_pid_get_unit(pid, &t) >= 0) { + + if (streq(t, SPECIAL_JOURNALD_SERVICE)) { + /* Make sure we don't make use of the journal, + * if it's the journal which is crashing */ + log_set_target(LOG_TARGET_KMSG); + log_open(); + + r = divert_coredump(); + goto finish; + } + + core_unit = strappend("COREDUMP_UNIT=", t); + free(t); + + if (core_unit) + IOVEC_SET_STRING(iovec[j++], core_unit); + } + + /* OK, now we know it's not the journal, hence make use of + * it */ + log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); + log_open(); + + r = parse_uid(argv[ARG_UID], &uid); + if (r < 0) { + log_error("Failed to parse UID."); + goto finish; + } + + r = parse_gid(argv[ARG_GID], &gid); + if (r < 0) { + log_error("Failed to parse GID."); + goto finish; + } + + core_pid = strappend("COREDUMP_PID=", argv[ARG_PID]); + if (core_pid) + IOVEC_SET_STRING(iovec[j++], core_pid); + + core_uid = strappend("COREDUMP_UID=", argv[ARG_UID]); + if (core_uid) + IOVEC_SET_STRING(iovec[j++], core_uid); + + core_gid = strappend("COREDUMP_GID=", argv[ARG_GID]); + if (core_gid) + IOVEC_SET_STRING(iovec[j++], core_gid); + + core_signal = strappend("COREDUMP_SIGNAL=", argv[ARG_SIGNAL]); + if (core_signal) + IOVEC_SET_STRING(iovec[j++], core_signal); + + core_comm = strappend("COREDUMP_COMM=", argv[ARG_COMM]); + if (core_comm) + IOVEC_SET_STRING(iovec[j++], core_comm); + + if (sd_pid_get_session(pid, &t) >= 0) { + core_session = strappend("COREDUMP_SESSION=", t); + free(t); + + if (core_session) + IOVEC_SET_STRING(iovec[j++], core_session); + } + + if (get_process_exe(pid, &t) >= 0) { + core_exe = strappend("COREDUMP_EXE=", t); + free(t); + + if (core_exe) + IOVEC_SET_STRING(iovec[j++], core_exe); + } + + if (get_process_cmdline(pid, LINE_MAX, false, &t) >= 0) { + core_cmdline = strappend("COREDUMP_CMDLINE=", t); + free(t); + + if (core_cmdline) + IOVEC_SET_STRING(iovec[j++], core_cmdline); + } + + core_timestamp = join("COREDUMP_TIMESTAMP=", argv[ARG_TIMESTAMP], "000000", NULL); + if (core_timestamp) + IOVEC_SET_STRING(iovec[j++], core_timestamp); + + IOVEC_SET_STRING(iovec[j++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1"); + IOVEC_SET_STRING(iovec[j++], "PRIORITY=2"); + + core_message = join("MESSAGE=Process ", argv[ARG_PID], " (", argv[ARG_COMM], ") dumped core.", NULL); + if (core_message) + IOVEC_SET_STRING(iovec[j++], core_message); + + /* Now, let's drop privileges to become the user who owns the + * segfaulted process and allocate the coredump memory under + * his uid. This also ensures that the credentials journald + * will see are the ones of the coredumping user, thus making + * sure the user himself gets access to the core dump. */ + + if (setresgid(gid, gid, gid) < 0 || + setresuid(uid, uid, uid) < 0) { + log_error("Failed to drop privileges: %m"); + r = -errno; + goto finish; + } + + p = malloc(9 + COREDUMP_MAX); + if (!p) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + memcpy(p, "COREDUMP=", 9); + + n = loop_read(STDIN_FILENO, p + 9, COREDUMP_MAX, false); + if (n < 0) { + log_error("Failed to read core dump data: %s", strerror(-n)); + r = (int) n; + goto finish; + } + + iovec[j].iov_base = p; + iovec[j].iov_len = 9 + n; + j++; + + r = sd_journal_sendv(iovec, j); + if (r < 0) + log_error("Failed to send coredump: %s", strerror(-r)); + +finish: + free(p); + free(core_pid); + free(core_uid); + free(core_gid); + free(core_signal); + free(core_timestamp); + free(core_comm); + free(core_exe); + free(core_cmdline); + free(core_unit); + free(core_session); + free(core_message); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/journal/journal-def.h b/src/journal/journal-def.h new file mode 100644 index 0000000..964e0c2 --- /dev/null +++ b/src/journal/journal-def.h @@ -0,0 +1,165 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foojournaldefhfoo +#define foojournaldefhfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include + +#include "macro.h" + +typedef struct Header Header; +typedef struct ObjectHeader ObjectHeader; +typedef union Object Object; +typedef struct DataObject DataObject; +typedef struct FieldObject FieldObject; +typedef struct EntryObject EntryObject; +typedef struct HashTableObject HashTableObject; +typedef struct EntryArrayObject EntryArrayObject; +typedef struct EntryItem EntryItem; +typedef struct HashItem HashItem; + +/* Object types */ +enum { + OBJECT_UNUSED, + OBJECT_DATA, + OBJECT_FIELD, + OBJECT_ENTRY, + OBJECT_DATA_HASH_TABLE, + OBJECT_FIELD_HASH_TABLE, + OBJECT_ENTRY_ARRAY, + _OBJECT_TYPE_MAX +}; + +/* Object flags */ +enum { + OBJECT_COMPRESSED = 1 +}; + +_packed_ struct ObjectHeader { + uint8_t type; + uint8_t flags; + uint8_t reserved[6]; + uint64_t size; + uint8_t payload[]; +}; + +_packed_ struct DataObject { + ObjectHeader object; + uint64_t hash; + uint64_t next_hash_offset; + uint64_t next_field_offset; + uint64_t entry_offset; /* the first array entry we store inline */ + uint64_t entry_array_offset; + uint64_t n_entries; + uint8_t payload[]; +}; + +_packed_ struct FieldObject { + ObjectHeader object; + uint64_t hash; + uint64_t next_hash_offset; + uint64_t head_data_offset; + uint64_t tail_data_offset; + uint8_t payload[]; +}; + +_packed_ struct EntryItem { + uint64_t object_offset; + uint64_t hash; +}; + +_packed_ struct EntryObject { + ObjectHeader object; + uint64_t seqnum; + uint64_t realtime; + uint64_t monotonic; + sd_id128_t boot_id; + uint64_t xor_hash; + EntryItem items[]; +}; + +_packed_ struct HashItem { + uint64_t head_hash_offset; + uint64_t tail_hash_offset; +}; + +_packed_ struct HashTableObject { + ObjectHeader object; + HashItem items[]; +}; + +_packed_ struct EntryArrayObject { + ObjectHeader object; + uint64_t next_entry_array_offset; + uint64_t items[]; +}; + +union Object { + ObjectHeader object; + DataObject data; + FieldObject field; + EntryObject entry; + HashTableObject hash_table; + EntryArrayObject entry_array; +}; + +enum { + STATE_OFFLINE, + STATE_ONLINE, + STATE_ARCHIVED +}; + +/* Header flags */ +enum { + HEADER_INCOMPATIBLE_COMPRESSED = 1 +}; + +_packed_ struct Header { + uint8_t signature[8]; /* "LPKSHHRH" */ + uint32_t compatible_flags; + uint32_t incompatible_flags; + uint8_t state; + uint8_t reserved[7]; + sd_id128_t file_id; + sd_id128_t machine_id; + sd_id128_t boot_id; + sd_id128_t seqnum_id; + uint64_t arena_offset; + uint64_t arena_size; + uint64_t data_hash_table_offset; /* for looking up data objects */ + uint64_t data_hash_table_size; + uint64_t field_hash_table_offset; /* for looking up field objects */ + uint64_t field_hash_table_size; + uint64_t tail_object_offset; + uint64_t n_objects; + uint64_t n_entries; + uint64_t seqnum; + uint64_t first_seqnum; + uint64_t entry_array_offset; + uint64_t head_entry_realtime; + uint64_t tail_entry_realtime; + uint64_t tail_entry_monotonic; +}; + +#endif diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c new file mode 100644 index 0000000..20ca3f6 --- /dev/null +++ b/src/journal/journal-file.c @@ -0,0 +1,2176 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "journal-def.h" +#include "journal-file.h" +#include "lookup3.h" +#include "compress.h" + +#define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*16ULL) +#define DEFAULT_FIELD_HASH_TABLE_SIZE (2047ULL*16ULL) + +#define DEFAULT_WINDOW_SIZE (128ULL*1024ULL*1024ULL) + +#define COMPRESSION_SIZE_THRESHOLD (512ULL) + +/* This is the minimum journal file size */ +#define JOURNAL_FILE_SIZE_MIN (64ULL*1024ULL) + +/* These are the lower and upper bounds if we deduce the max_use value + * from the file system size */ +#define DEFAULT_MAX_USE_LOWER (1ULL*1024ULL*1024ULL) /* 1 MiB */ +#define DEFAULT_MAX_USE_UPPER (4ULL*1024ULL*1024ULL*1024ULL) /* 4 GiB */ + +/* This is the upper bound if we deduce max_size from max_use */ +#define DEFAULT_MAX_SIZE_UPPER (16ULL*1024ULL*1024ULL) /* 16 MiB */ + +/* This is the upper bound if we deduce the keep_free value from the + * file system size */ +#define DEFAULT_KEEP_FREE_UPPER (4ULL*1024ULL*1024ULL*1024ULL) /* 4 GiB */ + +/* This is the keep_free value when we can't determine the system + * size */ +#define DEFAULT_KEEP_FREE (1024ULL*1024ULL) /* 1 MB */ + +static const char signature[] = { 'L', 'P', 'K', 'S', 'H', 'H', 'R', 'H' }; + +#define ALIGN64(x) (((x) + 7ULL) & ~7ULL) + +void journal_file_close(JournalFile *f) { + int t; + + assert(f); + + if (f->header && f->writable) + f->header->state = STATE_OFFLINE; + + + for (t = 0; t < _WINDOW_MAX; t++) + if (f->windows[t].ptr) + munmap(f->windows[t].ptr, f->windows[t].size); + + if (f->fd >= 0) + close_nointr_nofail(f->fd); + + free(f->path); + +#ifdef HAVE_XZ + free(f->compress_buffer); +#endif + + free(f); +} + +static int journal_file_init_header(JournalFile *f, JournalFile *template) { + Header h; + ssize_t k; + int r; + + assert(f); + + zero(h); + memcpy(h.signature, signature, 8); + h.arena_offset = htole64(ALIGN64(sizeof(h))); + + r = sd_id128_randomize(&h.file_id); + if (r < 0) + return r; + + if (template) { + h.seqnum_id = template->header->seqnum_id; + h.seqnum = template->header->seqnum; + } else + h.seqnum_id = h.file_id; + + k = pwrite(f->fd, &h, sizeof(h), 0); + if (k < 0) + return -errno; + + if (k != sizeof(h)) + return -EIO; + + return 0; +} + +static int journal_file_refresh_header(JournalFile *f) { + int r; + sd_id128_t boot_id; + + assert(f); + + r = sd_id128_get_machine(&f->header->machine_id); + if (r < 0) + return r; + + r = sd_id128_get_boot(&boot_id); + if (r < 0) + return r; + + if (sd_id128_equal(boot_id, f->header->boot_id)) + f->tail_entry_monotonic_valid = true; + + f->header->boot_id = boot_id; + + f->header->state = STATE_ONLINE; + + __sync_synchronize(); + + return 0; +} + +static int journal_file_verify_header(JournalFile *f) { + assert(f); + + if (memcmp(f->header, signature, 8)) + return -EBADMSG; + +#ifdef HAVE_XZ + if ((le64toh(f->header->incompatible_flags) & ~HEADER_INCOMPATIBLE_COMPRESSED) != 0) + return -EPROTONOSUPPORT; +#else + if (f->header->incompatible_flags != 0) + return -EPROTONOSUPPORT; +#endif + + if ((uint64_t) f->last_stat.st_size < (le64toh(f->header->arena_offset) + le64toh(f->header->arena_size))) + return -ENODATA; + + if (f->writable) { + uint32_t state; + sd_id128_t machine_id; + int r; + + r = sd_id128_get_machine(&machine_id); + if (r < 0) + return r; + + if (!sd_id128_equal(machine_id, f->header->machine_id)) + return -EHOSTDOWN; + + state = f->header->state; + + if (state == STATE_ONLINE) + log_debug("Journal file %s is already online. Assuming unclean closing. Ignoring.", f->path); + else if (state == STATE_ARCHIVED) + return -ESHUTDOWN; + else if (state != STATE_OFFLINE) + log_debug("Journal file %s has unknown state %u. Ignoring.", f->path, state); + } + + return 0; +} + +static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size) { + uint64_t old_size, new_size; + + assert(f); + + /* We assume that this file is not sparse, and we know that + * for sure, since we always call posix_fallocate() + * ourselves */ + + old_size = + le64toh(f->header->arena_offset) + + le64toh(f->header->arena_size); + + new_size = PAGE_ALIGN(offset + size); + if (new_size < le64toh(f->header->arena_offset)) + new_size = le64toh(f->header->arena_offset); + + if (new_size <= old_size) + return 0; + + if (f->metrics.max_size > 0 && + new_size > f->metrics.max_size) + return -E2BIG; + + if (new_size > f->metrics.min_size && + f->metrics.keep_free > 0) { + struct statvfs svfs; + + if (fstatvfs(f->fd, &svfs) >= 0) { + uint64_t available; + + available = svfs.f_bfree * svfs.f_bsize; + + if (available >= f->metrics.keep_free) + available -= f->metrics.keep_free; + else + available = 0; + + if (new_size - old_size > available) + return -E2BIG; + } + } + + /* Note that the glibc fallocate() fallback is very + inefficient, hence we try to minimize the allocation area + as we can. */ + if (posix_fallocate(f->fd, old_size, new_size - old_size) < 0) + return -errno; + + if (fstat(f->fd, &f->last_stat) < 0) + return -errno; + + f->header->arena_size = new_size - htole64(f->header->arena_offset); + + return 0; +} + +static int journal_file_map( + JournalFile *f, + uint64_t offset, + uint64_t size, + void **_window, + uint64_t *_woffset, + uint64_t *_wsize, + void **ret) { + + uint64_t woffset, wsize; + void *window; + + assert(f); + assert(size > 0); + assert(ret); + + woffset = offset & ~((uint64_t) page_size() - 1ULL); + wsize = size + (offset - woffset); + wsize = PAGE_ALIGN(wsize); + + /* Avoid SIGBUS on invalid accesses */ + if (woffset + wsize > (uint64_t) PAGE_ALIGN(f->last_stat.st_size)) + return -EADDRNOTAVAIL; + + window = mmap(NULL, wsize, f->prot, MAP_SHARED, f->fd, woffset); + if (window == MAP_FAILED) + return -errno; + + if (_window) + *_window = window; + + if (_woffset) + *_woffset = woffset; + + if (_wsize) + *_wsize = wsize; + + *ret = (uint8_t*) window + (offset - woffset); + + return 0; +} + +static int journal_file_move_to(JournalFile *f, int wt, uint64_t offset, uint64_t size, void **ret) { + void *p = NULL; + uint64_t delta; + int r; + Window *w; + + assert(f); + assert(ret); + assert(wt >= 0); + assert(wt < _WINDOW_MAX); + + if (offset + size > (uint64_t) f->last_stat.st_size) { + /* Hmm, out of range? Let's refresh the fstat() data + * first, before we trust that check. */ + + if (fstat(f->fd, &f->last_stat) < 0 || + offset + size > (uint64_t) f->last_stat.st_size) + return -EADDRNOTAVAIL; + } + + w = f->windows + wt; + + if (_likely_(w->ptr && + w->offset <= offset && + w->offset + w->size >= offset + size)) { + + *ret = (uint8_t*) w->ptr + (offset - w->offset); + return 0; + } + + if (w->ptr) { + if (munmap(w->ptr, w->size) < 0) + return -errno; + + w->ptr = NULL; + w->size = w->offset = 0; + } + + if (size < DEFAULT_WINDOW_SIZE) { + /* If the default window size is larger then what was + * asked for extend the mapping a bit in the hope to + * minimize needed remappings later on. We add half + * the window space before and half behind the + * requested mapping */ + + delta = (DEFAULT_WINDOW_SIZE - size) / 2; + + if (delta > offset) + delta = offset; + + offset -= delta; + size = DEFAULT_WINDOW_SIZE; + } else + delta = 0; + + if (offset + size > (uint64_t) f->last_stat.st_size) + size = (uint64_t) f->last_stat.st_size - offset; + + if (size <= 0) + return -EADDRNOTAVAIL; + + r = journal_file_map(f, + offset, size, + &w->ptr, &w->offset, &w->size, + &p); + + if (r < 0) + return r; + + *ret = (uint8_t*) p + delta; + return 0; +} + +static bool verify_hash(Object *o) { + uint64_t h1, h2; + + assert(o); + + if (o->object.type == OBJECT_DATA && !(o->object.flags & OBJECT_COMPRESSED)) { + h1 = le64toh(o->data.hash); + h2 = hash64(o->data.payload, le64toh(o->object.size) - offsetof(Object, data.payload)); + } else if (o->object.type == OBJECT_FIELD) { + h1 = le64toh(o->field.hash); + h2 = hash64(o->field.payload, le64toh(o->object.size) - offsetof(Object, field.payload)); + } else + return true; + + return h1 == h2; +} + +int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret) { + int r; + void *t; + Object *o; + uint64_t s; + + assert(f); + assert(ret); + assert(type < _OBJECT_TYPE_MAX); + + r = journal_file_move_to(f, type >= 0 ? type : WINDOW_UNKNOWN, offset, sizeof(ObjectHeader), &t); + if (r < 0) + return r; + + o = (Object*) t; + s = le64toh(o->object.size); + + if (s < sizeof(ObjectHeader)) + return -EBADMSG; + + if (type >= 0 && o->object.type != type) + return -EBADMSG; + + if (s > sizeof(ObjectHeader)) { + r = journal_file_move_to(f, o->object.type, offset, s, &t); + if (r < 0) + return r; + + o = (Object*) t; + } + + if (!verify_hash(o)) + return -EBADMSG; + + *ret = o; + return 0; +} + +static uint64_t journal_file_seqnum(JournalFile *f, uint64_t *seqnum) { + uint64_t r; + + assert(f); + + r = le64toh(f->header->seqnum) + 1; + + if (seqnum) { + /* If an external seqnum counter was passed, we update + * both the local and the external one, and set it to + * the maximum of both */ + + if (*seqnum + 1 > r) + r = *seqnum + 1; + + *seqnum = r; + } + + f->header->seqnum = htole64(r); + + if (f->header->first_seqnum == 0) + f->header->first_seqnum = htole64(r); + + return r; +} + +static int journal_file_append_object(JournalFile *f, int type, uint64_t size, Object **ret, uint64_t *offset) { + int r; + uint64_t p; + Object *tail, *o; + void *t; + + assert(f); + assert(size >= sizeof(ObjectHeader)); + assert(offset); + assert(ret); + + p = le64toh(f->header->tail_object_offset); + if (p == 0) + p = le64toh(f->header->arena_offset); + else { + r = journal_file_move_to_object(f, -1, p, &tail); + if (r < 0) + return r; + + p += ALIGN64(le64toh(tail->object.size)); + } + + r = journal_file_allocate(f, p, size); + if (r < 0) + return r; + + r = journal_file_move_to(f, type, p, size, &t); + if (r < 0) + return r; + + o = (Object*) t; + + zero(o->object); + o->object.type = type; + o->object.size = htole64(size); + + f->header->tail_object_offset = htole64(p); + f->header->n_objects = htole64(le64toh(f->header->n_objects) + 1); + + *ret = o; + *offset = p; + + return 0; +} + +static int journal_file_setup_data_hash_table(JournalFile *f) { + uint64_t s, p; + Object *o; + int r; + + assert(f); + + s = DEFAULT_DATA_HASH_TABLE_SIZE; + r = journal_file_append_object(f, + OBJECT_DATA_HASH_TABLE, + offsetof(Object, hash_table.items) + s, + &o, &p); + if (r < 0) + return r; + + memset(o->hash_table.items, 0, s); + + f->header->data_hash_table_offset = htole64(p + offsetof(Object, hash_table.items)); + f->header->data_hash_table_size = htole64(s); + + return 0; +} + +static int journal_file_setup_field_hash_table(JournalFile *f) { + uint64_t s, p; + Object *o; + int r; + + assert(f); + + s = DEFAULT_FIELD_HASH_TABLE_SIZE; + r = journal_file_append_object(f, + OBJECT_FIELD_HASH_TABLE, + offsetof(Object, hash_table.items) + s, + &o, &p); + if (r < 0) + return r; + + memset(o->hash_table.items, 0, s); + + f->header->field_hash_table_offset = htole64(p + offsetof(Object, hash_table.items)); + f->header->field_hash_table_size = htole64(s); + + return 0; +} + +static int journal_file_map_data_hash_table(JournalFile *f) { + uint64_t s, p; + void *t; + int r; + + assert(f); + + p = le64toh(f->header->data_hash_table_offset); + s = le64toh(f->header->data_hash_table_size); + + r = journal_file_move_to(f, + WINDOW_DATA_HASH_TABLE, + p, s, + &t); + if (r < 0) + return r; + + f->data_hash_table = t; + return 0; +} + +static int journal_file_map_field_hash_table(JournalFile *f) { + uint64_t s, p; + void *t; + int r; + + assert(f); + + p = le64toh(f->header->field_hash_table_offset); + s = le64toh(f->header->field_hash_table_size); + + r = journal_file_move_to(f, + WINDOW_FIELD_HASH_TABLE, + p, s, + &t); + if (r < 0) + return r; + + f->field_hash_table = t; + return 0; +} + +static int journal_file_link_data(JournalFile *f, Object *o, uint64_t offset, uint64_t hash) { + uint64_t p, h; + int r; + + assert(f); + assert(o); + assert(offset > 0); + assert(o->object.type == OBJECT_DATA); + + o->data.next_hash_offset = o->data.next_field_offset = 0; + o->data.entry_offset = o->data.entry_array_offset = 0; + o->data.n_entries = 0; + + h = hash % (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)); + p = le64toh(f->data_hash_table[h].head_hash_offset); + if (p == 0) { + /* Only entry in the hash table is easy */ + f->data_hash_table[h].head_hash_offset = htole64(offset); + } else { + /* Temporarily move back to the previous data object, + * to patch in pointer */ + + r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); + if (r < 0) + return r; + + o->data.next_hash_offset = htole64(offset); + + r = journal_file_move_to_object(f, OBJECT_DATA, offset, &o); + if (r < 0) + return r; + } + + f->data_hash_table[h].tail_hash_offset = htole64(offset); + + return 0; +} + +int journal_file_find_data_object_with_hash( + JournalFile *f, + const void *data, uint64_t size, uint64_t hash, + Object **ret, uint64_t *offset) { + uint64_t p, osize, h; + int r; + + assert(f); + assert(data || size == 0); + + osize = offsetof(Object, data.payload) + size; + + if (f->header->data_hash_table_size == 0) + return -EBADMSG; + + h = hash % (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)); + p = le64toh(f->data_hash_table[h].head_hash_offset); + + while (p > 0) { + Object *o; + + r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); + if (r < 0) + return r; + + if (le64toh(o->data.hash) != hash) + goto next; + + if (o->object.flags & OBJECT_COMPRESSED) { +#ifdef HAVE_XZ + uint64_t l, rsize; + + l = le64toh(o->object.size); + if (l <= offsetof(Object, data.payload)) + return -EBADMSG; + + l -= offsetof(Object, data.payload); + + if (!uncompress_blob(o->data.payload, l, &f->compress_buffer, &f->compress_buffer_size, &rsize)) + return -EBADMSG; + + if (rsize == size && + memcmp(f->compress_buffer, data, size) == 0) { + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + return 1; + } +#else + return -EPROTONOSUPPORT; +#endif + + } else if (le64toh(o->object.size) == osize && + memcmp(o->data.payload, data, size) == 0) { + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + return 1; + } + + next: + p = le64toh(o->data.next_hash_offset); + } + + return 0; +} + +int journal_file_find_data_object( + JournalFile *f, + const void *data, uint64_t size, + Object **ret, uint64_t *offset) { + + uint64_t hash; + + assert(f); + assert(data || size == 0); + + hash = hash64(data, size); + + return journal_file_find_data_object_with_hash(f, + data, size, hash, + ret, offset); +} + +static int journal_file_append_data(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset) { + uint64_t hash, p; + uint64_t osize; + Object *o; + int r; + bool compressed = false; + + assert(f); + assert(data || size == 0); + + hash = hash64(data, size); + + r = journal_file_find_data_object_with_hash(f, data, size, hash, &o, &p); + if (r < 0) + return r; + else if (r > 0) { + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + return 0; + } + + osize = offsetof(Object, data.payload) + size; + r = journal_file_append_object(f, OBJECT_DATA, osize, &o, &p); + if (r < 0) + return r; + + o->data.hash = htole64(hash); + +#ifdef HAVE_XZ + if (f->compress && + size >= COMPRESSION_SIZE_THRESHOLD) { + uint64_t rsize; + + compressed = compress_blob(data, size, o->data.payload, &rsize); + + if (compressed) { + o->object.size = htole64(offsetof(Object, data.payload) + rsize); + o->object.flags |= OBJECT_COMPRESSED; + + f->header->incompatible_flags = htole32(le32toh(f->header->incompatible_flags) | HEADER_INCOMPATIBLE_COMPRESSED); + + log_debug("Compressed data object %lu -> %lu", (unsigned long) size, (unsigned long) rsize); + } + } +#endif + + if (!compressed) + memcpy(o->data.payload, data, size); + + r = journal_file_link_data(f, o, p, hash); + if (r < 0) + return r; + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + return 0; +} + +uint64_t journal_file_entry_n_items(Object *o) { + assert(o); + assert(o->object.type == htole64(OBJECT_ENTRY)); + + return (le64toh(o->object.size) - offsetof(Object, entry.items)) / sizeof(EntryItem); +} + +static uint64_t journal_file_entry_array_n_items(Object *o) { + assert(o); + assert(o->object.type == htole64(OBJECT_ENTRY_ARRAY)); + + return (le64toh(o->object.size) - offsetof(Object, entry_array.items)) / sizeof(uint64_t); +} + +static int link_entry_into_array(JournalFile *f, + uint64_t *first, + uint64_t *idx, + uint64_t p) { + int r; + uint64_t n = 0, ap = 0, q, i, a, hidx; + Object *o; + + assert(f); + assert(first); + assert(idx); + assert(p > 0); + + a = le64toh(*first); + i = hidx = le64toh(*idx); + while (a > 0) { + + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o); + if (r < 0) + return r; + + n = journal_file_entry_array_n_items(o); + if (i < n) { + o->entry_array.items[i] = htole64(p); + *idx = htole64(hidx + 1); + return 0; + } + + i -= n; + ap = a; + a = le64toh(o->entry_array.next_entry_array_offset); + } + + if (hidx > n) + n = (hidx+1) * 2; + else + n = n * 2; + + if (n < 4) + n = 4; + + r = journal_file_append_object(f, OBJECT_ENTRY_ARRAY, + offsetof(Object, entry_array.items) + n * sizeof(uint64_t), + &o, &q); + if (r < 0) + return r; + + o->entry_array.items[i] = htole64(p); + + if (ap == 0) + *first = q; + else { + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, ap, &o); + if (r < 0) + return r; + + o->entry_array.next_entry_array_offset = htole64(q); + } + + *idx = htole64(hidx + 1); + + return 0; +} + +static int link_entry_into_array_plus_one(JournalFile *f, + uint64_t *extra, + uint64_t *first, + uint64_t *idx, + uint64_t p) { + + int r; + + assert(f); + assert(extra); + assert(first); + assert(idx); + assert(p > 0); + + if (*idx == 0) + *extra = htole64(p); + else { + uint64_t i; + + i = le64toh(*idx) - 1; + r = link_entry_into_array(f, first, &i, p); + if (r < 0) + return r; + } + + *idx = htole64(le64toh(*idx) + 1); + return 0; +} + +static int journal_file_link_entry_item(JournalFile *f, Object *o, uint64_t offset, uint64_t i) { + uint64_t p; + int r; + assert(f); + assert(o); + assert(offset > 0); + + p = le64toh(o->entry.items[i].object_offset); + if (p == 0) + return -EINVAL; + + r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); + if (r < 0) + return r; + + return link_entry_into_array_plus_one(f, + &o->data.entry_offset, + &o->data.entry_array_offset, + &o->data.n_entries, + offset); +} + +static int journal_file_link_entry(JournalFile *f, Object *o, uint64_t offset) { + uint64_t n, i; + int r; + + assert(f); + assert(o); + assert(offset > 0); + assert(o->object.type == OBJECT_ENTRY); + + __sync_synchronize(); + + /* Link up the entry itself */ + r = link_entry_into_array(f, + &f->header->entry_array_offset, + &f->header->n_entries, + offset); + if (r < 0) + return r; + + /* log_debug("=> %s seqnr=%lu n_entries=%lu", f->path, (unsigned long) o->entry.seqnum, (unsigned long) f->header->n_entries); */ + + if (f->header->head_entry_realtime == 0) + f->header->head_entry_realtime = o->entry.realtime; + + f->header->tail_entry_realtime = o->entry.realtime; + f->header->tail_entry_monotonic = o->entry.monotonic; + + f->tail_entry_monotonic_valid = true; + + /* Link up the items */ + n = journal_file_entry_n_items(o); + for (i = 0; i < n; i++) { + r = journal_file_link_entry_item(f, o, offset, i); + if (r < 0) + return r; + } + + return 0; +} + +static int journal_file_append_entry_internal( + JournalFile *f, + const dual_timestamp *ts, + uint64_t xor_hash, + const EntryItem items[], unsigned n_items, + uint64_t *seqnum, + Object **ret, uint64_t *offset) { + uint64_t np; + uint64_t osize; + Object *o; + int r; + + assert(f); + assert(items || n_items == 0); + assert(ts); + + osize = offsetof(Object, entry.items) + (n_items * sizeof(EntryItem)); + + r = journal_file_append_object(f, OBJECT_ENTRY, osize, &o, &np); + if (r < 0) + return r; + + o->entry.seqnum = htole64(journal_file_seqnum(f, seqnum)); + memcpy(o->entry.items, items, n_items * sizeof(EntryItem)); + o->entry.realtime = htole64(ts->realtime); + o->entry.monotonic = htole64(ts->monotonic); + o->entry.xor_hash = htole64(xor_hash); + o->entry.boot_id = f->header->boot_id; + + r = journal_file_link_entry(f, o, np); + if (r < 0) + return r; + + if (ret) + *ret = o; + + if (offset) + *offset = np; + + return 0; +} + +void journal_file_post_change(JournalFile *f) { + assert(f); + + /* inotify() does not receive IN_MODIFY events from file + * accesses done via mmap(). After each access we hence + * trigger IN_MODIFY by truncating the journal file to its + * current size which triggers IN_MODIFY. */ + + __sync_synchronize(); + + if (ftruncate(f->fd, f->last_stat.st_size) < 0) + log_error("Failed to to truncate file to its own size: %m"); +} + +int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const struct iovec iovec[], unsigned n_iovec, uint64_t *seqnum, Object **ret, uint64_t *offset) { + unsigned i; + EntryItem *items; + int r; + uint64_t xor_hash = 0; + struct dual_timestamp _ts; + + assert(f); + assert(iovec || n_iovec == 0); + + if (!f->writable) + return -EPERM; + + if (!ts) { + dual_timestamp_get(&_ts); + ts = &_ts; + } + + if (f->tail_entry_monotonic_valid && + ts->monotonic < le64toh(f->header->tail_entry_monotonic)) + return -EINVAL; + + items = alloca(sizeof(EntryItem) * n_iovec); + + for (i = 0; i < n_iovec; i++) { + uint64_t p; + Object *o; + + r = journal_file_append_data(f, iovec[i].iov_base, iovec[i].iov_len, &o, &p); + if (r < 0) + return r; + + xor_hash ^= le64toh(o->data.hash); + items[i].object_offset = htole64(p); + items[i].hash = o->data.hash; + } + + r = journal_file_append_entry_internal(f, ts, xor_hash, items, n_iovec, seqnum, ret, offset); + + journal_file_post_change(f); + + return r; +} + +static int generic_array_get(JournalFile *f, + uint64_t first, + uint64_t i, + Object **ret, uint64_t *offset) { + + Object *o; + uint64_t p = 0, a; + int r; + + assert(f); + + a = first; + while (a > 0) { + uint64_t n; + + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o); + if (r < 0) + return r; + + n = journal_file_entry_array_n_items(o); + if (i < n) { + p = le64toh(o->entry_array.items[i]); + break; + } + + i -= n; + a = le64toh(o->entry_array.next_entry_array_offset); + } + + if (a <= 0 || p <= 0) + return 0; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o); + if (r < 0) + return r; + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + return 1; +} + +static int generic_array_get_plus_one(JournalFile *f, + uint64_t extra, + uint64_t first, + uint64_t i, + Object **ret, uint64_t *offset) { + + Object *o; + + assert(f); + + if (i == 0) { + int r; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, extra, &o); + if (r < 0) + return r; + + if (ret) + *ret = o; + + if (offset) + *offset = extra; + + return 1; + } + + return generic_array_get(f, first, i-1, ret, offset); +} + +enum { + TEST_FOUND, + TEST_LEFT, + TEST_RIGHT +}; + +static int generic_array_bisect(JournalFile *f, + uint64_t first, + uint64_t n, + uint64_t needle, + int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle), + direction_t direction, + Object **ret, + uint64_t *offset, + uint64_t *idx) { + + uint64_t a, p, t = 0, i = 0, last_p = 0; + bool subtract_one = false; + Object *o, *array = NULL; + int r; + + assert(f); + assert(test_object); + + a = first; + while (a > 0) { + uint64_t left, right, k, lp; + + r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &array); + if (r < 0) + return r; + + k = journal_file_entry_array_n_items(array); + right = MIN(k, n); + if (right <= 0) + return 0; + + i = right - 1; + lp = p = le64toh(array->entry_array.items[i]); + if (p <= 0) + return -EBADMSG; + + r = test_object(f, p, needle); + if (r < 0) + return r; + + if (r == TEST_FOUND) + r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT; + + if (r == TEST_RIGHT) { + left = 0; + right -= 1; + for (;;) { + if (left == right) { + if (direction == DIRECTION_UP) + subtract_one = true; + + i = left; + goto found; + } + + assert(left < right); + + i = (left + right) / 2; + p = le64toh(array->entry_array.items[i]); + if (p <= 0) + return -EBADMSG; + + r = test_object(f, p, needle); + if (r < 0) + return r; + + if (r == TEST_FOUND) + r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT; + + if (r == TEST_RIGHT) + right = i; + else + left = i + 1; + } + } + + if (k > n) + return 0; + + last_p = lp; + + n -= k; + t += k; + a = le64toh(array->entry_array.next_entry_array_offset); + } + + return 0; + +found: + if (subtract_one && t == 0 && i == 0) + return 0; + + if (subtract_one && i == 0) + p = last_p; + else if (subtract_one) + p = le64toh(array->entry_array.items[i-1]); + else + p = le64toh(array->entry_array.items[i]); + + r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o); + if (r < 0) + return r; + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + if (idx) + *idx = t + i - (subtract_one ? 1 : 0); + + return 1; +} + +static int generic_array_bisect_plus_one(JournalFile *f, + uint64_t extra, + uint64_t first, + uint64_t n, + uint64_t needle, + int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle), + direction_t direction, + Object **ret, + uint64_t *offset, + uint64_t *idx) { + + int r; + + assert(f); + assert(test_object); + + if (n <= 0) + return 0; + + /* This bisects the array in object 'first', but first checks + * an extra */ + r = test_object(f, extra, needle); + if (r < 0) + return r; + else if (r == TEST_FOUND) { + Object *o; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, extra, &o); + if (r < 0) + return r; + + if (ret) + *ret = o; + + if (offset) + *offset = extra; + + if (idx) + *idx = 0; + + return 1; + } else if (r == TEST_RIGHT) + return 0; + + r = generic_array_bisect(f, first, n-1, needle, test_object, direction, ret, offset, idx); + + if (r > 0) + (*idx) ++; + + return r; +} + +static int test_object_seqnum(JournalFile *f, uint64_t p, uint64_t needle) { + Object *o; + int r; + + assert(f); + assert(p > 0); + + r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o); + if (r < 0) + return r; + + if (le64toh(o->entry.seqnum) == needle) + return TEST_FOUND; + else if (le64toh(o->entry.seqnum) < needle) + return TEST_LEFT; + else + return TEST_RIGHT; +} + +int journal_file_move_to_entry_by_seqnum( + JournalFile *f, + uint64_t seqnum, + direction_t direction, + Object **ret, + uint64_t *offset) { + + return generic_array_bisect(f, + le64toh(f->header->entry_array_offset), + le64toh(f->header->n_entries), + seqnum, + test_object_seqnum, + direction, + ret, offset, NULL); +} + +static int test_object_realtime(JournalFile *f, uint64_t p, uint64_t needle) { + Object *o; + int r; + + assert(f); + assert(p > 0); + + r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o); + if (r < 0) + return r; + + if (le64toh(o->entry.realtime) == needle) + return TEST_FOUND; + else if (le64toh(o->entry.realtime) < needle) + return TEST_LEFT; + else + return TEST_RIGHT; +} + +int journal_file_move_to_entry_by_realtime( + JournalFile *f, + uint64_t realtime, + direction_t direction, + Object **ret, + uint64_t *offset) { + + return generic_array_bisect(f, + le64toh(f->header->entry_array_offset), + le64toh(f->header->n_entries), + realtime, + test_object_realtime, + direction, + ret, offset, NULL); +} + +static int test_object_monotonic(JournalFile *f, uint64_t p, uint64_t needle) { + Object *o; + int r; + + assert(f); + assert(p > 0); + + r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o); + if (r < 0) + return r; + + if (le64toh(o->entry.monotonic) == needle) + return TEST_FOUND; + else if (le64toh(o->entry.monotonic) < needle) + return TEST_LEFT; + else + return TEST_RIGHT; +} + +int journal_file_move_to_entry_by_monotonic( + JournalFile *f, + sd_id128_t boot_id, + uint64_t monotonic, + direction_t direction, + Object **ret, + uint64_t *offset) { + + char t[8+32+1] = "_BOOT_ID="; + Object *o; + int r; + + sd_id128_to_string(boot_id, t + 8); + + r = journal_file_find_data_object(f, t, strlen(t), &o, NULL); + if (r < 0) + return r; + else if (r == 0) + return -ENOENT; + + return generic_array_bisect_plus_one(f, + le64toh(o->data.entry_offset), + le64toh(o->data.entry_array_offset), + le64toh(o->data.n_entries), + monotonic, + test_object_monotonic, + direction, + ret, offset, NULL); +} + +static int test_object_offset(JournalFile *f, uint64_t p, uint64_t needle) { + assert(f); + assert(p > 0); + + if (p == needle) + return TEST_FOUND; + else if (p < needle) + return TEST_LEFT; + else + return TEST_RIGHT; +} + +int journal_file_next_entry( + JournalFile *f, + Object *o, uint64_t p, + direction_t direction, + Object **ret, uint64_t *offset) { + + uint64_t i, n; + int r; + + assert(f); + assert(p > 0 || !o); + + n = le64toh(f->header->n_entries); + if (n <= 0) + return 0; + + if (!o) + i = direction == DIRECTION_DOWN ? 0 : n - 1; + else { + if (o->object.type != OBJECT_ENTRY) + return -EINVAL; + + r = generic_array_bisect(f, + le64toh(f->header->entry_array_offset), + le64toh(f->header->n_entries), + p, + test_object_offset, + DIRECTION_DOWN, + NULL, NULL, + &i); + if (r <= 0) + return r; + + if (direction == DIRECTION_DOWN) { + if (i >= n - 1) + return 0; + + i++; + } else { + if (i <= 0) + return 0; + + i--; + } + } + + /* And jump to it */ + return generic_array_get(f, + le64toh(f->header->entry_array_offset), + i, + ret, offset); +} + +int journal_file_skip_entry( + JournalFile *f, + Object *o, uint64_t p, + int64_t skip, + Object **ret, uint64_t *offset) { + + uint64_t i, n; + int r; + + assert(f); + assert(o); + assert(p > 0); + + if (o->object.type != OBJECT_ENTRY) + return -EINVAL; + + r = generic_array_bisect(f, + le64toh(f->header->entry_array_offset), + le64toh(f->header->n_entries), + p, + test_object_offset, + DIRECTION_DOWN, + NULL, NULL, + &i); + if (r <= 0) + return r; + + /* Calculate new index */ + if (skip < 0) { + if ((uint64_t) -skip >= i) + i = 0; + else + i = i - (uint64_t) -skip; + } else + i += (uint64_t) skip; + + n = le64toh(f->header->n_entries); + if (n <= 0) + return -EBADMSG; + + if (i >= n) + i = n-1; + + return generic_array_get(f, + le64toh(f->header->entry_array_offset), + i, + ret, offset); +} + +int journal_file_next_entry_for_data( + JournalFile *f, + Object *o, uint64_t p, + uint64_t data_offset, + direction_t direction, + Object **ret, uint64_t *offset) { + + uint64_t n, i; + int r; + Object *d; + + assert(f); + assert(p > 0 || !o); + + r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d); + if (r < 0) + return r; + + n = le64toh(d->data.n_entries); + if (n <= 0) + return n; + + if (!o) + i = direction == DIRECTION_DOWN ? 0 : n - 1; + else { + if (o->object.type != OBJECT_ENTRY) + return -EINVAL; + + r = generic_array_bisect_plus_one(f, + le64toh(d->data.entry_offset), + le64toh(d->data.entry_array_offset), + le64toh(d->data.n_entries), + p, + test_object_offset, + DIRECTION_DOWN, + NULL, NULL, + &i); + + if (r <= 0) + return r; + + if (direction == DIRECTION_DOWN) { + if (i >= n - 1) + return 0; + + i++; + } else { + if (i <= 0) + return 0; + + i--; + } + + } + + return generic_array_get_plus_one(f, + le64toh(d->data.entry_offset), + le64toh(d->data.entry_array_offset), + i, + ret, offset); +} + +int journal_file_move_to_entry_by_seqnum_for_data( + JournalFile *f, + uint64_t data_offset, + uint64_t seqnum, + direction_t direction, + Object **ret, uint64_t *offset) { + + Object *d; + int r; + + r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d); + if (r <= 0) + return r; + + return generic_array_bisect_plus_one(f, + le64toh(d->data.entry_offset), + le64toh(d->data.entry_array_offset), + le64toh(d->data.n_entries), + seqnum, + test_object_seqnum, + direction, + ret, offset, NULL); +} + +int journal_file_move_to_entry_by_realtime_for_data( + JournalFile *f, + uint64_t data_offset, + uint64_t realtime, + direction_t direction, + Object **ret, uint64_t *offset) { + + Object *d; + int r; + + r = journal_file_move_to_object(f, OBJECT_DATA, data_offset, &d); + if (r <= 0) + return r; + + return generic_array_bisect_plus_one(f, + le64toh(d->data.entry_offset), + le64toh(d->data.entry_array_offset), + le64toh(d->data.n_entries), + realtime, + test_object_realtime, + direction, + ret, offset, NULL); +} + +void journal_file_dump(JournalFile *f) { + char a[33], b[33], c[33]; + Object *o; + int r; + uint64_t p; + + assert(f); + + printf("File Path: %s\n" + "File ID: %s\n" + "Machine ID: %s\n" + "Boot ID: %s\n" + "Arena size: %llu\n" + "Objects: %lu\n" + "Entries: %lu\n", + f->path, + sd_id128_to_string(f->header->file_id, a), + sd_id128_to_string(f->header->machine_id, b), + sd_id128_to_string(f->header->boot_id, c), + (unsigned long long) le64toh(f->header->arena_size), + (unsigned long) le64toh(f->header->n_objects), + (unsigned long) le64toh(f->header->n_entries)); + + p = le64toh(f->header->arena_offset); + while (p != 0) { + r = journal_file_move_to_object(f, -1, p, &o); + if (r < 0) + goto fail; + + switch (o->object.type) { + + case OBJECT_UNUSED: + printf("Type: OBJECT_UNUSED\n"); + break; + + case OBJECT_DATA: + printf("Type: OBJECT_DATA\n"); + break; + + case OBJECT_ENTRY: + printf("Type: OBJECT_ENTRY %llu %llu %llu\n", + (unsigned long long) le64toh(o->entry.seqnum), + (unsigned long long) le64toh(o->entry.monotonic), + (unsigned long long) le64toh(o->entry.realtime)); + break; + + case OBJECT_FIELD_HASH_TABLE: + printf("Type: OBJECT_FIELD_HASH_TABLE\n"); + break; + + case OBJECT_DATA_HASH_TABLE: + printf("Type: OBJECT_DATA_HASH_TABLE\n"); + break; + + case OBJECT_ENTRY_ARRAY: + printf("Type: OBJECT_ENTRY_ARRAY\n"); + break; + } + + if (o->object.flags & OBJECT_COMPRESSED) + printf("Flags: COMPRESSED\n"); + + if (p == le64toh(f->header->tail_object_offset)) + p = 0; + else + p = p + ALIGN64(le64toh(o->object.size)); + } + + return; +fail: + log_error("File corrupt"); +} + +int journal_file_open( + const char *fname, + int flags, + mode_t mode, + JournalFile *template, + JournalFile **ret) { + + JournalFile *f; + int r; + bool newly_created = false; + + assert(fname); + + if ((flags & O_ACCMODE) != O_RDONLY && + (flags & O_ACCMODE) != O_RDWR) + return -EINVAL; + + f = new0(JournalFile, 1); + if (!f) + return -ENOMEM; + + f->fd = -1; + f->flags = flags; + f->mode = mode; + f->writable = (flags & O_ACCMODE) != O_RDONLY; + f->prot = prot_from_flags(flags); + + f->path = strdup(fname); + if (!f->path) { + r = -ENOMEM; + goto fail; + } + + f->fd = open(f->path, f->flags|O_CLOEXEC, f->mode); + if (f->fd < 0) { + r = -errno; + goto fail; + } + + if (fstat(f->fd, &f->last_stat) < 0) { + r = -errno; + goto fail; + } + + if (f->last_stat.st_size == 0 && f->writable) { + newly_created = true; + + r = journal_file_init_header(f, template); + if (r < 0) + goto fail; + + if (fstat(f->fd, &f->last_stat) < 0) { + r = -errno; + goto fail; + } + } + + if (f->last_stat.st_size < (off_t) sizeof(Header)) { + r = -EIO; + goto fail; + } + + f->header = mmap(NULL, PAGE_ALIGN(sizeof(Header)), prot_from_flags(flags), MAP_SHARED, f->fd, 0); + if (f->header == MAP_FAILED) { + f->header = NULL; + r = -errno; + goto fail; + } + + if (!newly_created) { + r = journal_file_verify_header(f); + if (r < 0) + goto fail; + } + + if (f->writable) { + r = journal_file_refresh_header(f); + if (r < 0) + goto fail; + } + + if (newly_created) { + + r = journal_file_setup_field_hash_table(f); + if (r < 0) + goto fail; + + r = journal_file_setup_data_hash_table(f); + if (r < 0) + goto fail; + } + + r = journal_file_map_field_hash_table(f); + if (r < 0) + goto fail; + + r = journal_file_map_data_hash_table(f); + if (r < 0) + goto fail; + + if (ret) + *ret = f; + + return 0; + +fail: + journal_file_close(f); + + return r; +} + +int journal_file_rotate(JournalFile **f) { + char *p; + size_t l; + JournalFile *old_file, *new_file = NULL; + int r; + + assert(f); + assert(*f); + + old_file = *f; + + if (!old_file->writable) + return -EINVAL; + + if (!endswith(old_file->path, ".journal")) + return -EINVAL; + + l = strlen(old_file->path); + + p = new(char, l + 1 + 16 + 1 + 32 + 1 + 16 + 1); + if (!p) + return -ENOMEM; + + memcpy(p, old_file->path, l - 8); + p[l-8] = '@'; + sd_id128_to_string(old_file->header->seqnum_id, p + l - 8 + 1); + snprintf(p + l - 8 + 1 + 32, 1 + 16 + 1 + 16 + 8 + 1, + "-%016llx-%016llx.journal", + (unsigned long long) le64toh((*f)->header->seqnum), + (unsigned long long) le64toh((*f)->header->tail_entry_realtime)); + + r = rename(old_file->path, p); + free(p); + + if (r < 0) + return -errno; + + old_file->header->state = le32toh(STATE_ARCHIVED); + + r = journal_file_open(old_file->path, old_file->flags, old_file->mode, old_file, &new_file); + journal_file_close(old_file); + + *f = new_file; + return r; +} + +struct vacuum_info { + off_t usage; + char *filename; + + uint64_t realtime; + sd_id128_t seqnum_id; + uint64_t seqnum; +}; + +static int vacuum_compare(const void *_a, const void *_b) { + const struct vacuum_info *a, *b; + + a = _a; + b = _b; + + if (sd_id128_equal(a->seqnum_id, b->seqnum_id)) { + if (a->seqnum < b->seqnum) + return -1; + else if (a->seqnum > b->seqnum) + return 1; + else + return 0; + } + + if (a->realtime < b->realtime) + return -1; + else if (a->realtime > b->realtime) + return 1; + else + return memcmp(&a->seqnum_id, &b->seqnum_id, 16); +} + +int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t min_free) { + DIR *d; + int r = 0; + struct vacuum_info *list = NULL; + unsigned n_list = 0, n_allocated = 0, i; + uint64_t sum = 0; + + assert(directory); + + if (max_use <= 0) + return 0; + + d = opendir(directory); + if (!d) + return -errno; + + for (;;) { + int k; + struct dirent buf, *de; + size_t q; + struct stat st; + char *p; + unsigned long long seqnum, realtime; + sd_id128_t seqnum_id; + + k = readdir_r(d, &buf, &de); + if (k != 0) { + r = -k; + goto finish; + } + + if (!de) + break; + + if (!dirent_is_file_with_suffix(de, ".journal")) + continue; + + q = strlen(de->d_name); + + if (q < 1 + 32 + 1 + 16 + 1 + 16 + 8) + continue; + + if (de->d_name[q-8-16-1] != '-' || + de->d_name[q-8-16-1-16-1] != '-' || + de->d_name[q-8-16-1-16-1-32-1] != '@') + continue; + + if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) + continue; + + if (!S_ISREG(st.st_mode)) + continue; + + p = strdup(de->d_name); + if (!p) { + r = -ENOMEM; + goto finish; + } + + de->d_name[q-8-16-1-16-1] = 0; + if (sd_id128_from_string(de->d_name + q-8-16-1-16-1-32, &seqnum_id) < 0) { + free(p); + continue; + } + + if (sscanf(de->d_name + q-8-16-1-16, "%16llx-%16llx.journal", &seqnum, &realtime) != 2) { + free(p); + continue; + } + + if (n_list >= n_allocated) { + struct vacuum_info *j; + + n_allocated = MAX(n_allocated * 2U, 8U); + j = realloc(list, n_allocated * sizeof(struct vacuum_info)); + if (!j) { + free(p); + r = -ENOMEM; + goto finish; + } + + list = j; + } + + list[n_list].filename = p; + list[n_list].usage = (uint64_t) st.st_blksize * (uint64_t) st.st_blocks; + list[n_list].seqnum = seqnum; + list[n_list].realtime = realtime; + list[n_list].seqnum_id = seqnum_id; + + sum += list[n_list].usage; + + n_list ++; + } + + qsort(list, n_list, sizeof(struct vacuum_info), vacuum_compare); + + for(i = 0; i < n_list; i++) { + struct statvfs ss; + + if (fstatvfs(dirfd(d), &ss) < 0) { + r = -errno; + goto finish; + } + + if (sum <= max_use && + (uint64_t) ss.f_bavail * (uint64_t) ss.f_bsize >= min_free) + break; + + if (unlinkat(dirfd(d), list[i].filename, 0) >= 0) { + log_debug("Deleted archived journal %s/%s.", directory, list[i].filename); + sum -= list[i].usage; + } else if (errno != ENOENT) + log_warning("Failed to delete %s/%s: %m", directory, list[i].filename); + } + +finish: + for (i = 0; i < n_list; i++) + free(list[i].filename); + + free(list); + + if (d) + closedir(d); + + return r; +} + +int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p, uint64_t *seqnum, Object **ret, uint64_t *offset) { + uint64_t i, n; + uint64_t q, xor_hash = 0; + int r; + EntryItem *items; + dual_timestamp ts; + + assert(from); + assert(to); + assert(o); + assert(p); + + if (!to->writable) + return -EPERM; + + ts.monotonic = le64toh(o->entry.monotonic); + ts.realtime = le64toh(o->entry.realtime); + + if (to->tail_entry_monotonic_valid && + ts.monotonic < le64toh(to->header->tail_entry_monotonic)) + return -EINVAL; + + if (ts.realtime < le64toh(to->header->tail_entry_realtime)) + return -EINVAL; + + n = journal_file_entry_n_items(o); + items = alloca(sizeof(EntryItem) * n); + + for (i = 0; i < n; i++) { + uint64_t le_hash, l, h; + size_t t; + void *data; + Object *u; + + q = le64toh(o->entry.items[i].object_offset); + le_hash = o->entry.items[i].hash; + + r = journal_file_move_to_object(from, OBJECT_DATA, q, &o); + if (r < 0) + return r; + + if (le_hash != o->data.hash) + return -EBADMSG; + + l = le64toh(o->object.size) - offsetof(Object, data.payload); + t = (size_t) l; + + /* We hit the limit on 32bit machines */ + if ((uint64_t) t != l) + return -E2BIG; + + if (o->object.flags & OBJECT_COMPRESSED) { +#ifdef HAVE_XZ + uint64_t rsize; + + if (!uncompress_blob(o->data.payload, l, &from->compress_buffer, &from->compress_buffer_size, &rsize)) + return -EBADMSG; + + data = from->compress_buffer; + l = rsize; +#else + return -EPROTONOSUPPORT; +#endif + } else + data = o->data.payload; + + r = journal_file_append_data(to, data, l, &u, &h); + if (r < 0) + return r; + + xor_hash ^= le64toh(u->data.hash); + items[i].object_offset = htole64(h); + items[i].hash = u->data.hash; + + r = journal_file_move_to_object(from, OBJECT_ENTRY, p, &o); + if (r < 0) + return r; + } + + return journal_file_append_entry_internal(to, &ts, xor_hash, items, n, seqnum, ret, offset); +} + +void journal_default_metrics(JournalMetrics *m, int fd) { + uint64_t fs_size = 0; + struct statvfs ss; + char a[FORMAT_BYTES_MAX], b[FORMAT_BYTES_MAX], c[FORMAT_BYTES_MAX], d[FORMAT_BYTES_MAX]; + + assert(m); + assert(fd >= 0); + + if (fstatvfs(fd, &ss) >= 0) + fs_size = ss.f_frsize * ss.f_blocks; + + if (m->max_use == (uint64_t) -1) { + + if (fs_size > 0) { + m->max_use = PAGE_ALIGN(fs_size / 10); /* 10% of file system size */ + + if (m->max_use > DEFAULT_MAX_USE_UPPER) + m->max_use = DEFAULT_MAX_USE_UPPER; + + if (m->max_use < DEFAULT_MAX_USE_LOWER) + m->max_use = DEFAULT_MAX_USE_LOWER; + } else + m->max_use = DEFAULT_MAX_USE_LOWER; + } else { + m->max_use = PAGE_ALIGN(m->max_use); + + if (m->max_use < JOURNAL_FILE_SIZE_MIN*2) + m->max_use = JOURNAL_FILE_SIZE_MIN*2; + } + + if (m->max_size == (uint64_t) -1) { + m->max_size = PAGE_ALIGN(m->max_use / 8); /* 8 chunks */ + + if (m->max_size > DEFAULT_MAX_SIZE_UPPER) + m->max_size = DEFAULT_MAX_SIZE_UPPER; + } else + m->max_size = PAGE_ALIGN(m->max_size); + + if (m->max_size < JOURNAL_FILE_SIZE_MIN) + m->max_size = JOURNAL_FILE_SIZE_MIN; + + if (m->max_size*2 > m->max_use) + m->max_use = m->max_size*2; + + if (m->min_size == (uint64_t) -1) + m->min_size = JOURNAL_FILE_SIZE_MIN; + else { + m->min_size = PAGE_ALIGN(m->min_size); + + if (m->min_size < JOURNAL_FILE_SIZE_MIN) + m->min_size = JOURNAL_FILE_SIZE_MIN; + + if (m->min_size > m->max_size) + m->max_size = m->min_size; + } + + if (m->keep_free == (uint64_t) -1) { + + if (fs_size > 0) { + m->keep_free = PAGE_ALIGN(fs_size / 20); /* 5% of file system size */ + + if (m->keep_free > DEFAULT_KEEP_FREE_UPPER) + m->keep_free = DEFAULT_KEEP_FREE_UPPER; + + } else + m->keep_free = DEFAULT_KEEP_FREE; + } + + log_debug("Fixed max_use=%s max_size=%s min_size=%s keep_free=%s", + format_bytes(a, sizeof(a), m->max_use), + format_bytes(b, sizeof(b), m->max_size), + format_bytes(c, sizeof(c), m->min_size), + format_bytes(d, sizeof(d), m->keep_free)); +} diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h new file mode 100644 index 0000000..4ef4a14 --- /dev/null +++ b/src/journal/journal-file.h @@ -0,0 +1,125 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foojournalfilehfoo +#define foojournalfilehfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include + +#include "journal-def.h" +#include "util.h" + +typedef struct Window { + void *ptr; + uint64_t offset; + uint64_t size; +} Window; + +enum { + WINDOW_UNKNOWN = OBJECT_UNUSED, + WINDOW_DATA = OBJECT_DATA, + WINDOW_ENTRY = OBJECT_ENTRY, + WINDOW_DATA_HASH_TABLE = OBJECT_DATA_HASH_TABLE, + WINDOW_FIELD_HASH_TABLE = OBJECT_FIELD_HASH_TABLE, + WINDOW_ENTRY_ARRAY = OBJECT_ENTRY_ARRAY, + WINDOW_HEADER, + _WINDOW_MAX +}; + +typedef struct JournalMetrics { + uint64_t max_use; + uint64_t max_size; + uint64_t min_size; + uint64_t keep_free; +} JournalMetrics; + +typedef struct JournalFile { + int fd; + char *path; + struct stat last_stat; + mode_t mode; + int flags; + int prot; + bool writable; + bool tail_entry_monotonic_valid; + + Header *header; + HashItem *data_hash_table; + HashItem *field_hash_table; + + Window windows[_WINDOW_MAX]; + + uint64_t current_offset; + + JournalMetrics metrics; + + bool compress; + +#ifdef HAVE_XZ + void *compress_buffer; + uint64_t compress_buffer_size; +#endif +} JournalFile; + +typedef enum direction { + DIRECTION_UP, + DIRECTION_DOWN +} direction_t; + +int journal_file_open(const char *fname, int flags, mode_t mode, JournalFile *template, JournalFile **ret); +void journal_file_close(JournalFile *j); + +int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret); + +uint64_t journal_file_entry_n_items(Object *o); + +int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const struct iovec iovec[], unsigned n_iovec, uint64_t *seqno, Object **ret, uint64_t *offset); + +int journal_file_find_data_object(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset); +int journal_file_find_data_object_with_hash(JournalFile *f, const void *data, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset); + +int journal_file_next_entry(JournalFile *f, Object *o, uint64_t p, direction_t direction, Object **ret, uint64_t *offset); +int journal_file_skip_entry(JournalFile *f, Object *o, uint64_t p, int64_t skip, Object **ret, uint64_t *offset); + +int journal_file_next_entry_for_data(JournalFile *f, Object *o, uint64_t p, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset); + +int journal_file_move_to_entry_by_seqnum(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset); +int journal_file_move_to_entry_by_realtime(JournalFile *f, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset); +int journal_file_move_to_entry_by_monotonic(JournalFile *f, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset); + +int journal_file_move_to_entry_by_seqnum_for_data(JournalFile *f, uint64_t data_offset, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset); +int journal_file_move_to_entry_by_realtime_for_data(JournalFile *f, uint64_t data_offset, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset); + +int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p, uint64_t *seqnum, Object **ret, uint64_t *offset); + +void journal_file_dump(JournalFile *f); + +int journal_file_rotate(JournalFile **f); + +int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t min_free); + +void journal_file_post_change(JournalFile *f); + +void journal_default_metrics(JournalMetrics *m, int fd); + +#endif diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h new file mode 100644 index 0000000..e5914bf --- /dev/null +++ b/src/journal/journal-internal.h @@ -0,0 +1,84 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foojournalinternalhfoo +#define foojournalinternalhfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include + +#include "list.h" + +typedef struct Match Match; + +struct Match { + char *data; + size_t size; + uint64_t le_hash; + + LIST_FIELDS(Match, matches); +}; + +typedef enum location_type { + LOCATION_HEAD, + LOCATION_TAIL, + LOCATION_DISCRETE +} location_type_t; + +typedef struct Location { + location_type_t type; + + uint64_t seqnum; + sd_id128_t seqnum_id; + bool seqnum_set; + + uint64_t realtime; + bool realtime_set; + + uint64_t monotonic; + sd_id128_t boot_id; + bool monotonic_set; + + uint64_t xor_hash; + bool xor_hash_set; +} Location; + +struct sd_journal { + int flags; + + Hashmap *files; + + Location current_location; + JournalFile *current_file; + uint64_t current_field; + + int inotify_fd; + Hashmap *inotify_wd_dirs; + Hashmap *inotify_wd_roots; + + LIST_HEAD(Match, matches); + unsigned n_matches; +}; + +#endif diff --git a/src/journal/journal-rate-limit.c b/src/journal/journal-rate-limit.c new file mode 100644 index 0000000..243ff2a --- /dev/null +++ b/src/journal/journal-rate-limit.c @@ -0,0 +1,275 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "journal-rate-limit.h" +#include "list.h" +#include "util.h" +#include "hashmap.h" + +#define POOLS_MAX 5 +#define BUCKETS_MAX 127 +#define GROUPS_MAX 2047 + +static const int priority_map[] = { + [LOG_EMERG] = 0, + [LOG_ALERT] = 0, + [LOG_CRIT] = 0, + [LOG_ERR] = 1, + [LOG_WARNING] = 2, + [LOG_NOTICE] = 3, + [LOG_INFO] = 3, + [LOG_DEBUG] = 4 +}; + +typedef struct JournalRateLimitPool JournalRateLimitPool; +typedef struct JournalRateLimitGroup JournalRateLimitGroup; + +struct JournalRateLimitPool { + usec_t begin; + unsigned num; + unsigned suppressed; +}; + +struct JournalRateLimitGroup { + JournalRateLimit *parent; + + char *id; + JournalRateLimitPool pools[POOLS_MAX]; + unsigned hash; + + LIST_FIELDS(JournalRateLimitGroup, bucket); + LIST_FIELDS(JournalRateLimitGroup, lru); +}; + +struct JournalRateLimit { + usec_t interval; + unsigned burst; + + JournalRateLimitGroup* buckets[BUCKETS_MAX]; + JournalRateLimitGroup *lru, *lru_tail; + + unsigned n_groups; +}; + +JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst) { + JournalRateLimit *r; + + assert(interval > 0 || burst == 0); + + r = new0(JournalRateLimit, 1); + if (!r) + return NULL; + + r->interval = interval; + r->burst = burst; + + return r; +} + +static void journal_rate_limit_group_free(JournalRateLimitGroup *g) { + assert(g); + + if (g->parent) { + assert(g->parent->n_groups > 0); + + if (g->parent->lru_tail == g) + g->parent->lru_tail = g->lru_prev; + + LIST_REMOVE(JournalRateLimitGroup, lru, g->parent->lru, g); + LIST_REMOVE(JournalRateLimitGroup, bucket, g->parent->buckets[g->hash % BUCKETS_MAX], g); + + g->parent->n_groups --; + } + + free(g->id); + free(g); +} + +void journal_rate_limit_free(JournalRateLimit *r) { + assert(r); + + while (r->lru) + journal_rate_limit_group_free(r->lru); + + free(r); +} + +static bool journal_rate_limit_group_expired(JournalRateLimitGroup *g, usec_t ts) { + unsigned i; + + assert(g); + + for (i = 0; i < POOLS_MAX; i++) + if (g->pools[i].begin + g->parent->interval >= ts) + return false; + + return true; +} + +static void journal_rate_limit_vacuum(JournalRateLimit *r, usec_t ts) { + assert(r); + + /* Makes room for at least one new item, but drop all + * expored items too. */ + + while (r->n_groups >= GROUPS_MAX || + (r->lru_tail && journal_rate_limit_group_expired(r->lru_tail, ts))) + journal_rate_limit_group_free(r->lru_tail); +} + +static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, const char *id, usec_t ts) { + JournalRateLimitGroup *g; + + assert(r); + assert(id); + + g = new0(JournalRateLimitGroup, 1); + if (!g) + return NULL; + + g->id = strdup(id); + if (!g->id) + goto fail; + + g->hash = string_hash_func(g->id); + + journal_rate_limit_vacuum(r, ts); + + LIST_PREPEND(JournalRateLimitGroup, bucket, r->buckets[g->hash % BUCKETS_MAX], g); + LIST_PREPEND(JournalRateLimitGroup, lru, r->lru, g); + if (!g->lru_next) + r->lru_tail = g; + r->n_groups ++; + + g->parent = r; + return g; + +fail: + journal_rate_limit_group_free(g); + return NULL; +} + +static uint64_t u64log2(uint64_t n) { + unsigned r; + + if (n <= 1) + return 0; + + r = 0; + for (;;) { + n = n >> 1; + if (!n) + return r; + r++; + } +} + +static unsigned burst_modulate(unsigned burst, uint64_t available) { + unsigned k; + + /* Modulates the burst rate a bit with the amount of available + * disk space */ + + k = u64log2(available); + + /* 1MB */ + if (k <= 20) + return burst; + + burst = (burst * (k-20)) / 4; + + /* + * Example: + * + * <= 1MB = rate * 1 + * 16MB = rate * 2 + * 256MB = rate * 3 + * 4GB = rate * 4 + * 64GB = rate * 5 + * 1TB = rate * 6 + */ + + return burst; +} + +int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available) { + unsigned h; + JournalRateLimitGroup *g; + JournalRateLimitPool *p; + unsigned burst; + usec_t ts; + + assert(id); + + if (!r) + return 1; + + if (r->interval == 0 || r->burst == 0) + return 1; + + burst = burst_modulate(r->burst, available); + + ts = now(CLOCK_MONOTONIC); + + h = string_hash_func(id); + g = r->buckets[h % BUCKETS_MAX]; + + LIST_FOREACH(bucket, g, g) + if (streq(g->id, id)) + break; + + if (!g) { + g = journal_rate_limit_group_new(r, id, ts); + if (!g) + return -ENOMEM; + } + + p = &g->pools[priority_map[priority]]; + + if (p->begin <= 0) { + p->suppressed = 0; + p->num = 1; + p->begin = ts; + return 1; + } + + if (p->begin + r->interval < ts) { + unsigned s; + + s = p->suppressed; + p->suppressed = 0; + p->num = 1; + p->begin = ts; + + return 1 + s; + } + + if (p->num <= burst) { + p->num++; + return 1; + } + + p->suppressed++; + return 0; +} diff --git a/src/journal/journal-rate-limit.h b/src/journal/journal-rate-limit.h new file mode 100644 index 0000000..2bbdd5f --- /dev/null +++ b/src/journal/journal-rate-limit.h @@ -0,0 +1,34 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foojournalratelimithfoo +#define foojournalratelimithfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "macro.h" +#include "util.h" + +typedef struct JournalRateLimit JournalRateLimit; + +JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst); +void journal_rate_limit_free(JournalRateLimit *r); +int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available); + +#endif diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c new file mode 100644 index 0000000..b5b4fbf --- /dev/null +++ b/src/journal/journal-send.c @@ -0,0 +1,334 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include + +#include "sd-journal.h" +#include "util.h" +#include "socket-util.h" + +#define SNDBUF_SIZE (8*1024*1024) + +/* We open a single fd, and we'll share it with the current process, + * all its threads, and all its subprocesses. This means we need to + * initialize it atomically, and need to operate on it atomically + * never assuming we are the only user */ + +static int journal_fd(void) { + int fd; + static int fd_plus_one = 0; + +retry: + if (fd_plus_one > 0) + return fd_plus_one - 1; + + fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); + if (fd < 0) + return -errno; + + fd_inc_sndbuf(fd, SNDBUF_SIZE); + + if (!__sync_bool_compare_and_swap(&fd_plus_one, 0, fd+1)) { + close_nointr_nofail(fd); + goto retry; + } + + return fd; +} + +_public_ int sd_journal_print(int priority, const char *format, ...) { + int r; + va_list ap; + + va_start(ap, format); + r = sd_journal_printv(priority, format, ap); + va_end(ap); + + return r; +} + +_public_ int sd_journal_printv(int priority, const char *format, va_list ap) { + char buffer[8 + LINE_MAX], p[11]; + struct iovec iov[2]; + + if (priority < 0 || priority > 7) + return -EINVAL; + + if (!format) + return -EINVAL; + + snprintf(p, sizeof(p), "PRIORITY=%i", priority & LOG_PRIMASK); + char_array_0(p); + + memcpy(buffer, "MESSAGE=", 8); + vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap); + char_array_0(buffer); + + zero(iov); + IOVEC_SET_STRING(iov[0], buffer); + IOVEC_SET_STRING(iov[1], p); + + return sd_journal_sendv(iov, 2); +} + +_public_ int sd_journal_send(const char *format, ...) { + int r, n = 0, i = 0, j; + va_list ap; + struct iovec *iov = NULL; + + va_start(ap, format); + while (format) { + struct iovec *c; + char *buffer; + + if (i >= n) { + n = MAX(i*2, 4); + c = realloc(iov, n * sizeof(struct iovec)); + if (!c) { + r = -ENOMEM; + goto fail; + } + + iov = c; + } + + if (vasprintf(&buffer, format, ap) < 0) { + r = -ENOMEM; + goto fail; + } + + IOVEC_SET_STRING(iov[i++], buffer); + + format = va_arg(ap, char *); + } + va_end(ap); + + r = sd_journal_sendv(iov, i); + +fail: + for (j = 0; j < i; j++) + free(iov[j].iov_base); + + free(iov); + + return r; +} + +_public_ int sd_journal_sendv(const struct iovec *iov, int n) { + int fd, buffer_fd; + struct iovec *w; + uint64_t *l; + int i, j = 0; + struct msghdr mh; + struct sockaddr_un sa; + ssize_t k; + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(int))]; + } control; + struct cmsghdr *cmsg; + /* We use /dev/shm instead of /tmp here, since we want this to + * be a tmpfs, and one that is available from early boot on + * and where unprivileged users can create files. */ + char path[] = "/dev/shm/journal.XXXXXX"; + + if (!iov || n <= 0) + return -EINVAL; + + w = alloca(sizeof(struct iovec) * n * 5); + l = alloca(sizeof(uint64_t) * n); + + for (i = 0; i < n; i++) { + char *c, *nl; + + if (!iov[i].iov_base || + iov[i].iov_len <= 1) + return -EINVAL; + + c = memchr(iov[i].iov_base, '=', iov[i].iov_len); + if (!c || c == iov[i].iov_base) + return -EINVAL; + + nl = memchr(iov[i].iov_base, '\n', iov[i].iov_len); + if (nl) { + if (nl < c) + return -EINVAL; + + /* Already includes a newline? Bummer, then + * let's write the variable name, then a + * newline, then the size (64bit LE), followed + * by the data and a final newline */ + + w[j].iov_base = iov[i].iov_base; + w[j].iov_len = c - (char*) iov[i].iov_base; + j++; + + IOVEC_SET_STRING(w[j++], "\n"); + + l[i] = htole64(iov[i].iov_len - (c - (char*) iov[i].iov_base) - 1); + w[j].iov_base = &l[i]; + w[j].iov_len = sizeof(uint64_t); + j++; + + w[j].iov_base = c + 1; + w[j].iov_len = iov[i].iov_len - (c - (char*) iov[i].iov_base) - 1; + j++; + + } else + /* Nothing special? Then just add the line and + * append a newline */ + w[j++] = iov[i]; + + IOVEC_SET_STRING(w[j++], "\n"); + } + + fd = journal_fd(); + if (fd < 0) + return fd; + + zero(sa); + sa.sun_family = AF_UNIX; + strncpy(sa.sun_path, "/run/systemd/journal/socket", sizeof(sa.sun_path)); + + zero(mh); + mh.msg_name = &sa; + mh.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path); + mh.msg_iov = w; + mh.msg_iovlen = j; + + k = sendmsg(fd, &mh, MSG_NOSIGNAL); + if (k >= 0) + return 0; + + if (errno != EMSGSIZE && errno != ENOBUFS) + return -errno; + + /* Message doesn't fit... Let's dump the data in a temporary + * file and just pass a file descriptor of it to the other + * side */ + + buffer_fd = mkostemp(path, O_CLOEXEC|O_RDWR); + if (buffer_fd < 0) + return -errno; + + if (unlink(path) < 0) { + close_nointr_nofail(buffer_fd); + return -errno; + } + + n = writev(buffer_fd, w, j); + if (n < 0) { + close_nointr_nofail(buffer_fd); + return -errno; + } + + mh.msg_iov = NULL; + mh.msg_iovlen = 0; + + zero(control); + mh.msg_control = &control; + mh.msg_controllen = sizeof(control); + + cmsg = CMSG_FIRSTHDR(&mh); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + memcpy(CMSG_DATA(cmsg), &buffer_fd, sizeof(int)); + + mh.msg_controllen = cmsg->cmsg_len; + + k = sendmsg(fd, &mh, MSG_NOSIGNAL); + close_nointr_nofail(buffer_fd); + + if (k < 0) + return -errno; + + return 0; +} + +_public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) { + union sockaddr_union sa; + int fd; + char *header; + size_t l; + ssize_t r; + + if (priority < 0 || priority > 7) + return -EINVAL; + + fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); + if (fd < 0) + return -errno; + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path)); + + r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); + if (r < 0) { + close_nointr_nofail(fd); + return -errno; + } + + if (shutdown(fd, SHUT_RD) < 0) { + close_nointr_nofail(fd); + return -errno; + } + + fd_inc_sndbuf(fd, SNDBUF_SIZE); + + if (!identifier) + identifier = ""; + + l = strlen(identifier); + header = alloca(l + 1 + 2 + 2 + 2 + 2 + 2); + + memcpy(header, identifier, l); + header[l++] = '\n'; + header[l++] = '0' + priority; + header[l++] = '\n'; + header[l++] = '0' + !!level_prefix; + header[l++] = '\n'; + header[l++] = '0'; + header[l++] = '\n'; + header[l++] = '0'; + header[l++] = '\n'; + header[l++] = '0'; + header[l++] = '\n'; + + r = loop_write(fd, header, l, false); + if (r < 0) { + close_nointr_nofail(fd); + return (int) r; + } + + if ((size_t) r != l) { + close_nointr_nofail(fd); + return -errno; + } + + return fd; +} diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c new file mode 100644 index 0000000..8db3fc9 --- /dev/null +++ b/src/journal/journalctl.c @@ -0,0 +1,308 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "log.h" +#include "util.h" +#include "build.h" +#include "pager.h" +#include "logs-show.h" + +static OutputMode arg_output = OUTPUT_SHORT; +static bool arg_follow = false; +static bool arg_show_all = false; +static bool arg_no_pager = false; +static int arg_lines = -1; +static bool arg_no_tail = false; +static bool arg_new_id128 = false; + +static int help(void) { + + printf("%s [OPTIONS...] {COMMAND} ...\n\n" + "Send control commands to or query the journal.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " --no-pager Do not pipe output into a pager\n" + " -a --all Show all properties, including long and unprintable\n" + " -f --follow Follow journal\n" + " -n --lines=INTEGER Journal entries to show\n" + " --no-tail Show all lines, even in follow mode\n" + " -o --output=STRING Change journal output mode (short, short-monotonic,\n" + " verbose, export, json, cat)\n" + " --new-id128 Generate a new 128 Bit id\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + ARG_NO_PAGER, + ARG_NO_TAIL, + ARG_NEW_ID128 + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version" , no_argument, NULL, ARG_VERSION }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "follow", no_argument, NULL, 'f' }, + { "output", required_argument, NULL, 'o' }, + { "all", no_argument, NULL, 'a' }, + { "lines", required_argument, NULL, 'n' }, + { "no-tail", no_argument, NULL, ARG_NO_TAIL }, + { "new-id128", no_argument, NULL, ARG_NEW_ID128 }, + { NULL, 0, NULL, 0 } + }; + + int c, r; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "hfo:an:", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(DISTRIBUTION); + puts(SYSTEMD_FEATURES); + return 0; + + case ARG_NO_PAGER: + arg_no_pager = true; + break; + + case 'f': + arg_follow = true; + break; + + case 'o': + arg_output = output_mode_from_string(optarg); + if (arg_output < 0) { + log_error("Unknown output '%s'.", optarg); + return -EINVAL; + } + + break; + + case 'a': + arg_show_all = true; + break; + + case 'n': + r = safe_atoi(optarg, &arg_lines); + if (r < 0 || arg_lines < 0) { + log_error("Failed to parse lines '%s'", optarg); + return -EINVAL; + } + break; + + case ARG_NO_TAIL: + arg_no_tail = true; + break; + + case ARG_NEW_ID128: + arg_new_id128 = true; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (arg_follow && !arg_no_tail && arg_lines < 0) + arg_lines = 10; + + return 1; +} + +static int generate_new_id128(void) { + sd_id128_t id; + int r; + unsigned i; + + r = sd_id128_randomize(&id); + if (r < 0) { + log_error("Failed to generate ID: %s", strerror(-r)); + return r; + } + + printf("As string:\n" + SD_ID128_FORMAT_STR "\n\n" + "As UUID:\n" + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n" + "As macro:\n" + "#define MESSAGE_XYZ SD_ID128_MAKE(", + SD_ID128_FORMAT_VAL(id), + SD_ID128_FORMAT_VAL(id)); + + for (i = 0; i < 16; i++) + printf("%02x%s", id.bytes[i], i != 15 ? "," : ""); + + fputs(")\n", stdout); + + return 0; +} + +int main(int argc, char *argv[]) { + int r, i, fd; + sd_journal *j = NULL; + unsigned line = 0; + bool need_seek = false; + + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r <= 0) + goto finish; + + if (arg_new_id128) { + r = generate_new_id128(); + goto finish; + } + + r = sd_journal_open(&j, 0); + if (r < 0) { + log_error("Failed to open journal: %s", strerror(-r)); + goto finish; + } + + for (i = optind; i < argc; i++) { + r = sd_journal_add_match(j, argv[i], strlen(argv[i])); + if (r < 0) { + log_error("Failed to add match: %s", strerror(-r)); + goto finish; + } + } + + fd = sd_journal_get_fd(j); + if (fd < 0) { + log_error("Failed to get wakeup fd: %s", strerror(-fd)); + goto finish; + } + + if (arg_lines >= 0) { + r = sd_journal_seek_tail(j); + if (r < 0) { + log_error("Failed to seek to tail: %s", strerror(-r)); + goto finish; + } + + r = sd_journal_previous_skip(j, arg_lines); + } else { + r = sd_journal_seek_head(j); + if (r < 0) { + log_error("Failed to seek to head: %s", strerror(-r)); + goto finish; + } + + r = sd_journal_next(j); + } + + if (r < 0) { + log_error("Failed to iterate through journal: %s", strerror(-r)); + goto finish; + } + + if (!arg_no_pager && !arg_follow) { + columns(); + pager_open(); + } + + if (arg_output == OUTPUT_JSON) { + fputc('[', stdout); + fflush(stdout); + } + + for (;;) { + for (;;) { + if (need_seek) { + r = sd_journal_next(j); + if (r < 0) { + log_error("Failed to iterate through journal: %s", strerror(-r)); + goto finish; + } + } + + if (r == 0) + break; + + line ++; + + r = output_journal(j, arg_output, line, arg_show_all); + if (r < 0) + goto finish; + + need_seek = true; + } + + if (!arg_follow) + break; + + r = fd_wait_for_event(fd, POLLIN, (usec_t) -1); + if (r < 0) { + log_error("Couldn't wait for event: %s", strerror(-r)); + goto finish; + } + + r = sd_journal_process(j); + if (r < 0) { + log_error("Failed to process: %s", strerror(-r)); + goto finish; + } + } + + if (arg_output == OUTPUT_JSON) + fputs("\n]\n", stdout); + +finish: + if (j) + sd_journal_close(j); + + pager_close(); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/journal/journald-gperf.gperf b/src/journal/journald-gperf.gperf new file mode 100644 index 0000000..a56f6d9 --- /dev/null +++ b/src/journal/journald-gperf.gperf @@ -0,0 +1,31 @@ +%{ +#include +#include "conf-parser.h" +#include "journald.h" +%} +struct ConfigPerfItem; +%null_strings +%language=ANSI-C +%define slot-name section_and_lvalue +%define hash-function-name journald_gperf_hash +%define lookup-function-name journald_gperf_lookup +%readonly-tables +%omit-struct-type +%struct-type +%includes +%% +Journal.RateLimitInterval, config_parse_usec, 0, offsetof(Server, rate_limit_interval) +Journal.RateLimitBurst, config_parse_unsigned, 0, offsetof(Server, rate_limit_burst) +Journal.Compress, config_parse_bool, 0, offsetof(Server, compress) +Journal.SystemMaxUse, config_parse_bytes_off, 0, offsetof(Server, system_metrics.max_use) +Journal.SystemMaxFileSize, config_parse_bytes_off, 0, offsetof(Server, system_metrics.max_size) +Journal.SystemMinFileSize, config_parse_bytes_off, 0, offsetof(Server, system_metrics.min_size) +Journal.SystemKeepFree, config_parse_bytes_off, 0, offsetof(Server, system_metrics.keep_free) +Journal.RuntimeMaxUse, config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.max_use) +Journal.RuntimeMaxFileSize, config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.max_size) +Journal.RuntimeMinFileSize, config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.min_size) +Journal.RuntimeKeepFree, config_parse_bytes_off, 0, offsetof(Server, runtime_metrics.keep_free) +Journal.ForwardToSyslog, config_parse_bool, 0, offsetof(Server, forward_to_syslog) +Journal.ForwardToKMsg, config_parse_bool, 0, offsetof(Server, forward_to_kmsg) +Journal.ForwardToConsole, config_parse_bool, 0, offsetof(Server, forward_to_console) +Journal.ImportKernel, config_parse_bool, 0, offsetof(Server, import_proc_kmsg) diff --git a/src/journal/journald.c b/src/journal/journald.c new file mode 100644 index 0000000..73f8ed6 --- /dev/null +++ b/src/journal/journald.c @@ -0,0 +1,2723 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "hashmap.h" +#include "journal-file.h" +#include "socket-util.h" +#include "cgroup-util.h" +#include "list.h" +#include "journal-rate-limit.h" +#include "journal-internal.h" +#include "conf-parser.h" +#include "journald.h" +#include "virt.h" + +#ifdef HAVE_ACL +#include +#include +#include "acl-util.h" +#endif + +#ifdef HAVE_SELINUX +#include +#endif + +#define USER_JOURNALS_MAX 1024 +#define STDOUT_STREAMS_MAX 4096 + +#define DEFAULT_RATE_LIMIT_INTERVAL (10*USEC_PER_SEC) +#define DEFAULT_RATE_LIMIT_BURST 200 + +#define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC) + +#define RECHECK_VAR_AVAILABLE_USEC (30*USEC_PER_SEC) + +#define N_IOVEC_META_FIELDS 17 + +#define ENTRY_SIZE_MAX (1024*1024*32) + +typedef enum StdoutStreamState { + STDOUT_STREAM_IDENTIFIER, + STDOUT_STREAM_PRIORITY, + STDOUT_STREAM_LEVEL_PREFIX, + STDOUT_STREAM_FORWARD_TO_SYSLOG, + STDOUT_STREAM_FORWARD_TO_KMSG, + STDOUT_STREAM_FORWARD_TO_CONSOLE, + STDOUT_STREAM_RUNNING +} StdoutStreamState; + +struct StdoutStream { + Server *server; + StdoutStreamState state; + + int fd; + + struct ucred ucred; + + char *identifier; + int priority; + bool level_prefix:1; + bool forward_to_syslog:1; + bool forward_to_kmsg:1; + bool forward_to_console:1; + + char buffer[LINE_MAX+1]; + size_t length; + + LIST_FIELDS(StdoutStream, stdout_stream); +}; + +static int server_flush_to_var(Server *s); + +static uint64_t available_space(Server *s) { + char ids[33], *p; + const char *f; + sd_id128_t machine; + struct statvfs ss; + uint64_t sum = 0, avail = 0, ss_avail = 0; + int r; + DIR *d; + usec_t ts; + JournalMetrics *m; + + ts = now(CLOCK_MONOTONIC); + + if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts) + return s->cached_available_space; + + r = sd_id128_get_machine(&machine); + if (r < 0) + return 0; + + if (s->system_journal) { + f = "/var/log/journal/"; + m = &s->system_metrics; + } else { + f = "/run/log/journal/"; + m = &s->runtime_metrics; + } + + assert(m); + + p = strappend(f, sd_id128_to_string(machine, ids)); + if (!p) + return 0; + + d = opendir(p); + free(p); + + if (!d) + return 0; + + if (fstatvfs(dirfd(d), &ss) < 0) + goto finish; + + for (;;) { + struct stat st; + struct dirent buf, *de; + int k; + + k = readdir_r(d, &buf, &de); + if (k != 0) { + r = -k; + goto finish; + } + + if (!de) + break; + + if (!dirent_is_file_with_suffix(de, ".journal")) + continue; + + if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) + continue; + + sum += (uint64_t) st.st_blocks * (uint64_t) st.st_blksize; + } + + avail = sum >= m->max_use ? 0 : m->max_use - sum; + + ss_avail = ss.f_bsize * ss.f_bavail; + + ss_avail = ss_avail < m->keep_free ? 0 : ss_avail - m->keep_free; + + if (ss_avail < avail) + avail = ss_avail; + + s->cached_available_space = avail; + s->cached_available_space_timestamp = ts; + +finish: + closedir(d); + + return avail; +} + +static void server_read_file_gid(Server *s) { + const char *adm = "adm"; + int r; + + assert(s); + + if (s->file_gid_valid) + return; + + r = get_group_creds(&adm, &s->file_gid); + if (r < 0) + log_warning("Failed to resolve 'adm' group: %s", strerror(-r)); + + /* if we couldn't read the gid, then it will be 0, but that's + * fine and we shouldn't try to resolve the group again, so + * let's just pretend it worked right-away. */ + s->file_gid_valid = true; +} + +static void server_fix_perms(Server *s, JournalFile *f, uid_t uid) { + int r; +#ifdef HAVE_ACL + acl_t acl; + acl_entry_t entry; + acl_permset_t permset; +#endif + + assert(f); + + server_read_file_gid(s); + + r = fchmod_and_fchown(f->fd, 0640, 0, s->file_gid); + if (r < 0) + log_warning("Failed to fix access mode/rights on %s, ignoring: %s", f->path, strerror(-r)); + +#ifdef HAVE_ACL + if (uid <= 0) + return; + + acl = acl_get_fd(f->fd); + if (!acl) { + log_warning("Failed to read ACL on %s, ignoring: %m", f->path); + return; + } + + r = acl_find_uid(acl, uid, &entry); + if (r <= 0) { + + if (acl_create_entry(&acl, &entry) < 0 || + acl_set_tag_type(entry, ACL_USER) < 0 || + acl_set_qualifier(entry, &uid) < 0) { + log_warning("Failed to patch ACL on %s, ignoring: %m", f->path); + goto finish; + } + } + + if (acl_get_permset(entry, &permset) < 0 || + acl_add_perm(permset, ACL_READ) < 0 || + acl_calc_mask(&acl) < 0) { + log_warning("Failed to patch ACL on %s, ignoring: %m", f->path); + goto finish; + } + + if (acl_set_fd(f->fd, acl) < 0) + log_warning("Failed to set ACL on %s, ignoring: %m", f->path); + +finish: + acl_free(acl); +#endif +} + +static JournalFile* find_journal(Server *s, uid_t uid) { + char *p; + int r; + JournalFile *f; + char ids[33]; + sd_id128_t machine; + + assert(s); + + /* We split up user logs only on /var, not on /run. If the + * runtime file is open, we write to it exclusively, in order + * to guarantee proper order as soon as we flush /run to + * /var and close the runtime file. */ + + if (s->runtime_journal) + return s->runtime_journal; + + if (uid <= 0) + return s->system_journal; + + r = sd_id128_get_machine(&machine); + if (r < 0) + return s->system_journal; + + f = hashmap_get(s->user_journals, UINT32_TO_PTR(uid)); + if (f) + return f; + + if (asprintf(&p, "/var/log/journal/%s/user-%lu.journal", sd_id128_to_string(machine, ids), (unsigned long) uid) < 0) + return s->system_journal; + + while (hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) { + /* Too many open? Then let's close one */ + f = hashmap_steal_first(s->user_journals); + assert(f); + journal_file_close(f); + } + + r = journal_file_open(p, O_RDWR|O_CREAT, 0640, s->system_journal, &f); + free(p); + + if (r < 0) + return s->system_journal; + + server_fix_perms(s, f, uid); + f->metrics = s->system_metrics; + f->compress = s->compress; + + r = hashmap_put(s->user_journals, UINT32_TO_PTR(uid), f); + if (r < 0) { + journal_file_close(f); + return s->system_journal; + } + + return f; +} + +static void server_rotate(Server *s) { + JournalFile *f; + void *k; + Iterator i; + int r; + + log_info("Rotating..."); + + if (s->runtime_journal) { + r = journal_file_rotate(&s->runtime_journal); + if (r < 0) + log_error("Failed to rotate %s: %s", s->runtime_journal->path, strerror(-r)); + } + + if (s->system_journal) { + r = journal_file_rotate(&s->system_journal); + if (r < 0) + log_error("Failed to rotate %s: %s", s->system_journal->path, strerror(-r)); + } + + HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) { + r = journal_file_rotate(&f); + if (r < 0) + log_error("Failed to rotate %s: %s", f->path, strerror(-r)); + else + hashmap_replace(s->user_journals, k, f); + } +} + +static void server_vacuum(Server *s) { + char *p; + char ids[33]; + sd_id128_t machine; + int r; + + log_info("Vacuuming..."); + + r = sd_id128_get_machine(&machine); + if (r < 0) { + log_error("Failed to get machine ID: %s", strerror(-r)); + return; + } + + sd_id128_to_string(machine, ids); + + if (s->system_journal) { + if (asprintf(&p, "/var/log/journal/%s", ids) < 0) { + log_error("Out of memory."); + return; + } + + r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free); + if (r < 0 && r != -ENOENT) + log_error("Failed to vacuum %s: %s", p, strerror(-r)); + free(p); + } + + + if (s->runtime_journal) { + if (asprintf(&p, "/run/log/journal/%s", ids) < 0) { + log_error("Out of memory."); + return; + } + + r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free); + if (r < 0 && r != -ENOENT) + log_error("Failed to vacuum %s: %s", p, strerror(-r)); + free(p); + } + + s->cached_available_space_timestamp = 0; +} + +static char *shortened_cgroup_path(pid_t pid) { + int r; + char *process_path, *init_path, *path; + + assert(pid > 0); + + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &process_path); + if (r < 0) + return NULL; + + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &init_path); + if (r < 0) { + free(process_path); + return NULL; + } + + if (endswith(init_path, "/system")) + init_path[strlen(init_path) - 7] = 0; + else if (streq(init_path, "/")) + init_path[0] = 0; + + if (startswith(process_path, init_path)) { + char *p; + + p = strdup(process_path + strlen(init_path)); + if (!p) { + free(process_path); + free(init_path); + return NULL; + } + path = p; + } else { + path = process_path; + process_path = NULL; + } + + free(process_path); + free(init_path); + + return path; +} + +static void dispatch_message_real(Server *s, + struct iovec *iovec, unsigned n, unsigned m, + struct ucred *ucred, + struct timeval *tv) { + + char *pid = NULL, *uid = NULL, *gid = NULL, + *source_time = NULL, *boot_id = NULL, *machine_id = NULL, + *comm = NULL, *cmdline = NULL, *hostname = NULL, + *audit_session = NULL, *audit_loginuid = NULL, + *exe = NULL, *cgroup = NULL, *session = NULL, + *owner_uid = NULL, *unit = NULL, *selinux_context = NULL; + + char idbuf[33]; + sd_id128_t id; + int r; + char *t; + uid_t loginuid = 0, realuid = 0; + JournalFile *f; + bool vacuumed = false; + + assert(s); + assert(iovec); + assert(n > 0); + assert(n + N_IOVEC_META_FIELDS <= m); + + if (ucred) { + uint32_t audit; + uid_t owner; +#ifdef HAVE_SELINUX + security_context_t con; +#endif + + realuid = ucred->uid; + + if (asprintf(&pid, "_PID=%lu", (unsigned long) ucred->pid) >= 0) + IOVEC_SET_STRING(iovec[n++], pid); + + if (asprintf(&uid, "_UID=%lu", (unsigned long) ucred->uid) >= 0) + IOVEC_SET_STRING(iovec[n++], uid); + + if (asprintf(&gid, "_GID=%lu", (unsigned long) ucred->gid) >= 0) + IOVEC_SET_STRING(iovec[n++], gid); + + r = get_process_comm(ucred->pid, &t); + if (r >= 0) { + comm = strappend("_COMM=", t); + free(t); + + if (comm) + IOVEC_SET_STRING(iovec[n++], comm); + } + + r = get_process_exe(ucred->pid, &t); + if (r >= 0) { + exe = strappend("_EXE=", t); + free(t); + + if (exe) + IOVEC_SET_STRING(iovec[n++], exe); + } + + r = get_process_cmdline(ucred->pid, LINE_MAX, false, &t); + if (r >= 0) { + cmdline = strappend("_CMDLINE=", t); + free(t); + + if (cmdline) + IOVEC_SET_STRING(iovec[n++], cmdline); + } + + r = audit_session_from_pid(ucred->pid, &audit); + if (r >= 0) + if (asprintf(&audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit) >= 0) + IOVEC_SET_STRING(iovec[n++], audit_session); + + r = audit_loginuid_from_pid(ucred->pid, &loginuid); + if (r >= 0) + if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0) + IOVEC_SET_STRING(iovec[n++], audit_loginuid); + + t = shortened_cgroup_path(ucred->pid); + if (t) { + cgroup = strappend("_SYSTEMD_CGROUP=", t); + free(t); + + if (cgroup) + IOVEC_SET_STRING(iovec[n++], cgroup); + } + + if (sd_pid_get_session(ucred->pid, &t) >= 0) { + session = strappend("_SYSTEMD_SESSION=", t); + free(t); + + if (session) + IOVEC_SET_STRING(iovec[n++], session); + } + + if (sd_pid_get_unit(ucred->pid, &t) >= 0) { + unit = strappend("_SYSTEMD_UNIT=", t); + free(t); + + if (unit) + IOVEC_SET_STRING(iovec[n++], unit); + } + + if (sd_pid_get_owner_uid(ucred->uid, &owner) >= 0) + if (asprintf(&owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner) >= 0) + IOVEC_SET_STRING(iovec[n++], owner_uid); + +#ifdef HAVE_SELINUX + if (getpidcon(ucred->pid, &con) >= 0) { + selinux_context = strappend("_SELINUX_CONTEXT=", con); + if (selinux_context) + IOVEC_SET_STRING(iovec[n++], selinux_context); + + freecon(con); + } +#endif + } + + if (tv) { + if (asprintf(&source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu", + (unsigned long long) timeval_load(tv)) >= 0) + IOVEC_SET_STRING(iovec[n++], source_time); + } + + /* Note that strictly speaking storing the boot id here is + * redundant since the entry includes this in-line + * anyway. However, we need this indexed, too. */ + r = sd_id128_get_boot(&id); + if (r >= 0) + if (asprintf(&boot_id, "_BOOT_ID=%s", sd_id128_to_string(id, idbuf)) >= 0) + IOVEC_SET_STRING(iovec[n++], boot_id); + + r = sd_id128_get_machine(&id); + if (r >= 0) + if (asprintf(&machine_id, "_MACHINE_ID=%s", sd_id128_to_string(id, idbuf)) >= 0) + IOVEC_SET_STRING(iovec[n++], machine_id); + + t = gethostname_malloc(); + if (t) { + hostname = strappend("_HOSTNAME=", t); + free(t); + if (hostname) + IOVEC_SET_STRING(iovec[n++], hostname); + } + + assert(n <= m); + + server_flush_to_var(s); + +retry: + f = find_journal(s, realuid == 0 ? 0 : loginuid); + if (!f) + log_warning("Dropping message, as we can't find a place to store the data."); + else { + r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL); + + if (r == -E2BIG && !vacuumed) { + log_info("Allocation limit reached."); + + server_rotate(s); + server_vacuum(s); + vacuumed = true; + + log_info("Retrying write."); + goto retry; + } + + if (r < 0) + log_error("Failed to write entry, ignoring: %s", strerror(-r)); + } + + free(pid); + free(uid); + free(gid); + free(comm); + free(exe); + free(cmdline); + free(source_time); + free(boot_id); + free(machine_id); + free(hostname); + free(audit_session); + free(audit_loginuid); + free(cgroup); + free(session); + free(owner_uid); + free(unit); + free(selinux_context); +} + +static void driver_message(Server *s, sd_id128_t message_id, const char *format, ...) { + char mid[11 + 32 + 1]; + char buffer[16 + LINE_MAX + 1]; + struct iovec iovec[N_IOVEC_META_FIELDS + 4]; + int n = 0; + va_list ap; + struct ucred ucred; + + assert(s); + assert(format); + + IOVEC_SET_STRING(iovec[n++], "PRIORITY=5"); + IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=driver"); + + memcpy(buffer, "MESSAGE=", 8); + va_start(ap, format); + vsnprintf(buffer + 8, sizeof(buffer) - 8, format, ap); + va_end(ap); + char_array_0(buffer); + IOVEC_SET_STRING(iovec[n++], buffer); + + snprintf(mid, sizeof(mid), "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(message_id)); + char_array_0(mid); + IOVEC_SET_STRING(iovec[n++], mid); + + zero(ucred); + ucred.pid = getpid(); + ucred.uid = getuid(); + ucred.gid = getgid(); + + dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL); +} + +static void dispatch_message(Server *s, + struct iovec *iovec, unsigned n, unsigned m, + struct ucred *ucred, + struct timeval *tv, + int priority) { + int rl; + char *path = NULL, *c; + + assert(s); + assert(iovec || n == 0); + + if (n == 0) + return; + + if (!ucred) + goto finish; + + path = shortened_cgroup_path(ucred->pid); + if (!path) + goto finish; + + /* example: /user/lennart/3/foobar + * /system/dbus.service/foobar + * + * So let's cut of everything past the third /, since that is + * wher user directories start */ + + c = strchr(path, '/'); + if (c) { + c = strchr(c+1, '/'); + if (c) { + c = strchr(c+1, '/'); + if (c) + *c = 0; + } + } + + rl = journal_rate_limit_test(s->rate_limit, path, priority & LOG_PRIMASK, available_space(s)); + + if (rl == 0) { + free(path); + return; + } + + /* Write a suppression message if we suppressed something */ + if (rl > 1) + driver_message(s, SD_MESSAGE_JOURNAL_DROPPED, "Suppressed %u messages from %s", rl - 1, path); + + free(path); + +finish: + dispatch_message_real(s, iovec, n, m, ucred, tv); +} + +static void forward_syslog_iovec(Server *s, const struct iovec *iovec, unsigned n_iovec, struct ucred *ucred, struct timeval *tv) { + struct msghdr msghdr; + struct cmsghdr *cmsg; + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; + } control; + union sockaddr_union sa; + + assert(s); + assert(iovec); + assert(n_iovec > 0); + + zero(msghdr); + msghdr.msg_iov = (struct iovec*) iovec; + msghdr.msg_iovlen = n_iovec; + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/run/systemd/journal/syslog", sizeof(sa.un.sun_path)); + msghdr.msg_name = &sa; + msghdr.msg_namelen = offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path); + + if (ucred) { + zero(control); + msghdr.msg_control = &control; + msghdr.msg_controllen = sizeof(control); + + cmsg = CMSG_FIRSTHDR(&msghdr); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_CREDENTIALS; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred)); + memcpy(CMSG_DATA(cmsg), ucred, sizeof(struct ucred)); + msghdr.msg_controllen = cmsg->cmsg_len; + } + + /* Forward the syslog message we received via /dev/log to + * /run/systemd/syslog. Unfortunately we currently can't set + * the SO_TIMESTAMP auxiliary data, and hence we don't. */ + + if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0) + return; + + /* The socket is full? I guess the syslog implementation is + * too slow, and we shouldn't wait for that... */ + if (errno == EAGAIN) + return; + + if (ucred && errno == ESRCH) { + struct ucred u; + + /* Hmm, presumably the sender process vanished + * by now, so let's fix it as good as we + * can, and retry */ + + u = *ucred; + u.pid = getpid(); + memcpy(CMSG_DATA(cmsg), &u, sizeof(struct ucred)); + + if (sendmsg(s->syslog_fd, &msghdr, MSG_NOSIGNAL) >= 0) + return; + + if (errno == EAGAIN) + return; + } + + log_debug("Failed to forward syslog message: %m"); +} + +static void forward_syslog_raw(Server *s, const char *buffer, struct ucred *ucred, struct timeval *tv) { + struct iovec iovec; + + assert(s); + assert(buffer); + + IOVEC_SET_STRING(iovec, buffer); + forward_syslog_iovec(s, &iovec, 1, ucred, tv); +} + +static void forward_syslog(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred, struct timeval *tv) { + struct iovec iovec[5]; + char header_priority[6], header_time[64], header_pid[16]; + int n = 0; + time_t t; + struct tm *tm; + char *ident_buf = NULL; + + assert(s); + assert(priority >= 0); + assert(priority <= 999); + assert(message); + + /* First: priority field */ + snprintf(header_priority, sizeof(header_priority), "<%i>", priority); + char_array_0(header_priority); + IOVEC_SET_STRING(iovec[n++], header_priority); + + /* Second: timestamp */ + t = tv ? tv->tv_sec : ((time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC)); + tm = localtime(&t); + if (!tm) + return; + if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0) + return; + IOVEC_SET_STRING(iovec[n++], header_time); + + /* Third: identifier and PID */ + if (ucred) { + if (!identifier) { + get_process_comm(ucred->pid, &ident_buf); + identifier = ident_buf; + } + + snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid); + char_array_0(header_pid); + + if (identifier) + IOVEC_SET_STRING(iovec[n++], identifier); + + IOVEC_SET_STRING(iovec[n++], header_pid); + } else if (identifier) { + IOVEC_SET_STRING(iovec[n++], identifier); + IOVEC_SET_STRING(iovec[n++], ": "); + } + + /* Fourth: message */ + IOVEC_SET_STRING(iovec[n++], message); + + forward_syslog_iovec(s, iovec, n, ucred, tv); + + free(ident_buf); +} + +static int fixup_priority(int priority) { + + if ((priority & LOG_FACMASK) == 0) + return (priority & LOG_PRIMASK) | LOG_USER; + + return priority; +} + +static void forward_kmsg(Server *s, int priority, const char *identifier, const char *message, struct ucred *ucred) { + struct iovec iovec[5]; + char header_priority[6], header_pid[16]; + int n = 0; + char *ident_buf = NULL; + int fd; + + assert(s); + assert(priority >= 0); + assert(priority <= 999); + assert(message); + + /* Never allow messages with kernel facility to be written to + * kmsg, regardless where the data comes from. */ + priority = fixup_priority(priority); + + /* First: priority field */ + snprintf(header_priority, sizeof(header_priority), "<%i>", priority); + char_array_0(header_priority); + IOVEC_SET_STRING(iovec[n++], header_priority); + + /* Second: identifier and PID */ + if (ucred) { + if (!identifier) { + get_process_comm(ucred->pid, &ident_buf); + identifier = ident_buf; + } + + snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid); + char_array_0(header_pid); + + if (identifier) + IOVEC_SET_STRING(iovec[n++], identifier); + + IOVEC_SET_STRING(iovec[n++], header_pid); + } else if (identifier) { + IOVEC_SET_STRING(iovec[n++], identifier); + IOVEC_SET_STRING(iovec[n++], ": "); + } + + /* Fourth: message */ + IOVEC_SET_STRING(iovec[n++], message); + IOVEC_SET_STRING(iovec[n++], "\n"); + + fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) { + log_debug("Failed to open /dev/kmsg for logging: %s", strerror(errno)); + goto finish; + } + + if (writev(fd, iovec, n) < 0) + log_debug("Failed to write to /dev/kmsg for logging: %s", strerror(errno)); + + close_nointr_nofail(fd); + +finish: + free(ident_buf); +} + +static void forward_console(Server *s, const char *identifier, const char *message, struct ucred *ucred) { + struct iovec iovec[4]; + char header_pid[16]; + int n = 0, fd; + char *ident_buf = NULL; + + assert(s); + assert(message); + + /* First: identifier and PID */ + if (ucred) { + if (!identifier) { + get_process_comm(ucred->pid, &ident_buf); + identifier = ident_buf; + } + + snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) ucred->pid); + char_array_0(header_pid); + + if (identifier) + IOVEC_SET_STRING(iovec[n++], identifier); + + IOVEC_SET_STRING(iovec[n++], header_pid); + } else if (identifier) { + IOVEC_SET_STRING(iovec[n++], identifier); + IOVEC_SET_STRING(iovec[n++], ": "); + } + + /* Third: message */ + IOVEC_SET_STRING(iovec[n++], message); + IOVEC_SET_STRING(iovec[n++], "\n"); + + fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) { + log_debug("Failed to open /dev/console for logging: %s", strerror(errno)); + goto finish; + } + + if (writev(fd, iovec, n) < 0) + log_debug("Failed to write to /dev/console for logging: %s", strerror(errno)); + + close_nointr_nofail(fd); + +finish: + free(ident_buf); +} + +static void read_identifier(const char **buf, char **identifier, char **pid) { + const char *p; + char *t; + size_t l, e; + + assert(buf); + assert(identifier); + assert(pid); + + p = *buf; + + p += strspn(p, WHITESPACE); + l = strcspn(p, WHITESPACE); + + if (l <= 0 || + p[l-1] != ':') + return; + + e = l; + l--; + + if (p[l-1] == ']') { + size_t k = l-1; + + for (;;) { + + if (p[k] == '[') { + t = strndup(p+k+1, l-k-2); + if (t) + *pid = t; + + l = k; + break; + } + + if (k == 0) + break; + + k--; + } + } + + t = strndup(p, l); + if (t) + *identifier = t; + + *buf = p + e; + *buf += strspn(*buf, WHITESPACE); +} + +static void process_syslog_message(Server *s, const char *buf, struct ucred *ucred, struct timeval *tv) { + char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *syslog_pid = NULL; + struct iovec iovec[N_IOVEC_META_FIELDS + 6]; + unsigned n = 0; + int priority = LOG_USER | LOG_INFO; + char *identifier = NULL, *pid = NULL; + + assert(s); + assert(buf); + + if (s->forward_to_syslog) + forward_syslog_raw(s, buf, ucred, tv); + + parse_syslog_priority((char**) &buf, &priority); + skip_syslog_date((char**) &buf); + read_identifier(&buf, &identifier, &pid); + + if (s->forward_to_kmsg) + forward_kmsg(s, priority, identifier, buf, ucred); + + if (s->forward_to_console) + forward_console(s, identifier, buf, ucred); + + IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=syslog"); + + if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0) + IOVEC_SET_STRING(iovec[n++], syslog_priority); + + if (priority & LOG_FACMASK) + if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0) + IOVEC_SET_STRING(iovec[n++], syslog_facility); + + if (identifier) { + syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier); + if (syslog_identifier) + IOVEC_SET_STRING(iovec[n++], syslog_identifier); + } + + if (pid) { + syslog_pid = strappend("SYSLOG_PID=", pid); + if (syslog_pid) + IOVEC_SET_STRING(iovec[n++], syslog_pid); + } + + message = strappend("MESSAGE=", buf); + if (message) + IOVEC_SET_STRING(iovec[n++], message); + + dispatch_message(s, iovec, n, ELEMENTSOF(iovec), ucred, tv, priority); + + free(message); + free(identifier); + free(pid); + free(syslog_priority); + free(syslog_facility); + free(syslog_identifier); +} + +static bool valid_user_field(const char *p, size_t l) { + const char *a; + + /* We kinda enforce POSIX syntax recommendations for + environment variables here, but make a couple of additional + requirements. + + http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */ + + /* No empty field names */ + if (l <= 0) + return false; + + /* Don't allow names longer than 64 chars */ + if (l > 64) + return false; + + /* Variables starting with an underscore are protected */ + if (p[0] == '_') + return false; + + /* Don't allow digits as first character */ + if (p[0] >= '0' && p[0] <= '9') + return false; + + /* Only allow A-Z0-9 and '_' */ + for (a = p; a < p + l; a++) + if (!((*a >= 'A' && *a <= 'Z') || + (*a >= '0' && *a <= '9') || + *a == '_')) + return false; + + return true; +} + +static void process_native_message(Server *s, const void *buffer, size_t buffer_size, struct ucred *ucred, struct timeval *tv) { + struct iovec *iovec = NULL; + unsigned n = 0, m = 0, j, tn = (unsigned) -1; + const char *p; + size_t remaining; + int priority = LOG_INFO; + char *identifier = NULL, *message = NULL; + + assert(s); + assert(buffer || n == 0); + + p = buffer; + remaining = buffer_size; + + while (remaining > 0) { + const char *e, *q; + + e = memchr(p, '\n', remaining); + + if (!e) { + /* Trailing noise, let's ignore it, and flush what we collected */ + log_debug("Received message with trailing noise, ignoring."); + break; + } + + if (e == p) { + /* Entry separator */ + dispatch_message(s, iovec, n, m, ucred, tv, priority); + n = 0; + priority = LOG_INFO; + + p++; + remaining--; + continue; + } + + if (*p == '.' || *p == '#') { + /* Ignore control commands for now, and + * comments too. */ + remaining -= (e - p) + 1; + p = e + 1; + continue; + } + + /* A property follows */ + + if (n+N_IOVEC_META_FIELDS >= m) { + struct iovec *c; + unsigned u; + + u = MAX((n+N_IOVEC_META_FIELDS+1) * 2U, 4U); + c = realloc(iovec, u * sizeof(struct iovec)); + if (!c) { + log_error("Out of memory"); + break; + } + + iovec = c; + m = u; + } + + q = memchr(p, '=', e - p); + if (q) { + if (valid_user_field(p, q - p)) { + size_t l; + + l = e - p; + + /* If the field name starts with an + * underscore, skip the variable, + * since that indidates a trusted + * field */ + iovec[n].iov_base = (char*) p; + iovec[n].iov_len = l; + n++; + + /* We need to determine the priority + * of this entry for the rate limiting + * logic */ + if (l == 10 && + memcmp(p, "PRIORITY=", 9) == 0 && + p[9] >= '0' && p[9] <= '9') + priority = (priority & LOG_FACMASK) | (p[9] - '0'); + + else if (l == 17 && + memcmp(p, "SYSLOG_FACILITY=", 16) == 0 && + p[16] >= '0' && p[16] <= '9') + priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3); + + else if (l == 18 && + memcmp(p, "SYSLOG_FACILITY=", 16) == 0 && + p[16] >= '0' && p[16] <= '9' && + p[17] >= '0' && p[17] <= '9') + priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3); + + else if (l >= 12 && + memcmp(p, "SYSLOG_IDENTIFIER=", 11) == 0) { + char *t; + + t = strndup(p + 11, l - 11); + if (t) { + free(identifier); + identifier = t; + } + } else if (l >= 8 && + memcmp(p, "MESSAGE=", 8) == 0) { + char *t; + + t = strndup(p + 8, l - 8); + if (t) { + free(message); + message = t; + } + } + } + + remaining -= (e - p) + 1; + p = e + 1; + continue; + } else { + uint64_t l; + char *k; + + if (remaining < e - p + 1 + sizeof(uint64_t) + 1) { + log_debug("Failed to parse message, ignoring."); + break; + } + + memcpy(&l, e + 1, sizeof(uint64_t)); + l = le64toh(l); + + if (remaining < e - p + 1 + sizeof(uint64_t) + l + 1 || + e[1+sizeof(uint64_t)+l] != '\n') { + log_debug("Failed to parse message, ignoring."); + break; + } + + k = malloc((e - p) + 1 + l); + if (!k) { + log_error("Out of memory"); + break; + } + + memcpy(k, p, e - p); + k[e - p] = '='; + memcpy(k + (e - p) + 1, e + 1 + sizeof(uint64_t), l); + + if (valid_user_field(p, e - p)) { + iovec[n].iov_base = k; + iovec[n].iov_len = (e - p) + 1 + l; + n++; + } else + free(k); + + remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1; + p = e + 1 + sizeof(uint64_t) + l + 1; + } + } + + if (n <= 0) + goto finish; + + tn = n++; + IOVEC_SET_STRING(iovec[tn], "_TRANSPORT=journal"); + + if (message) { + if (s->forward_to_syslog) + forward_syslog(s, priority, identifier, message, ucred, tv); + + if (s->forward_to_kmsg) + forward_kmsg(s, priority, identifier, message, ucred); + + if (s->forward_to_console) + forward_console(s, identifier, message, ucred); + } + + dispatch_message(s, iovec, n, m, ucred, tv, priority); + +finish: + for (j = 0; j < n; j++) { + if (j == tn) + continue; + + if (iovec[j].iov_base < buffer || + (const uint8_t*) iovec[j].iov_base >= (const uint8_t*) buffer + buffer_size) + free(iovec[j].iov_base); + } + + free(identifier); + free(message); +} + +static void process_native_file(Server *s, int fd, struct ucred *ucred, struct timeval *tv) { + struct stat st; + void *p; + ssize_t n; + + assert(s); + assert(fd >= 0); + + /* Data is in the passed file, since it didn't fit in a + * datagram. We can't map the file here, since clients might + * then truncate it and trigger a SIGBUS for us. So let's + * stupidly read it */ + + if (fstat(fd, &st) < 0) { + log_error("Failed to stat passed file, ignoring: %m"); + return; + } + + if (!S_ISREG(st.st_mode)) { + log_error("File passed is not regular. Ignoring."); + return; + } + + if (st.st_size <= 0) + return; + + if (st.st_size > ENTRY_SIZE_MAX) { + log_error("File passed too large. Ignoring."); + return; + } + + p = malloc(st.st_size); + if (!p) { + log_error("Out of memory"); + return; + } + + n = pread(fd, p, st.st_size, 0); + if (n < 0) + log_error("Failed to read file, ignoring: %s", strerror(-n)); + else if (n > 0) + process_native_message(s, p, n, ucred, tv); + + free(p); +} + +static int stdout_stream_log(StdoutStream *s, const char *p) { + struct iovec iovec[N_IOVEC_META_FIELDS + 5]; + char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_identifier = NULL; + unsigned n = 0; + int priority; + + assert(s); + assert(p); + + if (isempty(p)) + return 0; + + priority = s->priority; + + if (s->level_prefix) + parse_syslog_priority((char**) &p, &priority); + + if (s->forward_to_syslog || s->server->forward_to_syslog) + forward_syslog(s->server, fixup_priority(priority), s->identifier, p, &s->ucred, NULL); + + if (s->forward_to_kmsg || s->server->forward_to_kmsg) + forward_kmsg(s->server, priority, s->identifier, p, &s->ucred); + + if (s->forward_to_console || s->server->forward_to_console) + forward_console(s->server, s->identifier, p, &s->ucred); + + IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout"); + + if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0) + IOVEC_SET_STRING(iovec[n++], syslog_priority); + + if (priority & LOG_FACMASK) + if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0) + IOVEC_SET_STRING(iovec[n++], syslog_facility); + + if (s->identifier) { + syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier); + if (syslog_identifier) + IOVEC_SET_STRING(iovec[n++], syslog_identifier); + } + + message = strappend("MESSAGE=", p); + if (message) + IOVEC_SET_STRING(iovec[n++], message); + + dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, priority); + + free(message); + free(syslog_priority); + free(syslog_facility); + free(syslog_identifier); + + return 0; +} + +static int stdout_stream_line(StdoutStream *s, char *p) { + int r; + + assert(s); + assert(p); + + p = strstrip(p); + + switch (s->state) { + + case STDOUT_STREAM_IDENTIFIER: + if (isempty(p)) + s->identifier = NULL; + else { + s->identifier = strdup(p); + if (!s->identifier) { + log_error("Out of memory"); + return -ENOMEM; + } + } + + s->state = STDOUT_STREAM_PRIORITY; + return 0; + + case STDOUT_STREAM_PRIORITY: + r = safe_atoi(p, &s->priority); + if (r < 0 || s->priority <= 0 || s->priority >= 999) { + log_warning("Failed to parse log priority line."); + return -EINVAL; + } + + s->state = STDOUT_STREAM_LEVEL_PREFIX; + return 0; + + case STDOUT_STREAM_LEVEL_PREFIX: + r = parse_boolean(p); + if (r < 0) { + log_warning("Failed to parse level prefix line."); + return -EINVAL; + } + + s->level_prefix = !!r; + s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG; + return 0; + + case STDOUT_STREAM_FORWARD_TO_SYSLOG: + r = parse_boolean(p); + if (r < 0) { + log_warning("Failed to parse forward to syslog line."); + return -EINVAL; + } + + s->forward_to_syslog = !!r; + s->state = STDOUT_STREAM_FORWARD_TO_KMSG; + return 0; + + case STDOUT_STREAM_FORWARD_TO_KMSG: + r = parse_boolean(p); + if (r < 0) { + log_warning("Failed to parse copy to kmsg line."); + return -EINVAL; + } + + s->forward_to_kmsg = !!r; + s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE; + return 0; + + case STDOUT_STREAM_FORWARD_TO_CONSOLE: + r = parse_boolean(p); + if (r < 0) { + log_warning("Failed to parse copy to console line."); + return -EINVAL; + } + + s->forward_to_console = !!r; + s->state = STDOUT_STREAM_RUNNING; + return 0; + + case STDOUT_STREAM_RUNNING: + return stdout_stream_log(s, p); + } + + assert_not_reached("Unknown stream state"); +} + +static int stdout_stream_scan(StdoutStream *s, bool force_flush) { + char *p; + size_t remaining; + int r; + + assert(s); + + p = s->buffer; + remaining = s->length; + for (;;) { + char *end; + size_t skip; + + end = memchr(p, '\n', remaining); + if (end) + skip = end - p + 1; + else if (remaining >= sizeof(s->buffer) - 1) { + end = p + sizeof(s->buffer) - 1; + skip = remaining; + } else + break; + + *end = 0; + + r = stdout_stream_line(s, p); + if (r < 0) + return r; + + remaining -= skip; + p += skip; + } + + if (force_flush && remaining > 0) { + p[remaining] = 0; + r = stdout_stream_line(s, p); + if (r < 0) + return r; + + p += remaining; + remaining = 0; + } + + if (p > s->buffer) { + memmove(s->buffer, p, remaining); + s->length = remaining; + } + + return 0; +} + +static int stdout_stream_process(StdoutStream *s) { + ssize_t l; + int r; + + assert(s); + + l = read(s->fd, s->buffer+s->length, sizeof(s->buffer)-1-s->length); + if (l < 0) { + + if (errno == EAGAIN) + return 0; + + log_warning("Failed to read from stream: %m"); + return -errno; + } + + if (l == 0) { + r = stdout_stream_scan(s, true); + if (r < 0) + return r; + + return 0; + } + + s->length += l; + r = stdout_stream_scan(s, false); + if (r < 0) + return r; + + return 1; + +} + +static void stdout_stream_free(StdoutStream *s) { + assert(s); + + if (s->server) { + assert(s->server->n_stdout_streams > 0); + s->server->n_stdout_streams --; + LIST_REMOVE(StdoutStream, stdout_stream, s->server->stdout_streams, s); + } + + if (s->fd >= 0) { + if (s->server) + epoll_ctl(s->server->epoll_fd, EPOLL_CTL_DEL, s->fd, NULL); + + close_nointr_nofail(s->fd); + } + + free(s->identifier); + free(s); +} + +static int stdout_stream_new(Server *s) { + StdoutStream *stream; + int fd, r; + socklen_t len; + struct epoll_event ev; + + assert(s); + + fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC); + if (fd < 0) { + if (errno == EAGAIN) + return 0; + + log_error("Failed to accept stdout connection: %m"); + return -errno; + } + + if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) { + log_warning("Too many stdout streams, refusing connection."); + close_nointr_nofail(fd); + return 0; + } + + stream = new0(StdoutStream, 1); + if (!stream) { + log_error("Out of memory."); + close_nointr_nofail(fd); + return -ENOMEM; + } + + stream->fd = fd; + + len = sizeof(stream->ucred); + if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &stream->ucred, &len) < 0) { + log_error("Failed to determine peer credentials: %m"); + r = -errno; + goto fail; + } + + if (shutdown(fd, SHUT_WR) < 0) { + log_error("Failed to shutdown writing side of socket: %m"); + r = -errno; + goto fail; + } + + zero(ev); + ev.data.ptr = stream; + ev.events = EPOLLIN; + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) { + log_error("Failed to add stream to event loop: %m"); + r = -errno; + goto fail; + } + + stream->server = s; + LIST_PREPEND(StdoutStream, stdout_stream, s->stdout_streams, stream); + s->n_stdout_streams ++; + + return 0; + +fail: + stdout_stream_free(stream); + return r; +} + +static int parse_kernel_timestamp(char **_p, usec_t *t) { + usec_t r; + int k, i; + char *p; + + assert(_p); + assert(*_p); + assert(t); + + p = *_p; + + if (strlen(p) < 14 || p[0] != '[' || p[13] != ']' || p[6] != '.') + return 0; + + r = 0; + + for (i = 1; i <= 5; i++) { + r *= 10; + + if (p[i] == ' ') + continue; + + k = undecchar(p[i]); + if (k < 0) + return 0; + + r += k; + } + + for (i = 7; i <= 12; i++) { + r *= 10; + + k = undecchar(p[i]); + if (k < 0) + return 0; + + r += k; + } + + *t = r; + *_p += 14; + *_p += strspn(*_p, WHITESPACE); + + return 1; +} + +static void proc_kmsg_line(Server *s, const char *p) { + struct iovec iovec[N_IOVEC_META_FIELDS + 7]; + char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL; + int priority = LOG_KERN | LOG_INFO; + unsigned n = 0; + usec_t usec; + char *identifier = NULL, *pid = NULL; + + assert(s); + assert(p); + + if (isempty(p)) + return; + + parse_syslog_priority((char **) &p, &priority); + + if (s->forward_to_kmsg && (priority & LOG_FACMASK) != LOG_KERN) + return; + + if (parse_kernel_timestamp((char **) &p, &usec) > 0) { + if (asprintf(&source_time, "_SOURCE_MONOTONIC_TIMESTAMP=%llu", + (unsigned long long) usec) >= 0) + IOVEC_SET_STRING(iovec[n++], source_time); + } + + IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=kernel"); + + if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0) + IOVEC_SET_STRING(iovec[n++], syslog_priority); + + if ((priority & LOG_FACMASK) == LOG_KERN) { + + if (s->forward_to_syslog) + forward_syslog(s, priority, "kernel", p, NULL, NULL); + + IOVEC_SET_STRING(iovec[n++], "SYSLOG_IDENTIFIER=kernel"); + } else { + read_identifier(&p, &identifier, &pid); + + if (s->forward_to_syslog) + forward_syslog(s, priority, identifier, p, NULL, NULL); + + if (identifier) { + syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier); + if (syslog_identifier) + IOVEC_SET_STRING(iovec[n++], syslog_identifier); + } + + if (pid) { + syslog_pid = strappend("SYSLOG_PID=", pid); + if (syslog_pid) + IOVEC_SET_STRING(iovec[n++], syslog_pid); + } + + if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0) + IOVEC_SET_STRING(iovec[n++], syslog_facility); + } + + message = strappend("MESSAGE=", p); + if (message) + IOVEC_SET_STRING(iovec[n++], message); + + dispatch_message(s, iovec, n, ELEMENTSOF(iovec), NULL, NULL, priority); + + free(message); + free(syslog_priority); + free(syslog_identifier); + free(syslog_pid); + free(syslog_facility); + free(source_time); + free(identifier); + free(pid); +} + +static void proc_kmsg_scan(Server *s) { + char *p; + size_t remaining; + + assert(s); + + p = s->proc_kmsg_buffer; + remaining = s->proc_kmsg_length; + for (;;) { + char *end; + size_t skip; + + end = memchr(p, '\n', remaining); + if (end) + skip = end - p + 1; + else if (remaining >= sizeof(s->proc_kmsg_buffer) - 1) { + end = p + sizeof(s->proc_kmsg_buffer) - 1; + skip = remaining; + } else + break; + + *end = 0; + + proc_kmsg_line(s, p); + + remaining -= skip; + p += skip; + } + + if (p > s->proc_kmsg_buffer) { + memmove(s->proc_kmsg_buffer, p, remaining); + s->proc_kmsg_length = remaining; + } +} + +static int system_journal_open(Server *s) { + int r; + char *fn; + sd_id128_t machine; + char ids[33]; + + r = sd_id128_get_machine(&machine); + if (r < 0) + return r; + + sd_id128_to_string(machine, ids); + + if (!s->system_journal) { + + /* First try to create the machine path, but not the prefix */ + fn = strappend("/var/log/journal/", ids); + if (!fn) + return -ENOMEM; + (void) mkdir(fn, 0755); + free(fn); + + /* The create the system journal file */ + fn = join("/var/log/journal/", ids, "/system.journal", NULL); + if (!fn) + return -ENOMEM; + + r = journal_file_open(fn, O_RDWR|O_CREAT, 0640, NULL, &s->system_journal); + free(fn); + + if (r >= 0) { + journal_default_metrics(&s->system_metrics, s->system_journal->fd); + + s->system_journal->metrics = s->system_metrics; + s->system_journal->compress = s->compress; + + server_fix_perms(s, s->system_journal, 0); + } else if (r < 0) { + + if (r != -ENOENT && r != -EROFS) + log_warning("Failed to open system journal: %s", strerror(-r)); + + r = 0; + } + } + + if (!s->runtime_journal) { + + fn = join("/run/log/journal/", ids, "/system.journal", NULL); + if (!fn) + return -ENOMEM; + + if (s->system_journal) { + + /* Try to open the runtime journal, but only + * if it already exists, so that we can flush + * it into the system journal */ + + r = journal_file_open(fn, O_RDWR, 0640, NULL, &s->runtime_journal); + free(fn); + + if (r < 0) { + if (r != -ENOENT) + log_warning("Failed to open runtime journal: %s", strerror(-r)); + + r = 0; + } + + } else { + + /* OK, we really need the runtime journal, so create + * it if necessary. */ + + (void) mkdir_parents(fn, 0755); + r = journal_file_open(fn, O_RDWR|O_CREAT, 0640, NULL, &s->runtime_journal); + free(fn); + + if (r < 0) { + log_error("Failed to open runtime journal: %s", strerror(-r)); + return r; + } + } + + if (s->runtime_journal) { + journal_default_metrics(&s->runtime_metrics, s->runtime_journal->fd); + + s->runtime_journal->metrics = s->runtime_metrics; + s->runtime_journal->compress = s->compress; + + server_fix_perms(s, s->runtime_journal, 0); + } + } + + return r; +} + +static int server_flush_to_var(Server *s) { + char path[] = "/run/log/journal/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; + Object *o = NULL; + int r; + sd_id128_t machine; + sd_journal *j; + usec_t ts; + + assert(s); + + if (!s->runtime_journal) + return 0; + + ts = now(CLOCK_MONOTONIC); + if (s->var_available_timestamp + RECHECK_VAR_AVAILABLE_USEC > ts) + return 0; + + s->var_available_timestamp = ts; + + system_journal_open(s); + + if (!s->system_journal) + return 0; + + log_info("Flushing to /var..."); + + r = sd_id128_get_machine(&machine); + if (r < 0) { + log_error("Failed to get machine id: %s", strerror(-r)); + return r; + } + + r = sd_journal_open(&j, SD_JOURNAL_RUNTIME_ONLY); + if (r < 0) { + log_error("Failed to read runtime journal: %s", strerror(-r)); + return r; + } + + SD_JOURNAL_FOREACH(j) { + JournalFile *f; + + f = j->current_file; + assert(f && f->current_offset > 0); + + r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); + if (r < 0) { + log_error("Can't read entry: %s", strerror(-r)); + goto finish; + } + + r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL); + if (r == -E2BIG) { + log_info("Allocation limit reached."); + + journal_file_post_change(s->system_journal); + server_rotate(s); + server_vacuum(s); + + r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL); + } + + if (r < 0) { + log_error("Can't write entry: %s", strerror(-r)); + goto finish; + } + } + +finish: + journal_file_post_change(s->system_journal); + + journal_file_close(s->runtime_journal); + s->runtime_journal = NULL; + + if (r >= 0) { + sd_id128_to_string(machine, path + 17); + rm_rf(path, false, true, false); + } + + return r; +} + +static int server_read_proc_kmsg(Server *s) { + ssize_t l; + assert(s); + assert(s->proc_kmsg_fd >= 0); + + l = read(s->proc_kmsg_fd, s->proc_kmsg_buffer + s->proc_kmsg_length, sizeof(s->proc_kmsg_buffer) - 1 - s->proc_kmsg_length); + if (l < 0) { + + if (errno == EAGAIN || errno == EINTR) + return 0; + + log_error("Failed to read from kernel: %m"); + return -errno; + } + + s->proc_kmsg_length += l; + + proc_kmsg_scan(s); + return 1; +} + +static int server_flush_proc_kmsg(Server *s) { + int r; + + assert(s); + + if (s->proc_kmsg_fd < 0) + return 0; + + log_info("Flushing /proc/kmsg..."); + + for (;;) { + r = server_read_proc_kmsg(s); + if (r < 0) + return r; + + if (r == 0) + break; + } + + return 0; +} + +static int process_event(Server *s, struct epoll_event *ev) { + assert(s); + + if (ev->data.fd == s->signal_fd) { + struct signalfd_siginfo sfsi; + ssize_t n; + + if (ev->events != EPOLLIN) { + log_info("Got invalid event from epoll."); + return -EIO; + } + + n = read(s->signal_fd, &sfsi, sizeof(sfsi)); + if (n != sizeof(sfsi)) { + + if (n >= 0) + return -EIO; + + if (errno == EINTR || errno == EAGAIN) + return 1; + + return -errno; + } + + if (sfsi.ssi_signo == SIGUSR1) { + server_flush_to_var(s); + return 0; + } + + log_debug("Received SIG%s", signal_to_string(sfsi.ssi_signo)); + return 0; + + } else if (ev->data.fd == s->proc_kmsg_fd) { + int r; + + if (ev->events != EPOLLIN) { + log_info("Got invalid event from epoll."); + return -EIO; + } + + r = server_read_proc_kmsg(s); + if (r < 0) + return r; + + return 1; + + } else if (ev->data.fd == s->native_fd || + ev->data.fd == s->syslog_fd) { + + if (ev->events != EPOLLIN) { + log_info("Got invalid event from epoll."); + return -EIO; + } + + for (;;) { + struct msghdr msghdr; + struct iovec iovec; + struct ucred *ucred = NULL; + struct timeval *tv = NULL; + struct cmsghdr *cmsg; + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) + + CMSG_SPACE(sizeof(struct timeval)) + + CMSG_SPACE(sizeof(int))]; + } control; + ssize_t n; + int v; + int *fds = NULL; + unsigned n_fds = 0; + + if (ioctl(ev->data.fd, SIOCINQ, &v) < 0) { + log_error("SIOCINQ failed: %m"); + return -errno; + } + + if (s->buffer_size < (size_t) v) { + void *b; + size_t l; + + l = MAX(LINE_MAX + (size_t) v, s->buffer_size * 2); + b = realloc(s->buffer, l+1); + + if (!b) { + log_error("Couldn't increase buffer."); + return -ENOMEM; + } + + s->buffer_size = l; + s->buffer = b; + } + + zero(iovec); + iovec.iov_base = s->buffer; + iovec.iov_len = s->buffer_size; + + zero(control); + zero(msghdr); + msghdr.msg_iov = &iovec; + msghdr.msg_iovlen = 1; + msghdr.msg_control = &control; + msghdr.msg_controllen = sizeof(control); + + n = recvmsg(ev->data.fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (n < 0) { + + if (errno == EINTR || errno == EAGAIN) + return 1; + + log_error("recvmsg() failed: %m"); + return -errno; + } + + for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) { + + if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_CREDENTIALS && + cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) + ucred = (struct ucred*) CMSG_DATA(cmsg); + else if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SO_TIMESTAMP && + cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) + tv = (struct timeval*) CMSG_DATA(cmsg); + else if (cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_RIGHTS) { + fds = (int*) CMSG_DATA(cmsg); + n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int); + } + } + + if (ev->data.fd == s->syslog_fd) { + char *e; + + if (n > 0 && n_fds == 0) { + e = memchr(s->buffer, '\n', n); + if (e) + *e = 0; + else + s->buffer[n] = 0; + + process_syslog_message(s, strstrip(s->buffer), ucred, tv); + } else if (n_fds > 0) + log_warning("Got file descriptors via syslog socket. Ignoring."); + + } else { + if (n > 0 && n_fds == 0) + process_native_message(s, s->buffer, n, ucred, tv); + else if (n == 0 && n_fds == 1) + process_native_file(s, fds[0], ucred, tv); + else if (n_fds > 0) + log_warning("Got too many file descriptors via native socket. Ignoring."); + } + + close_many(fds, n_fds); + } + + return 1; + + } else if (ev->data.fd == s->stdout_fd) { + + if (ev->events != EPOLLIN) { + log_info("Got invalid event from epoll."); + return -EIO; + } + + stdout_stream_new(s); + return 1; + + } else { + StdoutStream *stream; + + if ((ev->events|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) { + log_info("Got invalid event from epoll."); + return -EIO; + } + + /* If it is none of the well-known fds, it must be an + * stdout stream fd. Note that this is a bit ugly here + * (since we rely that none of the well-known fds + * could be interpreted as pointer), but nonetheless + * safe, since the well-known fds would never get an + * fd > 4096, i.e. beyond the first memory page */ + + stream = ev->data.ptr; + + if (stdout_stream_process(stream) <= 0) + stdout_stream_free(stream); + + return 1; + } + + log_error("Unknown event."); + return 0; +} + +static int open_syslog_socket(Server *s) { + union sockaddr_union sa; + int one, r; + struct epoll_event ev; + + assert(s); + + if (s->syslog_fd < 0) { + + s->syslog_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + if (s->syslog_fd < 0) { + log_error("socket() failed: %m"); + return -errno; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/dev/log", sizeof(sa.un.sun_path)); + + unlink(sa.un.sun_path); + + r = bind(s->syslog_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); + if (r < 0) { + log_error("bind() failed: %m"); + return -errno; + } + + chmod(sa.un.sun_path, 0666); + } else + fd_nonblock(s->syslog_fd, 1); + + one = 1; + r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); + if (r < 0) { + log_error("SO_PASSCRED failed: %m"); + return -errno; + } + + one = 1; + r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)); + if (r < 0) { + log_error("SO_TIMESTAMP failed: %m"); + return -errno; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.fd = s->syslog_fd; + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->syslog_fd, &ev) < 0) { + log_error("Failed to add syslog server fd to epoll object: %m"); + return -errno; + } + + return 0; +} + +static int open_native_socket(Server*s) { + union sockaddr_union sa; + int one, r; + struct epoll_event ev; + + assert(s); + + if (s->native_fd < 0) { + + s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + if (s->native_fd < 0) { + log_error("socket() failed: %m"); + return -errno; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path)); + + unlink(sa.un.sun_path); + + r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); + if (r < 0) { + log_error("bind() failed: %m"); + return -errno; + } + + chmod(sa.un.sun_path, 0666); + } else + fd_nonblock(s->native_fd, 1); + + one = 1; + r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); + if (r < 0) { + log_error("SO_PASSCRED failed: %m"); + return -errno; + } + + one = 1; + r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)); + if (r < 0) { + log_error("SO_TIMESTAMP failed: %m"); + return -errno; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.fd = s->native_fd; + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->native_fd, &ev) < 0) { + log_error("Failed to add native server fd to epoll object: %m"); + return -errno; + } + + return 0; +} + +static int open_stdout_socket(Server *s) { + union sockaddr_union sa; + int r; + struct epoll_event ev; + + assert(s); + + if (s->stdout_fd < 0) { + + s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + if (s->stdout_fd < 0) { + log_error("socket() failed: %m"); + return -errno; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path)); + + unlink(sa.un.sun_path); + + r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); + if (r < 0) { + log_error("bind() failed: %m"); + return -errno; + } + + chmod(sa.un.sun_path, 0666); + + if (listen(s->stdout_fd, SOMAXCONN) < 0) { + log_error("liste() failed: %m"); + return -errno; + } + } else + fd_nonblock(s->stdout_fd, 1); + + zero(ev); + ev.events = EPOLLIN; + ev.data.fd = s->stdout_fd; + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->stdout_fd, &ev) < 0) { + log_error("Failed to add stdout server fd to epoll object: %m"); + return -errno; + } + + return 0; +} + +static int open_proc_kmsg(Server *s) { + struct epoll_event ev; + + assert(s); + + if (!s->import_proc_kmsg) + return 0; + + + s->proc_kmsg_fd = open("/proc/kmsg", O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + if (s->proc_kmsg_fd < 0) { + log_warning("Failed to open /proc/kmsg, ignoring: %m"); + return 0; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.fd = s->proc_kmsg_fd; + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->proc_kmsg_fd, &ev) < 0) { + log_error("Failed to add /proc/kmsg fd to epoll object: %m"); + return -errno; + } + + return 0; +} + +static int open_signalfd(Server *s) { + sigset_t mask; + struct epoll_event ev; + + assert(s); + + assert_se(sigemptyset(&mask) == 0); + sigset_add_many(&mask, SIGINT, SIGTERM, SIGUSR1, -1); + assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); + + s->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC); + if (s->signal_fd < 0) { + log_error("signalfd(): %m"); + return -errno; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.fd = s->signal_fd; + + if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->signal_fd, &ev) < 0) { + log_error("epoll_ctl(): %m"); + return -errno; + } + + return 0; +} + +static int server_parse_proc_cmdline(Server *s) { + char *line, *w, *state; + int r; + size_t l; + + if (detect_container(NULL) > 0) + return 0; + + r = read_one_line_file("/proc/cmdline", &line); + if (r < 0) { + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return 0; + } + + FOREACH_WORD_QUOTED(w, l, line, state) { + char *word; + + word = strndup(w, l); + if (!word) { + r = -ENOMEM; + goto finish; + } + + if (startswith(word, "systemd_journald.forward_to_syslog=")) { + r = parse_boolean(word + 35); + if (r < 0) + log_warning("Failed to parse forward to syslog switch %s. Ignoring.", word + 35); + else + s->forward_to_syslog = r; + } else if (startswith(word, "systemd_journald.forward_to_kmsg=")) { + r = parse_boolean(word + 33); + if (r < 0) + log_warning("Failed to parse forward to kmsg switch %s. Ignoring.", word + 33); + else + s->forward_to_kmsg = r; + } else if (startswith(word, "systemd_journald.forward_to_console=")) { + r = parse_boolean(word + 36); + if (r < 0) + log_warning("Failed to parse forward to console switch %s. Ignoring.", word + 36); + else + s->forward_to_console = r; + } + + free(word); + } + + r = 0; + +finish: + free(line); + return r; +} + +static int server_parse_config_file(Server *s) { + FILE *f; + const char *fn; + int r; + + assert(s); + + fn = "/etc/systemd/systemd-journald.conf"; + f = fopen(fn, "re"); + if (!f) { + if (errno == ENOENT) + return 0; + + log_warning("Failed to open configuration file %s: %m", fn); + return -errno; + } + + r = config_parse(fn, f, "Journal\0", config_item_perf_lookup, (void*) journald_gperf_lookup, false, s); + if (r < 0) + log_warning("Failed to parse configuration file: %s", strerror(-r)); + + fclose(f); + + return r; +} + +static int server_init(Server *s) { + int n, r, fd; + + assert(s); + + zero(*s); + s->syslog_fd = s->native_fd = s->stdout_fd = s->signal_fd = s->epoll_fd = s->proc_kmsg_fd = -1; + s->compress = true; + + s->rate_limit_interval = DEFAULT_RATE_LIMIT_INTERVAL; + s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST; + + s->forward_to_syslog = true; + s->import_proc_kmsg = true; + + memset(&s->system_metrics, 0xFF, sizeof(s->system_metrics)); + memset(&s->runtime_metrics, 0xFF, sizeof(s->runtime_metrics)); + + server_parse_config_file(s); + server_parse_proc_cmdline(s); + + s->user_journals = hashmap_new(trivial_hash_func, trivial_compare_func); + if (!s->user_journals) { + log_error("Out of memory."); + return -ENOMEM; + } + + s->epoll_fd = epoll_create1(EPOLL_CLOEXEC); + if (s->epoll_fd < 0) { + log_error("Failed to create epoll object: %m"); + return -errno; + } + + n = sd_listen_fds(true); + if (n < 0) { + log_error("Failed to read listening file descriptors from environment: %s", strerror(-n)); + return n; + } + + for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) { + + if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/run/systemd/journal/socket", 0) > 0) { + + if (s->native_fd >= 0) { + log_error("Too many native sockets passed."); + return -EINVAL; + } + + s->native_fd = fd; + + } else if (sd_is_socket_unix(fd, SOCK_STREAM, 1, "/run/systemd/journal/stdout", 0) > 0) { + + if (s->stdout_fd >= 0) { + log_error("Too many stdout sockets passed."); + return -EINVAL; + } + + s->stdout_fd = fd; + + } else if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/dev/log", 0) > 0) { + + if (s->syslog_fd >= 0) { + log_error("Too many /dev/log sockets passed."); + return -EINVAL; + } + + s->syslog_fd = fd; + + } else { + log_error("Unknown socket passed."); + return -EINVAL; + } + } + + r = open_syslog_socket(s); + if (r < 0) + return r; + + r = open_native_socket(s); + if (r < 0) + return r; + + r = open_stdout_socket(s); + if (r < 0) + return r; + + r = open_proc_kmsg(s); + if (r < 0) + return r; + + r = system_journal_open(s); + if (r < 0) + return r; + + r = open_signalfd(s); + if (r < 0) + return r; + + s->rate_limit = journal_rate_limit_new(s->rate_limit_interval, s->rate_limit_burst); + if (!s->rate_limit) + return -ENOMEM; + + return 0; +} + +static void server_done(Server *s) { + JournalFile *f; + assert(s); + + while (s->stdout_streams) + stdout_stream_free(s->stdout_streams); + + if (s->system_journal) + journal_file_close(s->system_journal); + + if (s->runtime_journal) + journal_file_close(s->runtime_journal); + + while ((f = hashmap_steal_first(s->user_journals))) + journal_file_close(f); + + hashmap_free(s->user_journals); + + if (s->epoll_fd >= 0) + close_nointr_nofail(s->epoll_fd); + + if (s->signal_fd >= 0) + close_nointr_nofail(s->signal_fd); + + if (s->syslog_fd >= 0) + close_nointr_nofail(s->syslog_fd); + + if (s->native_fd >= 0) + close_nointr_nofail(s->native_fd); + + if (s->stdout_fd >= 0) + close_nointr_nofail(s->stdout_fd); + + if (s->proc_kmsg_fd >= 0) + close_nointr_nofail(s->proc_kmsg_fd); + + if (s->rate_limit) + journal_rate_limit_free(s->rate_limit); + + free(s->buffer); +} + +int main(int argc, char *argv[]) { + Server server; + int r; + + /* if (getppid() != 1) { */ + /* log_error("This program should be invoked by init only."); */ + /* return EXIT_FAILURE; */ + /* } */ + + if (argc > 1) { + log_error("This program does not take arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_CONSOLE); + log_parse_environment(); + log_open(); + + umask(0022); + + r = server_init(&server); + if (r < 0) + goto finish; + + server_vacuum(&server); + server_flush_to_var(&server); + server_flush_proc_kmsg(&server); + + log_debug("systemd-journald running as pid %lu", (unsigned long) getpid()); + driver_message(&server, SD_MESSAGE_JOURNAL_START, "Journal started"); + + sd_notify(false, + "READY=1\n" + "STATUS=Processing requests..."); + + for (;;) { + struct epoll_event event; + + r = epoll_wait(server.epoll_fd, &event, 1, -1); + if (r < 0) { + + if (errno == EINTR) + continue; + + log_error("epoll_wait() failed: %m"); + r = -errno; + goto finish; + } else if (r == 0) + break; + + r = process_event(&server, &event); + if (r < 0) + goto finish; + else if (r == 0) + break; + } + + log_debug("systemd-journald stopped as pid %lu", (unsigned long) getpid()); + driver_message(&server, SD_MESSAGE_JOURNAL_STOP, "Journal stopped"); + +finish: + sd_notify(false, + "STATUS=Shutting down..."); + + server_done(&server); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/journal/journald.h b/src/journal/journald.h new file mode 100644 index 0000000..6160991 --- /dev/null +++ b/src/journal/journald.h @@ -0,0 +1,86 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foojournaldhfoo +#define foojournaldhfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "journal-file.h" +#include "hashmap.h" +#include "util.h" +#include "journal-rate-limit.h" +#include "list.h" + +typedef struct StdoutStream StdoutStream; + +typedef struct Server { + int epoll_fd; + int signal_fd; + int syslog_fd; + int native_fd; + int stdout_fd; + int proc_kmsg_fd; + + JournalFile *runtime_journal; + JournalFile *system_journal; + Hashmap *user_journals; + + uint64_t seqnum; + + char *buffer; + size_t buffer_size; + + JournalRateLimit *rate_limit; + usec_t rate_limit_interval; + unsigned rate_limit_burst; + + JournalMetrics runtime_metrics; + JournalMetrics system_metrics; + + bool compress; + + bool forward_to_kmsg; + bool forward_to_syslog; + bool forward_to_console; + + bool import_proc_kmsg; + char proc_kmsg_buffer[LINE_MAX+1]; + size_t proc_kmsg_length; + + uint64_t cached_available_space; + usec_t cached_available_space_timestamp; + + uint64_t var_available_timestamp; + + gid_t file_gid; + bool file_gid_valid; + + LIST_HEAD(StdoutStream, stdout_streams); + unsigned n_stdout_streams; +} Server; + +/* gperf lookup function */ +const struct ConfigPerfItem* journald_gperf_lookup(const char *key, unsigned length); + +#endif diff --git a/src/journal/libsystemd-journal.pc.in b/src/journal/libsystemd-journal.pc.in new file mode 100644 index 0000000..13cc820 --- /dev/null +++ b/src/journal/libsystemd-journal.pc.in @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd 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. + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: systemd +Description: systemd Journal Utility Library +URL: @PACKAGE_URL@ +Version: @PACKAGE_VERSION@ +Requires: libsystemd-id128 = @PACKAGE_VERSION@ +Libs: -L${libdir} -lsystemd-journal +Cflags: -I${includedir} diff --git a/src/journal/libsystemd-journal.sym b/src/journal/libsystemd-journal.sym new file mode 100644 index 0000000..7653880 --- /dev/null +++ b/src/journal/libsystemd-journal.sym @@ -0,0 +1,45 @@ +/*** + This file is part of systemd. + + systemd 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. +***/ + +/* Original symbols from systemd v38 */ + +LIBSYSTEMD_JOURNAL_38 { +global: + sd_journal_print; + sd_journal_printv; + sd_journal_send; + sd_journal_sendv; + sd_journal_stream_fd; + sd_journal_open; + sd_journal_close; + sd_journal_previous; + sd_journal_next; + sd_journal_previous_skip; + sd_journal_next_skip; + sd_journal_get_realtime_usec; + sd_journal_get_monotonic_usec; + sd_journal_get_data; + sd_journal_enumerate_data; + sd_journal_restart_data; + sd_journal_add_match; + sd_journal_flush_matches; + sd_journal_seek_head; + sd_journal_seek_tail; + sd_journal_seek_monotonic_usec; + sd_journal_seek_realtime_usec; + sd_journal_seek_cursor; + sd_journal_get_cursor; + sd_journal_query_unique; + sd_journal_enumerate_unique; + sd_journal_restart_unique; + sd_journal_get_fd; + sd_journal_process; +local: + *; +}; diff --git a/src/journal/lookup3.c b/src/journal/lookup3.c new file mode 100644 index 0000000..b90093a --- /dev/null +++ b/src/journal/lookup3.c @@ -0,0 +1,1003 @@ +/* Slightly modified by Lennart Poettering, to avoid name clashes, and + * unexport a few functions. */ + +#include "lookup3.h" + +/* +------------------------------------------------------------------------------- +lookup3.c, by Bob Jenkins, May 2006, Public Domain. + +These are functions for producing 32-bit hashes for hash table lookup. +hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() +are externally useful functions. Routines to test the hash are included +if SELF_TEST is defined. You can use this free for any purpose. It's in +the public domain. It has no warranty. + +You probably want to use hashlittle(). hashlittle() and hashbig() +hash byte arrays. hashlittle() is is faster than hashbig() on +little-endian machines. Intel and AMD are little-endian machines. +On second thought, you probably want hashlittle2(), which is identical to +hashlittle() except it returns two 32-bit hashes for the price of one. +You could implement hashbig2() if you wanted but I haven't bothered here. + +If you want to find a hash of, say, exactly 7 integers, do + a = i1; b = i2; c = i3; + mix(a,b,c); + a += i4; b += i5; c += i6; + mix(a,b,c); + a += i7; + final(a,b,c); +then use c as the hash value. If you have a variable length array of +4-byte integers to hash, use hashword(). If you have a byte array (like +a character string), use hashlittle(). If you have several byte arrays, or +a mix of things, see the comments above hashlittle(). + +Why is this so big? I read 12 bytes at a time into 3 4-byte integers, +then mix those integers. This is fast (you can do a lot more thorough +mixing with 12*3 instructions on 3 integers than you can with 3 instructions +on 1 byte), but shoehorning those bytes into integers efficiently is messy. +------------------------------------------------------------------------------- +*/ +/* #define SELF_TEST 1 */ + +#include /* defines printf for tests */ +#include /* defines time_t for timings in the test */ +#include /* defines uint32_t etc */ +#include /* attempt to define endianness */ +#ifdef linux +# include /* attempt to define endianness */ +#endif + +/* + * My best guess at if you are big-endian or little-endian. This may + * need adjustment. + */ +#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ + __BYTE_ORDER == __LITTLE_ENDIAN) || \ + (defined(i386) || defined(__i386__) || defined(__i486__) || \ + defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL)) +# define HASH_LITTLE_ENDIAN 1 +# define HASH_BIG_ENDIAN 0 +#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ + __BYTE_ORDER == __BIG_ENDIAN) || \ + (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) +# define HASH_LITTLE_ENDIAN 0 +# define HASH_BIG_ENDIAN 1 +#else +# define HASH_LITTLE_ENDIAN 0 +# define HASH_BIG_ENDIAN 0 +#endif + +#define hashsize(n) ((uint32_t)1<<(n)) +#define hashmask(n) (hashsize(n)-1) +#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) + +/* +------------------------------------------------------------------------------- +mix -- mix 3 32-bit values reversibly. + +This is reversible, so any information in (a,b,c) before mix() is +still in (a,b,c) after mix(). + +If four pairs of (a,b,c) inputs are run through mix(), or through +mix() in reverse, there are at least 32 bits of the output that +are sometimes the same for one pair and different for another pair. +This was tested for: +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that +satisfy this are + 4 6 8 16 19 4 + 9 15 3 18 27 15 + 14 9 3 7 17 3 +Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing +for "differ" defined as + with a one-bit base and a two-bit delta. I +used http://burtleburtle.net/bob/hash/avalanche.html to choose +the operations, constants, and arrangements of the variables. + +This does not achieve avalanche. There are input bits of (a,b,c) +that fail to affect some output bits of (a,b,c), especially of a. The +most thoroughly mixed value is c, but it doesn't really even achieve +avalanche in c. + +This allows some parallelism. Read-after-writes are good at doubling +the number of bits affected, so the goal of mixing pulls in the opposite +direction as the goal of parallelism. I did what I could. Rotates +seem to cost as much as shifts on every machine I could lay my hands +on, and rotates are much kinder to the top and bottom bits, so I used +rotates. +------------------------------------------------------------------------------- +*/ +#define mix(a,b,c) \ +{ \ + a -= c; a ^= rot(c, 4); c += b; \ + b -= a; b ^= rot(a, 6); a += c; \ + c -= b; c ^= rot(b, 8); b += a; \ + a -= c; a ^= rot(c,16); c += b; \ + b -= a; b ^= rot(a,19); a += c; \ + c -= b; c ^= rot(b, 4); b += a; \ +} + +/* +------------------------------------------------------------------------------- +final -- final mixing of 3 32-bit values (a,b,c) into c + +Pairs of (a,b,c) values differing in only a few bits will usually +produce values of c that look totally different. This was tested for +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +These constants passed: + 14 11 25 16 4 14 24 + 12 14 25 16 4 14 24 +and these came close: + 4 8 15 26 3 22 24 + 10 8 15 26 3 22 24 + 11 8 15 26 3 22 24 +------------------------------------------------------------------------------- +*/ +#define final(a,b,c) \ +{ \ + c ^= b; c -= rot(b,14); \ + a ^= c; a -= rot(c,11); \ + b ^= a; b -= rot(a,25); \ + c ^= b; c -= rot(b,16); \ + a ^= c; a -= rot(c,4); \ + b ^= a; b -= rot(a,14); \ + c ^= b; c -= rot(b,24); \ +} + +/* +-------------------------------------------------------------------- + This works on all machines. To be useful, it requires + -- that the key be an array of uint32_t's, and + -- that the length be the number of uint32_t's in the key + + The function hashword() is identical to hashlittle() on little-endian + machines, and identical to hashbig() on big-endian machines, + except that the length has to be measured in uint32_ts rather than in + bytes. hashlittle() is more complicated than hashword() only because + hashlittle() has to dance around fitting the key bytes into registers. +-------------------------------------------------------------------- +*/ +uint32_t jenkins_hashword( +const uint32_t *k, /* the key, an array of uint32_t values */ +size_t length, /* the length of the key, in uint32_ts */ +uint32_t initval) /* the previous hash, or an arbitrary value */ +{ + uint32_t a,b,c; + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + (((uint32_t)length)<<2) + initval; + + /*------------------------------------------------- handle most of the key */ + while (length > 3) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 3; + k += 3; + } + + /*------------------------------------------- handle the last 3 uint32_t's */ + switch(length) /* all the case statements fall through */ + { + case 3 : c+=k[2]; + case 2 : b+=k[1]; + case 1 : a+=k[0]; + final(a,b,c); + case 0: /* case 0: nothing left to add */ + break; + } + /*------------------------------------------------------ report the result */ + return c; +} + + +/* +-------------------------------------------------------------------- +hashword2() -- same as hashword(), but take two seeds and return two +32-bit values. pc and pb must both be nonnull, and *pc and *pb must +both be initialized with seeds. If you pass in (*pb)==0, the output +(*pc) will be the same as the return value from hashword(). +-------------------------------------------------------------------- +*/ +void jenkins_hashword2 ( +const uint32_t *k, /* the key, an array of uint32_t values */ +size_t length, /* the length of the key, in uint32_ts */ +uint32_t *pc, /* IN: seed OUT: primary hash value */ +uint32_t *pb) /* IN: more seed OUT: secondary hash value */ +{ + uint32_t a,b,c; + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)(length<<2)) + *pc; + c += *pb; + + /*------------------------------------------------- handle most of the key */ + while (length > 3) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 3; + k += 3; + } + + /*------------------------------------------- handle the last 3 uint32_t's */ + switch(length) /* all the case statements fall through */ + { + case 3 : c+=k[2]; + case 2 : b+=k[1]; + case 1 : a+=k[0]; + final(a,b,c); + case 0: /* case 0: nothing left to add */ + break; + } + /*------------------------------------------------------ report the result */ + *pc=c; *pb=b; +} + + +/* +------------------------------------------------------------------------------- +hashlittle() -- hash a variable-length key into a 32-bit value + k : the key (the unaligned variable-length array of bytes) + length : the length of the key, counting by bytes + initval : can be any 4-byte value +Returns a 32-bit value. Every bit of the key affects every bit of +the return value. Two keys differing by one or two bits will have +totally different hash values. + +The best hash table sizes are powers of 2. There is no need to do +mod a prime (mod is sooo slow!). If you need less than 32 bits, +use a bitmask. For example, if you need only 10 bits, do + h = (h & hashmask(10)); +In which case, the hash table should have hashsize(10) elements. + +If you are hashing n strings (uint8_t **)k, do it like this: + for (i=0, h=0; i 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff; a+=k[0]; break; + case 6 : b+=k[1]&0xffff; a+=k[0]; break; + case 5 : b+=k[1]&0xff; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff; break; + case 2 : a+=k[0]&0xffff; break; + case 1 : a+=k[0]&0xff; break; + case 0 : return c; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ + case 1 : a+=k8[0]; break; + case 0 : return c; + } + +#endif /* !valgrind */ + + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + /*--------------- all but last block: aligned reads and different mixing */ + while (length > 12) + { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + mix(a,b,c); + length -= 12; + k += 6; + } + + /*----------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[4]+(((uint32_t)k[5])<<16); + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=k[4]; + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=k[2]; + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=k[0]; + break; + case 1 : a+=k8[0]; + break; + case 0 : return c; /* zero length requires no mixing */ + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=((uint32_t)k[11])<<24; + case 11: c+=((uint32_t)k[10])<<16; + case 10: c+=((uint32_t)k[9])<<8; + case 9 : c+=k[8]; + case 8 : b+=((uint32_t)k[7])<<24; + case 7 : b+=((uint32_t)k[6])<<16; + case 6 : b+=((uint32_t)k[5])<<8; + case 5 : b+=k[4]; + case 4 : a+=((uint32_t)k[3])<<24; + case 3 : a+=((uint32_t)k[2])<<16; + case 2 : a+=((uint32_t)k[1])<<8; + case 1 : a+=k[0]; + break; + case 0 : return c; + } + } + + final(a,b,c); + return c; +} + + +/* + * hashlittle2: return 2 32-bit hash values + * + * This is identical to hashlittle(), except it returns two 32-bit hash + * values instead of just one. This is good enough for hash table + * lookup with 2^^64 buckets, or if you want a second hash if you're not + * happy with the first, or if you want a probably-unique 64-bit ID for + * the key. *pc is better mixed than *pb, so use *pc first. If you want + * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)". + */ +void jenkins_hashlittle2( + const void *key, /* the key to hash */ + size_t length, /* length of the key */ + uint32_t *pc, /* IN: primary initval, OUT: primary hash */ + uint32_t *pb) /* IN: secondary initval, OUT: secondary hash */ +{ + uint32_t a,b,c; /* internal state */ + union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc; + c += *pb; + + u.ptr = key; + if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { + const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ + + /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff; a+=k[0]; break; + case 6 : b+=k[1]&0xffff; a+=k[0]; break; + case 5 : b+=k[1]&0xff; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff; break; + case 2 : a+=k[0]&0xffff; break; + case 1 : a+=k[0]&0xff; break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ + case 1 : a+=k8[0]; break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + +#endif /* !valgrind */ + + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + /*--------------- all but last block: aligned reads and different mixing */ + while (length > 12) + { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + mix(a,b,c); + length -= 12; + k += 6; + } + + /*----------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[4]+(((uint32_t)k[5])<<16); + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=k[4]; + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=k[2]; + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=k[0]; + break; + case 1 : a+=k8[0]; + break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=((uint32_t)k[11])<<24; + case 11: c+=((uint32_t)k[10])<<16; + case 10: c+=((uint32_t)k[9])<<8; + case 9 : c+=k[8]; + case 8 : b+=((uint32_t)k[7])<<24; + case 7 : b+=((uint32_t)k[6])<<16; + case 6 : b+=((uint32_t)k[5])<<8; + case 5 : b+=k[4]; + case 4 : a+=((uint32_t)k[3])<<24; + case 3 : a+=((uint32_t)k[2])<<16; + case 2 : a+=((uint32_t)k[1])<<8; + case 1 : a+=k[0]; + break; + case 0 : *pc=c; *pb=b; return; /* zero length strings require no mixing */ + } + } + + final(a,b,c); + *pc=c; *pb=b; +} + + + +/* + * hashbig(): + * This is the same as hashword() on big-endian machines. It is different + * from hashlittle() on all machines. hashbig() takes advantage of + * big-endian byte ordering. + */ +uint32_t jenkins_hashbig( const void *key, size_t length, uint32_t initval) +{ + uint32_t a,b,c; + union { const void *ptr; size_t i; } u; /* to cast key to (size_t) happily */ + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; + + u.ptr = key; + if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { + const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ + + /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]<<8" actually reads beyond the end of the string, but + * then shifts out the part it's not allowed to read. Because the + * string is aligned, the illegal read is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff00; a+=k[0]; break; + case 6 : b+=k[1]&0xffff0000; a+=k[0]; break; + case 5 : b+=k[1]&0xff000000; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff00; break; + case 2 : a+=k[0]&0xffff0000; break; + case 1 : a+=k[0]&0xff000000; break; + case 0 : return c; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch(length) /* all the case statements fall through */ + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<8; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<16; /* fall through */ + case 9 : c+=((uint32_t)k8[8])<<24; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<8; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<16; /* fall through */ + case 5 : b+=((uint32_t)k8[4])<<24; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<8; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<16; /* fall through */ + case 1 : a+=((uint32_t)k8[0])<<24; break; + case 0 : return c; + } + +#endif /* !VALGRIND */ + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += ((uint32_t)k[0])<<24; + a += ((uint32_t)k[1])<<16; + a += ((uint32_t)k[2])<<8; + a += ((uint32_t)k[3]); + b += ((uint32_t)k[4])<<24; + b += ((uint32_t)k[5])<<16; + b += ((uint32_t)k[6])<<8; + b += ((uint32_t)k[7]); + c += ((uint32_t)k[8])<<24; + c += ((uint32_t)k[9])<<16; + c += ((uint32_t)k[10])<<8; + c += ((uint32_t)k[11]); + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=k[11]; + case 11: c+=((uint32_t)k[10])<<8; + case 10: c+=((uint32_t)k[9])<<16; + case 9 : c+=((uint32_t)k[8])<<24; + case 8 : b+=k[7]; + case 7 : b+=((uint32_t)k[6])<<8; + case 6 : b+=((uint32_t)k[5])<<16; + case 5 : b+=((uint32_t)k[4])<<24; + case 4 : a+=k[3]; + case 3 : a+=((uint32_t)k[2])<<8; + case 2 : a+=((uint32_t)k[1])<<16; + case 1 : a+=((uint32_t)k[0])<<24; + break; + case 0 : return c; + } + } + + final(a,b,c); + return c; +} + + +#ifdef SELF_TEST + +/* used for timings */ +void driver1() +{ + uint8_t buf[256]; + uint32_t i; + uint32_t h=0; + time_t a,z; + + time(&a); + for (i=0; i<256; ++i) buf[i] = 'x'; + for (i=0; i<1; ++i) + { + h = hashlittle(&buf[0],1,h); + } + time(&z); + if (z-a > 0) printf("time %d %.8x\n", z-a, h); +} + +/* check that every input bit changes every output bit half the time */ +#define HASHSTATE 1 +#define HASHLEN 1 +#define MAXPAIR 60 +#define MAXLEN 70 +void driver2() +{ + uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1]; + uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z; + uint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE]; + uint32_t x[HASHSTATE],y[HASHSTATE]; + uint32_t hlen; + + printf("No more than %d trials should ever be needed \n",MAXPAIR/2); + for (hlen=0; hlen < MAXLEN; ++hlen) + { + z=0; + for (i=0; i>(8-j)); + c[0] = hashlittle(a, hlen, m); + b[i] ^= ((k+1)<>(8-j)); + d[0] = hashlittle(b, hlen, m); + /* check every bit is 1, 0, set, and not set at least once */ + for (l=0; lz) z=k; + if (k==MAXPAIR) + { + printf("Some bit didn't change: "); + printf("%.8x %.8x %.8x %.8x %.8x %.8x ", + e[0],f[0],g[0],h[0],x[0],y[0]); + printf("i %d j %d m %d len %d\n", i, j, m, hlen); + } + if (z==MAXPAIR) goto done; + } + } + } + done: + if (z < MAXPAIR) + { + printf("Mix success %2d bytes %2d initvals ",i,m); + printf("required %d trials\n", z/2); + } + } + printf("\n"); +} + +/* Check for reading beyond the end of the buffer and alignment problems */ +void driver3() +{ + uint8_t buf[MAXLEN+20], *b; + uint32_t len; + uint8_t q[] = "This is the time for all good men to come to the aid of their country..."; + uint32_t h; + uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country..."; + uint32_t i; + uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country..."; + uint32_t j; + uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country..."; + uint32_t ref,x,y; + uint8_t *p; + + printf("Endianness. These lines should all be the same (for values filled in):\n"); + printf("%.8x %.8x %.8x\n", + hashword((const uint32_t *)q, (sizeof(q)-1)/4, 13), + hashword((const uint32_t *)q, (sizeof(q)-5)/4, 13), + hashword((const uint32_t *)q, (sizeof(q)-9)/4, 13)); + p = q; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + p = &qq[1]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + p = &qqq[2]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + p = &qqqq[3]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13), + hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13), + hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13), + hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13), + hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13), + hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13)); + printf("\n"); + + /* check that hashlittle2 and hashlittle produce the same results */ + i=47; j=0; + hashlittle2(q, sizeof(q), &i, &j); + if (hashlittle(q, sizeof(q), 47) != i) + printf("hashlittle2 and hashlittle mismatch\n"); + + /* check that hashword2 and hashword produce the same results */ + len = 0xdeadbeef; + i=47, j=0; + hashword2(&len, 1, &i, &j); + if (hashword(&len, 1, 47) != i) + printf("hashword2 and hashword mismatch %x %x\n", + i, hashword(&len, 1, 47)); + + /* check hashlittle doesn't read before or after the ends of the string */ + for (h=0, b=buf+1; h<8; ++h, ++b) + { + for (i=0; i +#include + +uint32_t jenkins_hashword(const uint32_t *k, size_t length, uint32_t initval); +void jenkins_hashword2(const uint32_t *k, size_t length, uint32_t *pc, uint32_t *pb); + +uint32_t jenkins_hashlittle(const void *key, size_t length, uint32_t initval); +void jenkins_hashlittle2(const void *key, size_t length, uint32_t *pc, uint32_t *pb); + +uint32_t jenkins_hashbig(const void *key, size_t length, uint32_t initval); + +static inline uint64_t hash64(const void *data, size_t length) { + uint32_t a = 0, b = 0; + + jenkins_hashlittle2(data, length, &a, &b); + + return ((uint64_t) a << 32ULL) | (uint64_t) b; +} + +#endif diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c new file mode 100644 index 0000000..baf51db --- /dev/null +++ b/src/journal/sd-journal.c @@ -0,0 +1,1616 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "sd-journal.h" +#include "journal-def.h" +#include "journal-file.h" +#include "hashmap.h" +#include "list.h" +#include "lookup3.h" +#include "compress.h" +#include "journal-internal.h" + +#define JOURNAL_FILES_MAX 1024 + +static void detach_location(sd_journal *j) { + Iterator i; + JournalFile *f; + + assert(j); + + j->current_file = NULL; + j->current_field = 0; + + HASHMAP_FOREACH(f, j->files, i) + f->current_offset = 0; +} + +static void reset_location(sd_journal *j) { + assert(j); + + detach_location(j); + zero(j->current_location); +} + +static void init_location(Location *l, JournalFile *f, Object *o) { + assert(l); + assert(f); + assert(o->object.type == OBJECT_ENTRY); + + l->type = LOCATION_DISCRETE; + l->seqnum = le64toh(o->entry.seqnum); + l->seqnum_id = f->header->seqnum_id; + l->realtime = le64toh(o->entry.realtime); + l->monotonic = le64toh(o->entry.monotonic); + l->boot_id = o->entry.boot_id; + l->xor_hash = le64toh(o->entry.xor_hash); + + l->seqnum_set = l->realtime_set = l->monotonic_set = l->xor_hash_set = true; +} + +static void set_location(sd_journal *j, JournalFile *f, Object *o, uint64_t offset) { + assert(j); + assert(f); + assert(o); + + init_location(&j->current_location, f, o); + + j->current_file = f; + j->current_field = 0; + + f->current_offset = offset; +} + +static int same_field(const void *_a, size_t s, const void *_b, size_t t) { + const uint8_t *a = _a, *b = _b; + size_t j; + bool a_good = false, b_good = false, different = false; + + for (j = 0; j < s && j < t; j++) { + + if (a[j] == '=') + a_good = true; + if (b[j] == '=') + b_good = true; + if (a[j] != b[j]) + different = true; + + if (a_good && b_good) + return different ? 0 : 1; + } + + return -EINVAL; +} + +_public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) { + Match *m, *after = NULL; + uint64_t le_hash; + + if (!j) + return -EINVAL; + if (!data) + return -EINVAL; + if (size <= 0) + return -EINVAL; + + le_hash = htole64(hash64(data, size)); + + LIST_FOREACH(matches, m, j->matches) { + int r; + + if (m->le_hash == le_hash && + m->size == size && + memcmp(m->data, data, size) == 0) + return 0; + + r = same_field(data, size, m->data, m->size); + if (r < 0) + return r; + else if (r > 0) + after = m; + } + + m = new0(Match, 1); + if (!m) + return -ENOMEM; + + m->size = size; + + m->data = malloc(m->size); + if (!m->data) { + free(m); + return -ENOMEM; + } + + memcpy(m->data, data, size); + m->le_hash = le_hash; + + /* Matches for the same fields we order adjacent to each + * other */ + LIST_INSERT_AFTER(Match, matches, j->matches, after, m); + j->n_matches ++; + + detach_location(j); + + return 0; +} + +_public_ void sd_journal_flush_matches(sd_journal *j) { + if (!j) + return; + + while (j->matches) { + Match *m = j->matches; + + LIST_REMOVE(Match, matches, j->matches, m); + free(m->data); + free(m); + } + + j->n_matches = 0; + + detach_location(j); +} + +static int compare_order(JournalFile *af, Object *ao, + JournalFile *bf, Object *bo) { + + uint64_t a, b; + + assert(af); + assert(ao); + assert(bf); + assert(bo); + + /* We operate on two different files here, hence we can access + * two objects at the same time, which we normally can't. + * + * If contents and timestamps match, these entries are + * identical, even if the seqnum does not match */ + + if (sd_id128_equal(ao->entry.boot_id, bo->entry.boot_id) && + ao->entry.monotonic == bo->entry.monotonic && + ao->entry.realtime == bo->entry.realtime && + ao->entry.xor_hash == bo->entry.xor_hash) + return 0; + + if (sd_id128_equal(af->header->seqnum_id, bf->header->seqnum_id)) { + + /* If this is from the same seqnum source, compare + * seqnums */ + a = le64toh(ao->entry.seqnum); + b = le64toh(bo->entry.seqnum); + + if (a < b) + return -1; + if (a > b) + return 1; + + /* Wow! This is weird, different data but the same + * seqnums? Something is borked, but let's make the + * best of it and compare by time. */ + } + + if (sd_id128_equal(ao->entry.boot_id, bo->entry.boot_id)) { + + /* If the boot id matches compare monotonic time */ + a = le64toh(ao->entry.monotonic); + b = le64toh(bo->entry.monotonic); + + if (a < b) + return -1; + if (a > b) + return 1; + } + + /* Otherwise compare UTC time */ + a = le64toh(ao->entry.realtime); + b = le64toh(ao->entry.realtime); + + if (a < b) + return -1; + if (a > b) + return 1; + + /* Finally, compare by contents */ + a = le64toh(ao->entry.xor_hash); + b = le64toh(ao->entry.xor_hash); + + if (a < b) + return -1; + if (a > b) + return 1; + + return 0; +} + +static int compare_with_location(JournalFile *af, Object *ao, Location *l) { + uint64_t a; + + assert(af); + assert(ao); + assert(l); + assert(l->type == LOCATION_DISCRETE); + + if (l->monotonic_set && + sd_id128_equal(ao->entry.boot_id, l->boot_id) && + l->realtime_set && + le64toh(ao->entry.realtime) == l->realtime && + l->xor_hash_set && + le64toh(ao->entry.xor_hash) == l->xor_hash) + return 0; + + if (l->seqnum_set && + sd_id128_equal(af->header->seqnum_id, l->seqnum_id)) { + + a = le64toh(ao->entry.seqnum); + + if (a < l->seqnum) + return -1; + if (a > l->seqnum) + return 1; + } + + if (l->monotonic_set && + sd_id128_equal(ao->entry.boot_id, l->boot_id)) { + + a = le64toh(ao->entry.monotonic); + + if (a < l->monotonic) + return -1; + if (a > l->monotonic) + return 1; + } + + if (l->realtime_set) { + + a = le64toh(ao->entry.realtime); + + if (a < l->realtime) + return -1; + if (a > l->realtime) + return 1; + } + + if (l->xor_hash_set) { + a = le64toh(ao->entry.xor_hash); + + if (a < l->xor_hash) + return -1; + if (a > l->xor_hash) + return 1; + } + + return 0; +} + +static int find_location(sd_journal *j, JournalFile *f, direction_t direction, Object **ret, uint64_t *offset) { + Object *o = NULL; + uint64_t p = 0; + int r; + + assert(j); + + if (!j->matches) { + /* No matches is simple */ + + if (j->current_location.type == LOCATION_HEAD) + r = journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p); + else if (j->current_location.type == LOCATION_TAIL) + r = journal_file_next_entry(f, NULL, 0, DIRECTION_UP, &o, &p); + else if (j->current_location.seqnum_set && + sd_id128_equal(j->current_location.seqnum_id, f->header->seqnum_id)) + r = journal_file_move_to_entry_by_seqnum(f, j->current_location.seqnum, direction, &o, &p); + else if (j->current_location.monotonic_set) + r = journal_file_move_to_entry_by_monotonic(f, j->current_location.boot_id, j->current_location.monotonic, direction, &o, &p); + else if (j->current_location.realtime_set) + r = journal_file_move_to_entry_by_realtime(f, j->current_location.realtime, direction, &o, &p); + else + r = journal_file_next_entry(f, NULL, 0, direction, &o, &p); + + if (r <= 0) + return r; + + } else { + Match *m, *term_match = NULL; + Object *to = NULL; + uint64_t tp = 0; + + /* We have matches, first, let's jump to the monotonic + * position if we have any, since it implies a + * match. */ + + if (j->current_location.type == LOCATION_DISCRETE && + j->current_location.monotonic_set) { + + r = journal_file_move_to_entry_by_monotonic(f, j->current_location.boot_id, j->current_location.monotonic, direction, &o, &p); + if (r <= 0) + return r == -ENOENT ? 0 : r; + } + + LIST_FOREACH(matches, m, j->matches) { + Object *c, *d; + uint64_t cp, dp; + + r = journal_file_find_data_object_with_hash(f, m->data, m->size, m->le_hash, &d, &dp); + if (r <= 0) + return r; + + if (j->current_location.type == LOCATION_HEAD) + r = journal_file_next_entry_for_data(f, NULL, 0, dp, DIRECTION_DOWN, &c, &cp); + else if (j->current_location.type == LOCATION_TAIL) + r = journal_file_next_entry_for_data(f, NULL, 0, dp, DIRECTION_UP, &c, &cp); + else if (j->current_location.seqnum_set && + sd_id128_equal(j->current_location.seqnum_id, f->header->seqnum_id)) + r = journal_file_move_to_entry_by_seqnum_for_data(f, dp, j->current_location.seqnum, direction, &c, &cp); + else if (j->current_location.realtime_set) + r = journal_file_move_to_entry_by_realtime_for_data(f, dp, j->current_location.realtime, direction, &c, &cp); + else + r = journal_file_next_entry_for_data(f, NULL, 0, dp, direction, &c, &cp); + + if (r < 0) + return r; + + if (!term_match) { + term_match = m; + + if (r > 0) { + to = c; + tp = cp; + } + } else if (same_field(term_match->data, term_match->size, m->data, m->size)) { + + /* Same field as previous match... */ + if (r > 0) { + + /* Find the earliest of the OR matches */ + + if (!to || + (direction == DIRECTION_DOWN && cp < tp) || + (direction == DIRECTION_UP && cp > tp)) { + to = c; + tp = cp; + } + + } + + } else { + + /* Previous term is finished, did anything match? */ + if (!to) + return 0; + + /* Find the last of the AND matches */ + if (!o || + (direction == DIRECTION_DOWN && tp > p) || + (direction == DIRECTION_UP && tp < p)) { + o = to; + p = tp; + } + + term_match = m; + + if (r > 0) { + to = c; + tp = cp; + } else { + to = NULL; + tp = 0; + } + } + } + + /* Last term is finished, did anything match? */ + if (!to) + return 0; + + if (!o || + (direction == DIRECTION_DOWN && tp > p) || + (direction == DIRECTION_UP && tp < p)) { + o = to; + p = tp; + } + + if (!o) + return 0; + } + + if (ret) + *ret = o; + + if (offset) + *offset = p; + + return 1; +} + +static int next_with_matches(sd_journal *j, JournalFile *f, direction_t direction, Object **ret, uint64_t *offset) { + int r; + uint64_t cp; + Object *c; + + assert(j); + assert(f); + assert(ret); + assert(offset); + + c = *ret; + cp = *offset; + + if (!j->matches) { + /* No matches is easy */ + + r = journal_file_next_entry(f, c, cp, direction, &c, &cp); + if (r <= 0) + return r; + + if (ret) + *ret = c; + if (offset) + *offset = cp; + return 1; + } + + /* So there are matches we have to adhere to, let's find the + * first entry that matches all of them */ + + for (;;) { + uint64_t np, n; + bool found, term_result = false; + Match *m, *term_match = NULL; + Object *npo = NULL; + + n = journal_file_entry_n_items(c); + + /* Make sure we don't match the entry we are starting + * from. */ + found = cp != *offset; + + np = 0; + LIST_FOREACH(matches, m, j->matches) { + uint64_t q, k; + Object *qo = NULL; + + /* Let's check if this is the beginning of a + * new term, i.e. has a different field prefix + * as the preceeding match. */ + if (!term_match) { + term_match = m; + term_result = false; + } else if (!same_field(term_match->data, term_match->size, m->data, m->size)) { + if (!term_result) + found = false; + + term_match = m; + term_result = false; + } + + for (k = 0; k < n; k++) + if (c->entry.items[k].hash == m->le_hash) + break; + + if (k >= n) { + /* Hmm, didn't find any field that + * matched this rule, so ignore this + * match. Go on with next match */ + continue; + } + + term_result = true; + + /* Hmm, so, this field matched, let's remember + * where we'd have to try next, in case the other + * matches are not OK */ + + r = journal_file_next_entry_for_data(f, c, cp, le64toh(c->entry.items[k].object_offset), direction, &qo, &q); + if (r < 0) + return r; + + if (r > 0) { + + if (direction == DIRECTION_DOWN) { + if (q > np) { + np = q; + npo = qo; + } + } else { + if (np == 0 || q < np) { + np = q; + npo = qo; + } + } + } + } + + /* Check the last term */ + if (term_match && !term_result) + found = false; + + /* Did this entry match against all matches? */ + if (found) { + if (ret) + *ret = c; + if (offset) + *offset = cp; + return 1; + } + + /* Did we find a subsequent entry? */ + if (np == 0) + return 0; + + /* Hmm, ok, this entry only matched partially, so + * let's try another one */ + cp = np; + c = npo; + } +} + +static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direction, Object **ret, uint64_t *offset) { + Object *c; + uint64_t cp; + int compare_value, r; + + assert(j); + assert(f); + + if (f->current_offset > 0) { + cp = f->current_offset; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, cp, &c); + if (r < 0) + return r; + + r = next_with_matches(j, f, direction, &c, &cp); + if (r <= 0) + return r; + + compare_value = 1; + } else { + r = find_location(j, f, direction, &c, &cp); + if (r <= 0) + return r; + + compare_value = 0; + } + + for (;;) { + bool found; + + if (j->current_location.type == LOCATION_DISCRETE) { + int k; + + k = compare_with_location(f, c, &j->current_location); + if (direction == DIRECTION_DOWN) + found = k >= compare_value; + else + found = k <= -compare_value; + } else + found = true; + + if (found) { + if (ret) + *ret = c; + if (offset) + *offset = cp; + return 1; + } + + r = next_with_matches(j, f, direction, &c, &cp); + if (r <= 0) + return r; + } +} + +static int real_journal_next(sd_journal *j, direction_t direction) { + JournalFile *f, *new_current = NULL; + Iterator i; + int r; + uint64_t new_offset = 0; + Object *new_entry = NULL; + + if (!j) + return -EINVAL; + + HASHMAP_FOREACH(f, j->files, i) { + Object *o; + uint64_t p; + bool found; + + r = next_beyond_location(j, f, direction, &o, &p); + if (r < 0) + return r; + else if (r == 0) + continue; + + if (!new_current) + found = true; + else { + int k; + + k = compare_order(f, o, new_current, new_entry); + + if (direction == DIRECTION_DOWN) + found = k < 0; + else + found = k > 0; + } + + if (found) { + new_current = f; + new_entry = o; + new_offset = p; + } + } + + if (!new_current) + return 0; + + set_location(j, new_current, new_entry, new_offset); + + return 1; +} + +_public_ int sd_journal_next(sd_journal *j) { + return real_journal_next(j, DIRECTION_DOWN); +} + +_public_ int sd_journal_previous(sd_journal *j) { + return real_journal_next(j, DIRECTION_UP); +} + +static int real_journal_next_skip(sd_journal *j, direction_t direction, uint64_t skip) { + int c = 0, r; + + if (!j) + return -EINVAL; + + if (skip == 0) { + /* If this is not a discrete skip, then at least + * resolve the current location */ + if (j->current_location.type != LOCATION_DISCRETE) + return real_journal_next(j, direction); + + return 0; + } + + do { + r = real_journal_next(j, direction); + if (r < 0) + return r; + + if (r == 0) + return c; + + skip--; + c++; + } while (skip > 0); + + return c; +} + +_public_ int sd_journal_next_skip(sd_journal *j, uint64_t skip) { + return real_journal_next_skip(j, DIRECTION_DOWN, skip); +} + +_public_ int sd_journal_previous_skip(sd_journal *j, uint64_t skip) { + return real_journal_next_skip(j, DIRECTION_UP, skip); +} + +_public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) { + Object *o; + int r; + char bid[33], sid[33]; + + if (!j) + return -EINVAL; + if (!cursor) + return -EINVAL; + + if (!j->current_file || j->current_file->current_offset <= 0) + return -EADDRNOTAVAIL; + + r = journal_file_move_to_object(j->current_file, OBJECT_ENTRY, j->current_file->current_offset, &o); + if (r < 0) + return r; + + sd_id128_to_string(j->current_file->header->seqnum_id, sid); + sd_id128_to_string(o->entry.boot_id, bid); + + if (asprintf(cursor, + "s=%s;i=%llx;b=%s;m=%llx;t=%llx;x=%llx;p=%s", + sid, (unsigned long long) le64toh(o->entry.seqnum), + bid, (unsigned long long) le64toh(o->entry.monotonic), + (unsigned long long) le64toh(o->entry.realtime), + (unsigned long long) le64toh(o->entry.xor_hash), + file_name_from_path(j->current_file->path)) < 0) + return -ENOMEM; + + return 1; +} + +_public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) { + char *w; + size_t l; + char *state; + unsigned long long seqnum, monotonic, realtime, xor_hash; + bool + seqnum_id_set = false, + seqnum_set = false, + boot_id_set = false, + monotonic_set = false, + realtime_set = false, + xor_hash_set = false; + sd_id128_t seqnum_id, boot_id; + + if (!j) + return -EINVAL; + if (!cursor) + return -EINVAL; + + FOREACH_WORD_SEPARATOR(w, l, cursor, ";", state) { + char *item; + int k = 0; + + if (l < 2 || w[1] != '=') + return -EINVAL; + + item = strndup(w, l); + if (!item) + return -ENOMEM; + + switch (w[0]) { + + case 's': + seqnum_id_set = true; + k = sd_id128_from_string(w+2, &seqnum_id); + break; + + case 'i': + seqnum_set = true; + if (sscanf(w+2, "%llx", &seqnum) != 1) + k = -EINVAL; + break; + + case 'b': + boot_id_set = true; + k = sd_id128_from_string(w+2, &boot_id); + break; + + case 'm': + monotonic_set = true; + if (sscanf(w+2, "%llx", &monotonic) != 1) + k = -EINVAL; + break; + + case 't': + realtime_set = true; + if (sscanf(w+2, "%llx", &realtime) != 1) + k = -EINVAL; + break; + + case 'x': + xor_hash_set = true; + if (sscanf(w+2, "%llx", &xor_hash) != 1) + k = -EINVAL; + break; + } + + free(item); + + if (k < 0) + return k; + } + + if ((!seqnum_set || !seqnum_id_set) && + (!monotonic_set || !boot_id_set) && + !realtime_set) + return -EINVAL; + + reset_location(j); + + j->current_location.type = LOCATION_DISCRETE; + + if (realtime_set) { + j->current_location.realtime = (uint64_t) realtime; + j->current_location.realtime_set = true; + } + + if (seqnum_set && seqnum_id_set) { + j->current_location.seqnum = (uint64_t) seqnum; + j->current_location.seqnum_id = seqnum_id; + j->current_location.seqnum_set = true; + } + + if (monotonic_set && boot_id_set) { + j->current_location.monotonic = (uint64_t) monotonic; + j->current_location.boot_id = boot_id; + j->current_location.monotonic_set = true; + } + + if (xor_hash_set) { + j->current_location.xor_hash = (uint64_t) xor_hash; + j->current_location.xor_hash_set = true; + } + + return 0; +} + +_public_ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec) { + if (!j) + return -EINVAL; + + reset_location(j); + j->current_location.type = LOCATION_DISCRETE; + j->current_location.boot_id = boot_id; + j->current_location.monotonic = usec; + j->current_location.monotonic_set = true; + + return 0; +} + +_public_ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) { + if (!j) + return -EINVAL; + + reset_location(j); + j->current_location.type = LOCATION_DISCRETE; + j->current_location.realtime = usec; + j->current_location.realtime_set = true; + + return 0; +} + +_public_ int sd_journal_seek_head(sd_journal *j) { + if (!j) + return -EINVAL; + + reset_location(j); + j->current_location.type = LOCATION_HEAD; + + return 0; +} + +_public_ int sd_journal_seek_tail(sd_journal *j) { + if (!j) + return -EINVAL; + + reset_location(j); + j->current_location.type = LOCATION_TAIL; + + return 0; +} + +static int add_file(sd_journal *j, const char *prefix, const char *dir, const char *filename) { + char *fn; + int r; + JournalFile *f; + + assert(j); + assert(prefix); + assert(filename); + + if ((j->flags & SD_JOURNAL_SYSTEM_ONLY) && + !startswith(filename, "system.journal")) + return 0; + + if (dir) + fn = join(prefix, "/", dir, "/", filename, NULL); + else + fn = join(prefix, "/", filename, NULL); + + if (!fn) + return -ENOMEM; + + if (hashmap_get(j->files, fn)) { + free(fn); + return 0; + } + + if (hashmap_size(j->files) >= JOURNAL_FILES_MAX) { + log_debug("Too many open journal files, not adding %s, ignoring.", fn); + free(fn); + return 0; + } + + r = journal_file_open(fn, O_RDONLY, 0, NULL, &f); + free(fn); + + if (r < 0) { + if (errno == ENOENT) + return 0; + + return r; + } + + /* journal_file_dump(f); */ + + r = hashmap_put(j->files, f->path, f); + if (r < 0) { + journal_file_close(f); + return r; + } + + log_debug("File %s got added.", f->path); + + return 0; +} + +static int remove_file(sd_journal *j, const char *prefix, const char *dir, const char *filename) { + char *fn; + JournalFile *f; + + assert(j); + assert(prefix); + assert(filename); + + if (dir) + fn = join(prefix, "/", dir, "/", filename, NULL); + else + fn = join(prefix, "/", filename, NULL); + + if (!fn) + return -ENOMEM; + + f = hashmap_get(j->files, fn); + free(fn); + + if (!f) + return 0; + + hashmap_remove(j->files, f->path); + journal_file_close(f); + + log_debug("File %s got removed.", f->path); + return 0; +} + +static int add_directory(sd_journal *j, const char *prefix, const char *dir) { + char *fn; + int r; + DIR *d; + int wd; + sd_id128_t id, mid; + + assert(j); + assert(prefix); + assert(dir); + + if ((j->flags & SD_JOURNAL_LOCAL_ONLY) && + (sd_id128_from_string(dir, &id) < 0 || + sd_id128_get_machine(&mid) < 0 || + !sd_id128_equal(id, mid))) + return 0; + + fn = join(prefix, "/", dir, NULL); + if (!fn) + return -ENOMEM; + + d = opendir(fn); + + if (!d) { + free(fn); + if (errno == ENOENT) + return 0; + + return -errno; + } + + wd = inotify_add_watch(j->inotify_fd, fn, + IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB|IN_DELETE| + IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT| + IN_DONT_FOLLOW|IN_ONLYDIR); + if (wd > 0) { + if (hashmap_put(j->inotify_wd_dirs, INT_TO_PTR(wd), fn) < 0) + inotify_rm_watch(j->inotify_fd, wd); + else + fn = NULL; + } + + free(fn); + + for (;;) { + struct dirent buf, *de; + + r = readdir_r(d, &buf, &de); + if (r != 0 || !de) + break; + + if (!dirent_is_file_with_suffix(de, ".journal")) + continue; + + r = add_file(j, prefix, dir, de->d_name); + if (r < 0) + log_debug("Failed to add file %s/%s/%s: %s", prefix, dir, de->d_name, strerror(-r)); + } + + closedir(d); + + log_debug("Directory %s/%s got added.", prefix, dir); + + return 0; +} + +static void remove_directory_wd(sd_journal *j, int wd) { + char *p; + + assert(j); + assert(wd > 0); + + if (j->inotify_fd >= 0) + inotify_rm_watch(j->inotify_fd, wd); + + p = hashmap_remove(j->inotify_wd_dirs, INT_TO_PTR(wd)); + + if (p) { + log_debug("Directory %s got removed.", p); + free(p); + } +} + +static void add_root_wd(sd_journal *j, const char *p) { + int wd; + char *k; + + assert(j); + assert(p); + + wd = inotify_add_watch(j->inotify_fd, p, + IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB|IN_DELETE| + IN_DONT_FOLLOW|IN_ONLYDIR); + if (wd <= 0) + return; + + k = strdup(p); + if (!k || hashmap_put(j->inotify_wd_roots, INT_TO_PTR(wd), k) < 0) { + inotify_rm_watch(j->inotify_fd, wd); + free(k); + } +} + +static void remove_root_wd(sd_journal *j, int wd) { + char *p; + + assert(j); + assert(wd > 0); + + if (j->inotify_fd >= 0) + inotify_rm_watch(j->inotify_fd, wd); + + p = hashmap_remove(j->inotify_wd_roots, INT_TO_PTR(wd)); + + if (p) { + log_debug("Root %s got removed.", p); + free(p); + } +} + +_public_ int sd_journal_open(sd_journal **ret, int flags) { + sd_journal *j; + const char *p; + const char search_paths[] = + "/run/log/journal\0" + "/var/log/journal\0"; + int r; + + if (!ret) + return -EINVAL; + + if (flags & ~(SD_JOURNAL_LOCAL_ONLY| + SD_JOURNAL_RUNTIME_ONLY| + SD_JOURNAL_SYSTEM_ONLY)) + return -EINVAL; + + j = new0(sd_journal, 1); + if (!j) + return -ENOMEM; + + j->flags = flags; + + j->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); + if (j->inotify_fd < 0) { + r = -errno; + goto fail; + } + + j->files = hashmap_new(string_hash_func, string_compare_func); + if (!j->files) { + r = -ENOMEM; + goto fail; + } + + j->inotify_wd_dirs = hashmap_new(trivial_hash_func, trivial_compare_func); + j->inotify_wd_roots = hashmap_new(trivial_hash_func, trivial_compare_func); + + if (!j->inotify_wd_dirs || !j->inotify_wd_roots) { + r = -ENOMEM; + goto fail; + } + + /* We ignore most errors here, since the idea is to only open + * what's actually accessible, and ignore the rest. */ + + NULSTR_FOREACH(p, search_paths) { + DIR *d; + + if ((flags & SD_JOURNAL_RUNTIME_ONLY) && + !path_startswith(p, "/run")) + continue; + + d = opendir(p); + if (!d) { + if (errno != ENOENT) + log_debug("Failed to open %s: %m", p); + continue; + } + + add_root_wd(j, p); + + for (;;) { + struct dirent buf, *de; + sd_id128_t id; + + r = readdir_r(d, &buf, &de); + if (r != 0 || !de) + break; + + if (dirent_is_file_with_suffix(de, ".journal")) { + r = add_file(j, p, NULL, de->d_name); + if (r < 0) + log_debug("Failed to add file %s/%s: %s", p, de->d_name, strerror(-r)); + + } else if ((de->d_type == DT_DIR || de->d_type == DT_UNKNOWN) && + sd_id128_from_string(de->d_name, &id) >= 0) { + + r = add_directory(j, p, de->d_name); + if (r < 0) + log_debug("Failed to add directory %s/%s: %s", p, de->d_name, strerror(-r)); + } + } + + closedir(d); + } + + *ret = j; + return 0; + +fail: + sd_journal_close(j); + + return r; +}; + +_public_ void sd_journal_close(sd_journal *j) { + if (!j) + return; + + if (j->inotify_wd_dirs) { + void *k; + + while ((k = hashmap_first_key(j->inotify_wd_dirs))) + remove_directory_wd(j, PTR_TO_INT(k)); + + hashmap_free(j->inotify_wd_dirs); + } + + if (j->inotify_wd_roots) { + void *k; + + while ((k = hashmap_first_key(j->inotify_wd_roots))) + remove_root_wd(j, PTR_TO_INT(k)); + + hashmap_free(j->inotify_wd_roots); + } + + if (j->files) { + JournalFile *f; + + while ((f = hashmap_steal_first(j->files))) + journal_file_close(f); + + hashmap_free(j->files); + } + + sd_journal_flush_matches(j); + + if (j->inotify_fd >= 0) + close_nointr_nofail(j->inotify_fd); + + free(j); +} + +_public_ int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret) { + Object *o; + JournalFile *f; + int r; + + if (!j) + return -EINVAL; + if (!ret) + return -EINVAL; + + f = j->current_file; + if (!f) + return -EADDRNOTAVAIL; + + if (f->current_offset <= 0) + return -EADDRNOTAVAIL; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); + if (r < 0) + return r; + + *ret = le64toh(o->entry.realtime); + return 0; +} + +_public_ int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id128_t *ret_boot_id) { + Object *o; + JournalFile *f; + int r; + sd_id128_t id; + + if (!j) + return -EINVAL; + if (!ret) + return -EINVAL; + + f = j->current_file; + if (!f) + return -EADDRNOTAVAIL; + + if (f->current_offset <= 0) + return -EADDRNOTAVAIL; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); + if (r < 0) + return r; + + if (ret_boot_id) + *ret_boot_id = o->entry.boot_id; + else { + r = sd_id128_get_boot(&id); + if (r < 0) + return r; + + if (!sd_id128_equal(id, o->entry.boot_id)) + return -ESTALE; + } + + *ret = le64toh(o->entry.monotonic); + return 0; +} + +_public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *size) { + JournalFile *f; + uint64_t i, n; + size_t field_length; + int r; + Object *o; + + if (!j) + return -EINVAL; + if (!field) + return -EINVAL; + if (!data) + return -EINVAL; + if (!size) + return -EINVAL; + + if (isempty(field) || strchr(field, '=')) + return -EINVAL; + + f = j->current_file; + if (!f) + return -EADDRNOTAVAIL; + + if (f->current_offset <= 0) + return -EADDRNOTAVAIL; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); + if (r < 0) + return r; + + field_length = strlen(field); + + n = journal_file_entry_n_items(o); + for (i = 0; i < n; i++) { + uint64_t p, l, le_hash; + size_t t; + + p = le64toh(o->entry.items[i].object_offset); + le_hash = o->entry.items[i].hash; + r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); + if (r < 0) + return r; + + if (le_hash != o->data.hash) + return -EBADMSG; + + l = le64toh(o->object.size) - offsetof(Object, data.payload); + + if (o->object.flags & OBJECT_COMPRESSED) { + +#ifdef HAVE_XZ + if (uncompress_startswith(o->data.payload, l, + &f->compress_buffer, &f->compress_buffer_size, + field, field_length, '=')) { + + uint64_t rsize; + + if (!uncompress_blob(o->data.payload, l, + &f->compress_buffer, &f->compress_buffer_size, &rsize)) + return -EBADMSG; + + *data = f->compress_buffer; + *size = (size_t) rsize; + + return 0; + } +#else + return -EPROTONOSUPPORT; +#endif + + } else if (l >= field_length+1 && + memcmp(o->data.payload, field, field_length) == 0 && + o->data.payload[field_length] == '=') { + + t = (size_t) l; + + if ((uint64_t) t != l) + return -E2BIG; + + *data = o->data.payload; + *size = t; + + return 0; + } + + r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); + if (r < 0) + return r; + } + + return -ENOENT; +} + +_public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *size) { + JournalFile *f; + uint64_t p, l, n, le_hash; + int r; + Object *o; + size_t t; + + if (!j) + return -EINVAL; + if (!data) + return -EINVAL; + if (!size) + return -EINVAL; + + f = j->current_file; + if (!f) + return -EADDRNOTAVAIL; + + if (f->current_offset <= 0) + return -EADDRNOTAVAIL; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); + if (r < 0) + return r; + + n = journal_file_entry_n_items(o); + if (j->current_field >= n) + return 0; + + p = le64toh(o->entry.items[j->current_field].object_offset); + le_hash = o->entry.items[j->current_field].hash; + r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); + if (r < 0) + return r; + + if (le_hash != o->data.hash) + return -EBADMSG; + + l = le64toh(o->object.size) - offsetof(Object, data.payload); + t = (size_t) l; + + /* We can't read objects larger than 4G on a 32bit machine */ + if ((uint64_t) t != l) + return -E2BIG; + + if (o->object.flags & OBJECT_COMPRESSED) { +#ifdef HAVE_XZ + uint64_t rsize; + + if (!uncompress_blob(o->data.payload, l, &f->compress_buffer, &f->compress_buffer_size, &rsize)) + return -EBADMSG; + + *data = f->compress_buffer; + *size = (size_t) rsize; +#else + return -EPROTONOSUPPORT; +#endif + } else { + *data = o->data.payload; + *size = t; + } + + j->current_field ++; + + return 1; +} + +_public_ void sd_journal_restart_data(sd_journal *j) { + if (!j) + return; + + j->current_field = 0; +} + +_public_ int sd_journal_get_fd(sd_journal *j) { + if (!j) + return -EINVAL; + + return j->inotify_fd; +} + +static void process_inotify_event(sd_journal *j, struct inotify_event *e) { + char *p; + int r; + + assert(j); + assert(e); + + /* Is this a subdirectory we watch? */ + p = hashmap_get(j->inotify_wd_dirs, INT_TO_PTR(e->wd)); + if (p) { + + if (!(e->mask & IN_ISDIR) && e->len > 0 && endswith(e->name, ".journal")) { + + /* Event for a journal file */ + + if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) { + r = add_file(j, p, NULL, e->name); + if (r < 0) + log_debug("Failed to add file %s/%s: %s", p, e->name, strerror(-r)); + } else if (e->mask & (IN_DELETE|IN_UNMOUNT)) { + + r = remove_file(j, p, NULL, e->name); + if (r < 0) + log_debug("Failed to remove file %s/%s: %s", p, e->name, strerror(-r)); + } + + } else if (e->len == 0) { + + /* Event for the directory itself */ + + if (e->mask & (IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT)) + remove_directory_wd(j, e->wd); + } + + return; + } + + /* Must be the root directory then? */ + p = hashmap_get(j->inotify_wd_roots, INT_TO_PTR(e->wd)); + if (p) { + sd_id128_t id; + + if (!(e->mask & IN_ISDIR) && e->len > 0 && endswith(e->name, ".journal")) { + + /* Event for a journal file */ + + if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) { + r = add_file(j, p, NULL, e->name); + if (r < 0) + log_debug("Failed to add file %s/%s: %s", p, e->name, strerror(-r)); + } else if (e->mask & (IN_DELETE|IN_UNMOUNT)) { + + r = remove_file(j, p, NULL, e->name); + if (r < 0) + log_debug("Failed to remove file %s/%s: %s", p, e->name, strerror(-r)); + } + + } else if ((e->mask & IN_ISDIR) && e->len > 0 && sd_id128_from_string(e->name, &id) >= 0) { + + /* Event for subdirectory */ + + if (e->mask & (IN_CREATE|IN_MOVED_TO|IN_MODIFY|IN_ATTRIB)) { + + r = add_directory(j, p, e->name); + if (r < 0) + log_debug("Failed to add directory %s/%s: %s", p, e->name, strerror(-r)); + } + } + + return; + } + + if (e->mask & IN_IGNORED) + return; + + log_warning("Unknown inotify event."); +} + +_public_ int sd_journal_process(sd_journal *j) { + uint8_t buffer[sizeof(struct inotify_event) + FILENAME_MAX]; + + if (!j) + return -EINVAL; + + for (;;) { + struct inotify_event *e; + ssize_t l; + + l = read(j->inotify_fd, buffer, sizeof(buffer)); + if (l < 0) { + if (errno == EINTR || errno == EAGAIN) + return 0; + + return -errno; + } + + e = (struct inotify_event*) buffer; + while (l > 0) { + size_t step; + + process_inotify_event(j, e); + + step = sizeof(struct inotify_event) + e->len; + assert(step <= (size_t) l); + + e = (struct inotify_event*) ((uint8_t*) e + step); + l -= step; + } + } +} + +/* _public_ int sd_journal_query_unique(sd_journal *j, const char *field) { */ +/* if (!j) */ +/* return -EINVAL; */ +/* if (!field) */ +/* return -EINVAL; */ + +/* return -ENOTSUP; */ +/* } */ + +/* _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l) { */ +/* if (!j) */ +/* return -EINVAL; */ +/* if (!data) */ +/* return -EINVAL; */ +/* if (!l) */ +/* return -EINVAL; */ + +/* return -ENOTSUP; */ +/* } */ + +/* _public_ void sd_journal_restart_unique(sd_journal *j) { */ +/* if (!j) */ +/* return; */ +/* } */ diff --git a/src/journal/systemd-journald.conf b/src/journal/systemd-journald.conf new file mode 100644 index 0000000..710b0aa --- /dev/null +++ b/src/journal/systemd-journald.conf @@ -0,0 +1,25 @@ +# This file is part of systemd. +# +# systemd 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. +# +# See system-journald.conf(5) for details + +[Journal] +#Compress=yes +#RateLimitInterval=10s +#RateLimitBurst=200 +#SystemMaxUse= +#SystemKeepFree= +#SystemMaxFileSize= +#SystemMinFileSize= +#RuntimeMaxUse= +#RuntimeKeepFree= +#RuntimeMaxFileSize= +#RuntimeMinFileSize= +#ForwardToSyslog=yes +#ForwardToKMsg=no +#ForwardToConsole=no +#ImportKernel=yes diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c new file mode 100644 index 0000000..a023509 --- /dev/null +++ b/src/journal/test-journal.c @@ -0,0 +1,120 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include + +#include "journal-file.h" +#include "log.h" + +int main(int argc, char *argv[]) { + dual_timestamp ts; + JournalFile *f; + struct iovec iovec; + static const char test[] = "test", test2[] = "test2"; + Object *o; + uint64_t p; + + log_set_max_level(LOG_DEBUG); + + unlink("test.journal"); + + assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, NULL, &f) == 0); + + dual_timestamp_get(&ts); + + iovec.iov_base = (void*) test; + iovec.iov_len = strlen(test); + assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0); + + iovec.iov_base = (void*) test2; + iovec.iov_len = strlen(test2); + assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0); + + iovec.iov_base = (void*) test; + iovec.iov_len = strlen(test); + assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0); + + journal_file_dump(f); + + assert(journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p) == 1); + assert(le64toh(o->entry.seqnum) == 1); + + assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 1); + assert(le64toh(o->entry.seqnum) == 2); + + assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 1); + assert(le64toh(o->entry.seqnum) == 3); + + assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 0); + + assert(journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p) == 1); + assert(le64toh(o->entry.seqnum) == 1); + + assert(journal_file_skip_entry(f, o, p, 2, &o, &p) == 1); + assert(le64toh(o->entry.seqnum) == 3); + + assert(journal_file_skip_entry(f, o, p, -2, &o, &p) == 1); + assert(le64toh(o->entry.seqnum) == 1); + + assert(journal_file_skip_entry(f, o, p, -2, &o, &p) == 1); + assert(le64toh(o->entry.seqnum) == 1); + + assert(journal_file_find_data_object(f, test, strlen(test), NULL, &p) == 1); + assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_DOWN, &o, NULL) == 1); + assert(le64toh(o->entry.seqnum) == 1); + + assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_UP, &o, NULL) == 1); + assert(le64toh(o->entry.seqnum) == 3); + + assert(journal_file_find_data_object(f, test2, strlen(test2), NULL, &p) == 1); + assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_UP, &o, NULL) == 1); + assert(le64toh(o->entry.seqnum) == 2); + + assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_DOWN, &o, NULL) == 1); + assert(le64toh(o->entry.seqnum) == 2); + + assert(journal_file_find_data_object(f, "quux", 4, NULL, &p) == 0); + + assert(journal_file_move_to_entry_by_seqnum(f, 1, DIRECTION_DOWN, &o, NULL) == 1); + assert(le64toh(o->entry.seqnum) == 1); + + assert(journal_file_move_to_entry_by_seqnum(f, 3, DIRECTION_DOWN, &o, NULL) == 1); + assert(le64toh(o->entry.seqnum) == 3); + + assert(journal_file_move_to_entry_by_seqnum(f, 2, DIRECTION_DOWN, &o, NULL) == 1); + assert(le64toh(o->entry.seqnum) == 2); + + assert(journal_file_move_to_entry_by_seqnum(f, 10, DIRECTION_DOWN, &o, NULL) == 0); + + journal_file_rotate(&f); + journal_file_rotate(&f); + + journal_file_close(f); + + journal_directory_vacuum(".", 3000000, 0); + + log_error("Exiting..."); + + return 0; +} diff --git a/src/kmod-setup.c b/src/kmod-setup.c new file mode 100644 index 0000000..dc35156 --- /dev/null +++ b/src/kmod-setup.c @@ -0,0 +1,96 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "macro.h" +#include "execute.h" + +#include "kmod-setup.h" + +static const char * const kmod_table[] = { + "autofs4", "/sys/class/misc/autofs", + "ipv6", "/sys/module/ipv6", + "unix", "/proc/net/unix" +}; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +static void systemd_kmod_log(void *data, int priority, const char *file, int line, + const char *fn, const char *format, va_list args) +{ + log_meta(priority, file, line, fn, format, args); +} +#pragma GCC diagnostic pop + +int kmod_setup(void) { + unsigned i; + struct kmod_ctx *ctx = NULL; + struct kmod_module *mod; + int err; + + for (i = 0; i < ELEMENTSOF(kmod_table); i += 2) { + + if (access(kmod_table[i+1], F_OK) >= 0) + continue; + + log_debug("Your kernel apparently lacks built-in %s support. Might be a good idea to compile it in. " + "We'll now try to work around this by loading the module...", + kmod_table[i]); + + if (!ctx) { + ctx = kmod_new(NULL, NULL); + if (!ctx) { + log_error("Failed to allocate memory for kmod"); + return -ENOMEM; + } + + kmod_set_log_fn(ctx, systemd_kmod_log, NULL); + + kmod_load_resources(ctx); + } + + err = kmod_module_new_from_name(ctx, kmod_table[i], &mod); + if (err < 0) { + log_error("Failed to load module '%s'", kmod_table[i]); + continue; + } + + err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL); + if (err == 0) + log_info("Inserted module '%s'", kmod_module_get_name(mod)); + else if (err == KMOD_PROBE_APPLY_BLACKLIST) + log_info("Module '%s' is blacklisted", kmod_module_get_name(mod)); + else + log_error("Failed to insert '%s'", kmod_module_get_name(mod)); + + kmod_module_unref(mod); + } + + if (ctx) + ctx = kmod_unref(ctx); + + return 0; +} diff --git a/src/kmod-setup.h b/src/kmod-setup.h new file mode 100644 index 0000000..496aef3 --- /dev/null +++ b/src/kmod-setup.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fookmodsetuphfoo +#define fookmodsetuphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +int kmod_setup(void); + +#endif diff --git a/src/label.c b/src/label.c new file mode 100644 index 0000000..2c887a0 --- /dev/null +++ b/src/label.c @@ -0,0 +1,413 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include + +#include "label.h" +#include "util.h" + +#ifdef HAVE_SELINUX +#include +#include + +static struct selabel_handle *label_hnd = NULL; + +static int use_selinux_cached = -1; + +static inline bool use_selinux(void) { + + if (use_selinux_cached < 0) + use_selinux_cached = is_selinux_enabled() > 0; + + return use_selinux_cached; +} + +void label_retest_selinux(void) { + use_selinux_cached = -1; +} + +#endif + +int label_init(void) { + int r = 0; + +#ifdef HAVE_SELINUX + usec_t before_timestamp, after_timestamp; + struct mallinfo before_mallinfo, after_mallinfo; + + if (!use_selinux()) + return 0; + + if (label_hnd) + return 0; + + before_mallinfo = mallinfo(); + before_timestamp = now(CLOCK_MONOTONIC); + + label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0); + if (!label_hnd) { + log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, + "Failed to initialize SELinux context: %m"); + r = security_getenforce() == 1 ? -errno : 0; + } else { + char timespan[FORMAT_TIMESPAN_MAX]; + int l; + + after_timestamp = now(CLOCK_MONOTONIC); + after_mallinfo = mallinfo(); + + l = after_mallinfo.uordblks > before_mallinfo.uordblks ? after_mallinfo.uordblks - before_mallinfo.uordblks : 0; + + log_info("Successfully loaded SELinux database in %s, size on heap is %iK.", + format_timespan(timespan, sizeof(timespan), after_timestamp - before_timestamp), + (l+1023)/1024); + } +#endif + + return r; +} + +int label_fix(const char *path, bool ignore_enoent) { + int r = 0; + +#ifdef HAVE_SELINUX + struct stat st; + security_context_t fcon; + + if (!use_selinux() || !label_hnd) + return 0; + + r = lstat(path, &st); + if (r == 0) { + r = selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode); + + /* If there's no label to set, then exit without warning */ + if (r < 0 && errno == ENOENT) + return 0; + + if (r == 0) { + r = lsetfilecon(path, fcon); + freecon(fcon); + + /* If the FS doesn't support labels, then exit without warning */ + if (r < 0 && errno == ENOTSUP) + return 0; + } + } + + if (r < 0) { + /* Ignore ENOENT in some cases */ + if (ignore_enoent && errno == ENOENT) + return 0; + + log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, + "Unable to fix label of %s: %m", path); + r = security_getenforce() == 1 ? -errno : 0; + } +#endif + + return r; +} + +void label_finish(void) { + +#ifdef HAVE_SELINUX + if (use_selinux() && label_hnd) + selabel_close(label_hnd); +#endif +} + +int label_get_create_label_from_exe(const char *exe, char **label) { + + int r = 0; + +#ifdef HAVE_SELINUX + security_context_t mycon = NULL, fcon = NULL; + security_class_t sclass; + + if (!use_selinux()) { + *label = NULL; + return 0; + } + + r = getcon(&mycon); + if (r < 0) + goto fail; + + r = getfilecon(exe, &fcon); + if (r < 0) + goto fail; + + sclass = string_to_security_class("process"); + r = security_compute_create(mycon, fcon, sclass, (security_context_t *) label); + if (r == 0) + log_debug("SELinux Socket context for %s will be set to %s", exe, *label); + +fail: + if (r < 0 && security_getenforce() == 1) + r = -errno; + + freecon(mycon); + freecon(fcon); +#endif + + return r; +} + +int label_fifofile_set(const char *path) { + int r = 0; + +#ifdef HAVE_SELINUX + security_context_t filecon = NULL; + + if (!use_selinux() || !label_hnd) + return 0; + + r = selabel_lookup_raw(label_hnd, &filecon, path, S_IFIFO); + if (r < 0) + r = -errno; + else if (r == 0) { + r = setfscreatecon(filecon); + if (r < 0) { + log_error("Failed to set SELinux file context on %s: %m", path); + r = -errno; + } + + freecon(filecon); + } + + if (r < 0 && security_getenforce() == 0) + r = 0; +#endif + + return r; +} + +int label_symlinkfile_set(const char *path) { + int r = 0; + +#ifdef HAVE_SELINUX + security_context_t filecon = NULL; + + if (!use_selinux() || !label_hnd) + return 0; + + r = selabel_lookup_raw(label_hnd, &filecon, path, S_IFLNK); + if (r < 0) + r = -errno; + else if (r == 0) { + r = setfscreatecon(filecon); + if (r < 0) { + log_error("Failed to set SELinux file context on %s: %m", path); + r = -errno; + } + + freecon(filecon); + } + + if (r < 0 && security_getenforce() == 0) + r = 0; +#endif + + return r; +} + +int label_socket_set(const char *label) { + +#ifdef HAVE_SELINUX + if (!use_selinux()) + return 0; + + if (setsockcreatecon((security_context_t) label) < 0) { + log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, + "Failed to set SELinux context (%s) on socket: %m", label); + + if (security_getenforce() == 1) + return -errno; + } +#endif + + return 0; +} + +void label_file_clear(void) { + +#ifdef HAVE_SELINUX + if (!use_selinux()) + return; + + setfscreatecon(NULL); +#endif +} + +void label_socket_clear(void) { + +#ifdef HAVE_SELINUX + if (!use_selinux()) + return; + + setsockcreatecon(NULL); +#endif +} + +void label_free(const char *label) { + +#ifdef HAVE_SELINUX + if (!use_selinux()) + return; + + freecon((security_context_t) label); +#endif +} + +int label_mkdir(const char *path, mode_t mode) { + + /* Creates a directory and labels it according to the SELinux policy */ + +#ifdef HAVE_SELINUX + int r; + security_context_t fcon = NULL; + + if (!use_selinux() || !label_hnd) + goto skipped; + + if (path_is_absolute(path)) + r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFDIR); + else { + char *newpath; + + newpath = path_make_absolute_cwd(path); + if (!newpath) + return -ENOMEM; + + r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFDIR); + free(newpath); + } + + if (r == 0) + r = setfscreatecon(fcon); + + if (r < 0 && errno != ENOENT) { + log_error("Failed to set security context %s for %s: %m", fcon, path); + + if (security_getenforce() == 1) { + r = -errno; + goto finish; + } + } + + r = mkdir(path, mode); + if (r < 0) + r = -errno; + +finish: + setfscreatecon(NULL); + freecon(fcon); + + return r; + +skipped: +#endif + return mkdir(path, mode) < 0 ? -errno : 0; +} + +int label_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) { + + /* Binds a socket and label its file system object according to the SELinux policy */ + +#ifdef HAVE_SELINUX + int r; + security_context_t fcon = NULL; + const struct sockaddr_un *un; + char *path = NULL; + + assert(fd >= 0); + assert(addr); + assert(addrlen >= sizeof(sa_family_t)); + + if (!use_selinux() || !label_hnd) + goto skipped; + + /* Filter out non-local sockets */ + if (addr->sa_family != AF_UNIX) + goto skipped; + + /* Filter out anonymous sockets */ + if (addrlen < sizeof(sa_family_t) + 1) + goto skipped; + + /* Filter out abstract namespace sockets */ + un = (const struct sockaddr_un*) addr; + if (un->sun_path[0] == 0) + goto skipped; + + path = strndup(un->sun_path, addrlen - offsetof(struct sockaddr_un, sun_path)); + if (!path) + return -ENOMEM; + + if (path_is_absolute(path)) + r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK); + else { + char *newpath; + + newpath = path_make_absolute_cwd(path); + + if (!newpath) { + free(path); + return -ENOMEM; + } + + r = selabel_lookup_raw(label_hnd, &fcon, newpath, S_IFSOCK); + free(newpath); + } + + if (r == 0) + r = setfscreatecon(fcon); + + if (r < 0 && errno != ENOENT) { + log_error("Failed to set security context %s for %s: %m", fcon, path); + + if (security_getenforce() == 1) { + r = -errno; + goto finish; + } + } + + r = bind(fd, addr, addrlen); + if (r < 0) + r = -errno; + +finish: + setfscreatecon(NULL); + freecon(fcon); + free(path); + + return r; + +skipped: +#endif + return bind(fd, addr, addrlen) < 0 ? -errno : 0; +} diff --git a/src/label.h b/src/label.h new file mode 100644 index 0000000..ead4483 --- /dev/null +++ b/src/label.h @@ -0,0 +1,51 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foolabelhfoo +#define foolabelhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +int label_init(void); +void label_finish(void); + +int label_fix(const char *path, bool ignore_enoent); + +int label_socket_set(const char *label); +void label_socket_clear(void); + +int label_fifofile_set(const char *path); +int label_symlinkfile_set(const char *path); +void label_file_clear(void); + +void label_free(const char *label); + +int label_get_create_label_from_exe(const char *exe, char **label); + +int label_mkdir(const char *path, mode_t mode); + +void label_retest_selinux(void); + +int label_bind(int fd, const struct sockaddr *addr, socklen_t addrlen); + +#endif diff --git a/src/libsystemd-daemon.pc.in b/src/libsystemd-daemon.pc.in new file mode 100644 index 0000000..8bb3a74 --- /dev/null +++ b/src/libsystemd-daemon.pc.in @@ -0,0 +1,19 @@ +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: systemd +Description: systemd Daemon Utility Library +URL: @PACKAGE_URL@ +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lsystemd-daemon +Cflags: -I${includedir} diff --git a/src/libsystemd-daemon.sym b/src/libsystemd-daemon.sym new file mode 100644 index 0000000..f440238 --- /dev/null +++ b/src/libsystemd-daemon.sym @@ -0,0 +1,27 @@ +/*** + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: +***/ + +/* Original symbols from systemd v31 */ + +LIBSYSTEMD_DAEMON_31 { +global: + sd_booted; + sd_is_fifo; + sd_is_mq; + sd_is_socket; + sd_is_socket_inet; + sd_is_socket_unix; + sd_is_special; + sd_listen_fds; + sd_notify; + sd_notifyf; +local: + *; +}; diff --git a/src/libsystemd-id128.pc.in b/src/libsystemd-id128.pc.in new file mode 100644 index 0000000..4d984fd --- /dev/null +++ b/src/libsystemd-id128.pc.in @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: systemd +Description: systemd 128 Bit ID Utility Library +URL: @PACKAGE_URL@ +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lsystemd-id128 +Cflags: -I${includedir} diff --git a/src/libsystemd-id128.sym b/src/libsystemd-id128.sym new file mode 100644 index 0000000..2373fe6 --- /dev/null +++ b/src/libsystemd-id128.sym @@ -0,0 +1,21 @@ +/*** + This file is part of systemd. + + systemd 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. +***/ + +/* Original symbols from systemd v38 */ + +LIBSYSTEMD_ID128_38 { +global: + sd_id128_to_string; + sd_id128_from_string; + sd_id128_randomize; + sd_id128_get_machine; + sd_id128_get_boot; +local: + *; +}; diff --git a/src/linux/auto_dev-ioctl.h b/src/linux/auto_dev-ioctl.h new file mode 100644 index 0000000..850f39b --- /dev/null +++ b/src/linux/auto_dev-ioctl.h @@ -0,0 +1,229 @@ +/* + * Copyright 2008 Red Hat, Inc. All rights reserved. + * Copyright 2008 Ian Kent + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + */ + +#ifndef _LINUX_AUTO_DEV_IOCTL_H +#define _LINUX_AUTO_DEV_IOCTL_H + +#include + +#ifdef __KERNEL__ +#include +#else +#include +#endif /* __KERNEL__ */ + +#define AUTOFS_DEVICE_NAME "autofs" + +#define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1 +#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0 + +#define AUTOFS_DEVID_LEN 16 + +#define AUTOFS_DEV_IOCTL_SIZE sizeof(struct autofs_dev_ioctl) + +/* + * An ioctl interface for autofs mount point control. + */ + +struct args_protover { + __u32 version; +}; + +struct args_protosubver { + __u32 sub_version; +}; + +struct args_openmount { + __u32 devid; +}; + +struct args_ready { + __u32 token; +}; + +struct args_fail { + __u32 token; + __s32 status; +}; + +struct args_setpipefd { + __s32 pipefd; +}; + +struct args_timeout { + __u64 timeout; +}; + +struct args_requester { + __u32 uid; + __u32 gid; +}; + +struct args_expire { + __u32 how; +}; + +struct args_askumount { + __u32 may_umount; +}; + +struct args_ismountpoint { + union { + struct args_in { + __u32 type; + } in; + struct args_out { + __u32 devid; + __u32 magic; + } out; + }; +}; + +/* + * All the ioctls use this structure. + * When sending a path size must account for the total length + * of the chunk of memory otherwise is is the size of the + * structure. + */ + +struct autofs_dev_ioctl { + __u32 ver_major; + __u32 ver_minor; + __u32 size; /* total size of data passed in + * including this struct */ + __s32 ioctlfd; /* automount command fd */ + + /* Command parameters */ + + union { + struct args_protover protover; + struct args_protosubver protosubver; + struct args_openmount openmount; + struct args_ready ready; + struct args_fail fail; + struct args_setpipefd setpipefd; + struct args_timeout timeout; + struct args_requester requester; + struct args_expire expire; + struct args_askumount askumount; + struct args_ismountpoint ismountpoint; + }; + + char path[0]; +}; + +static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in) +{ + memset(in, 0, sizeof(struct autofs_dev_ioctl)); + in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR; + in->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR; + in->size = sizeof(struct autofs_dev_ioctl); + in->ioctlfd = -1; + return; +} + +/* + * If you change this make sure you make the corresponding change + * to autofs-dev-ioctl.c:lookup_ioctl() + */ +enum { + /* Get various version info */ + AUTOFS_DEV_IOCTL_VERSION_CMD = 0x71, + AUTOFS_DEV_IOCTL_PROTOVER_CMD, + AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, + + /* Open mount ioctl fd */ + AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, + + /* Close mount ioctl fd */ + AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, + + /* Mount/expire status returns */ + AUTOFS_DEV_IOCTL_READY_CMD, + AUTOFS_DEV_IOCTL_FAIL_CMD, + + /* Activate/deactivate autofs mount */ + AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, + AUTOFS_DEV_IOCTL_CATATONIC_CMD, + + /* Expiry timeout */ + AUTOFS_DEV_IOCTL_TIMEOUT_CMD, + + /* Get mount last requesting uid and gid */ + AUTOFS_DEV_IOCTL_REQUESTER_CMD, + + /* Check for eligible expire candidates */ + AUTOFS_DEV_IOCTL_EXPIRE_CMD, + + /* Request busy status */ + AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, + + /* Check if path is a mountpoint */ + AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, +}; + +#define AUTOFS_IOCTL 0x93 + +#define AUTOFS_DEV_IOCTL_VERSION \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_VERSION_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_PROTOVER \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_PROTOVER_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_PROTOSUBVER \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_OPENMOUNT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_CLOSEMOUNT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_READY \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_READY_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_FAIL \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_FAIL_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_SETPIPEFD \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_CATATONIC \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_CATATONIC_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_TIMEOUT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_TIMEOUT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_REQUESTER \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_REQUESTER_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_EXPIRE \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_EXPIRE_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_ASKUMOUNT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_ISMOUNTPOINT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, struct autofs_dev_ioctl) + +#endif /* _LINUX_AUTO_DEV_IOCTL_H */ diff --git a/src/linux/fanotify.h b/src/linux/fanotify.h new file mode 100644 index 0000000..63531a6 --- /dev/null +++ b/src/linux/fanotify.h @@ -0,0 +1,98 @@ +#ifndef _LINUX_FANOTIFY_H +#define _LINUX_FANOTIFY_H + +#include + +/* the following events that user-space can register for */ +#define FAN_ACCESS 0x00000001 /* File was accessed */ +#define FAN_MODIFY 0x00000002 /* File was modified */ +#define FAN_CLOSE_WRITE 0x00000008 /* Unwrittable file closed */ +#define FAN_CLOSE_NOWRITE 0x00000010 /* Writtable file closed */ +#define FAN_OPEN 0x00000020 /* File was opened */ + +#define FAN_EVENT_ON_CHILD 0x08000000 /* interested in child events */ + +/* FIXME currently Q's have no limit.... */ +#define FAN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ + +#define FAN_OPEN_PERM 0x00010000 /* File open in perm check */ +#define FAN_ACCESS_PERM 0x00020000 /* File accessed in perm check */ + +/* helper events */ +#define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */ + +/* flags used for fanotify_init() */ +#define FAN_CLOEXEC 0x00000001 +#define FAN_NONBLOCK 0x00000002 + +#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK) + +/* flags used for fanotify_modify_mark() */ +#define FAN_MARK_ADD 0x00000001 +#define FAN_MARK_REMOVE 0x00000002 +#define FAN_MARK_DONT_FOLLOW 0x00000004 +#define FAN_MARK_ONLYDIR 0x00000008 +#define FAN_MARK_MOUNT 0x00000010 +#define FAN_MARK_IGNORED_MASK 0x00000020 +#define FAN_MARK_IGNORED_SURV_MODIFY 0x00000040 +#define FAN_MARK_FLUSH 0x00000080 + +#define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD |\ + FAN_MARK_REMOVE |\ + FAN_MARK_DONT_FOLLOW |\ + FAN_MARK_ONLYDIR |\ + FAN_MARK_MOUNT |\ + FAN_MARK_IGNORED_MASK |\ + FAN_MARK_IGNORED_SURV_MODIFY) + +/* + * All of the events - we build the list by hand so that we can add flags in + * the future and not break backward compatibility. Apps will get only the + * events that they originally wanted. Be sure to add new events here! + */ +#define FAN_ALL_EVENTS (FAN_ACCESS |\ + FAN_MODIFY |\ + FAN_CLOSE |\ + FAN_OPEN) + +/* + * All events which require a permission response from userspace + */ +#define FAN_ALL_PERM_EVENTS (FAN_OPEN_PERM |\ + FAN_ACCESS_PERM) + +#define FAN_ALL_OUTGOING_EVENTS (FAN_ALL_EVENTS |\ + FAN_ALL_PERM_EVENTS |\ + FAN_Q_OVERFLOW) + +#define FANOTIFY_METADATA_VERSION 2 + +struct fanotify_event_metadata { + __u32 event_len; + __u32 vers; + __u64 mask; + __s32 fd; + __s32 pid; +} __attribute__ ((packed)); + +struct fanotify_response { + __s32 fd; + __u32 response; +} __attribute__ ((packed)); + +/* Legit userspace responses to a _PERM event */ +#define FAN_ALLOW 0x01 +#define FAN_DENY 0x02 + +/* Helper functions to deal with fanotify_event_metadata buffers */ +#define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata)) + +#define FAN_EVENT_NEXT(meta, len) ((len) -= (meta)->event_len, \ + (struct fanotify_event_metadata*)(((char *)(meta)) + \ + (meta)->event_len)) + +#define FAN_EVENT_OK(meta, len) ((long)(len) >= (long)FAN_EVENT_METADATA_LEN && \ + (long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && \ + (long)(meta)->event_len <= (long)(len)) + +#endif /* _LINUX_FANOTIFY_H */ diff --git a/src/list.h b/src/list.h new file mode 100644 index 0000000..2bec8c9 --- /dev/null +++ b/src/list.h @@ -0,0 +1,128 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foolisthfoo +#define foolisthfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +/* The head of the linked list. Use this in the structure that shall + * contain the head of the linked list */ +#define LIST_HEAD(t,name) \ + t *name + +/* The pointers in the linked list's items. Use this in the item structure */ +#define LIST_FIELDS(t,name) \ + t *name##_next, *name##_prev + +/* Initialize the list's head */ +#define LIST_HEAD_INIT(t,head) \ + do { \ + (head) = NULL; } \ + while(false) + +/* Initialize a list item */ +#define LIST_INIT(t,name,item) \ + do { \ + t *_item = (item); \ + assert(_item); \ + _item->name##_prev = _item->name##_next = NULL; \ + } while(false) + +/* Prepend an item to the list */ +#define LIST_PREPEND(t,name,head,item) \ + do { \ + t **_head = &(head), *_item = (item); \ + assert(_item); \ + if ((_item->name##_next = *_head)) \ + _item->name##_next->name##_prev = _item; \ + _item->name##_prev = NULL; \ + *_head = _item; \ + } while(false) + +/* Remove an item from the list */ +#define LIST_REMOVE(t,name,head,item) \ + do { \ + t **_head = &(head), *_item = (item); \ + assert(_item); \ + if (_item->name##_next) \ + _item->name##_next->name##_prev = _item->name##_prev; \ + if (_item->name##_prev) \ + _item->name##_prev->name##_next = _item->name##_next; \ + else { \ + assert(*_head == _item); \ + *_head = _item->name##_next; \ + } \ + _item->name##_next = _item->name##_prev = NULL; \ + } while(false) + +/* Find the head of the list */ +#define LIST_FIND_HEAD(t,name,item,head) \ + do { \ + t *_item = (item); \ + assert(_item); \ + while (_item->name##_prev) \ + _item = _item->name##_prev; \ + (head) = _item; \ + } while (false) + +/* Find the head of the list */ +#define LIST_FIND_TAIL(t,name,item,tail) \ + do { \ + t *_item = (item); \ + assert(_item); \ + while (_item->name##_next) \ + _item = _item->name##_next; \ + (tail) = _item; \ + } while (false) + +/* Insert an item after another one (a = where, b = what) */ +#define LIST_INSERT_AFTER(t,name,head,a,b) \ + do { \ + t **_head = &(head), *_a = (a), *_b = (b); \ + assert(_b); \ + if (!_a) { \ + if ((_b->name##_next = *_head)) \ + _b->name##_next->name##_prev = _b; \ + _b->name##_prev = NULL; \ + *_head = _b; \ + } else { \ + if ((_b->name##_next = _a->name##_next)) \ + _b->name##_next->name##_prev = _b; \ + _b->name##_prev = _a; \ + _a->name##_next = _b; \ + } \ + } while(false) + +#define LIST_JUST_US(name,item) \ + (!(item)->name##_prev && !(item)->name##_next) \ + +#define LIST_FOREACH(name,i,head) \ + for ((i) = (head); (i); (i) = (i)->name##_next) + +#define LIST_FOREACH_SAFE(name,i,n,head) \ + for ((i) = (head); (i) && (((n) = (i)->name##_next), 1); (i) = (n)) + +#define LIST_FOREACH_BEFORE(name,i,p) \ + for ((i) = (p)->name##_prev; (i); (i) = (i)->name##_prev) + +#define LIST_FOREACH_AFTER(name,i,p) \ + for ((i) = (p)->name##_next; (i); (i) = (i)->name##_next) + +#endif diff --git a/src/load-dropin.c b/src/load-dropin.c new file mode 100644 index 0000000..d869ee0 --- /dev/null +++ b/src/load-dropin.c @@ -0,0 +1,150 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "unit.h" +#include "load-dropin.h" +#include "log.h" +#include "strv.h" +#include "unit-name.h" + +static int iterate_dir(Unit *u, const char *path, UnitDependency dependency) { + DIR *d; + struct dirent *de; + int r; + + assert(u); + assert(path); + + d = opendir(path); + if (!d) { + + if (errno == ENOENT) + return 0; + + return -errno; + } + + while ((de = readdir(d))) { + char *f; + + if (ignore_file(de->d_name)) + continue; + + f = join(path, "/", de->d_name, NULL); + if (!f) { + r = -ENOMEM; + goto finish; + } + + r = unit_add_dependency_by_name(u, dependency, de->d_name, f, true); + free(f); + + if (r < 0) + log_error("Cannot add dependency %s to %s, ignoring: %s", de->d_name, u->id, strerror(-r)); + } + + r = 0; + +finish: + closedir(d); + return r; +} + +static int process_dir(Unit *u, const char *unit_path, const char *name, const char *suffix, UnitDependency dependency) { + int r; + char *path; + + assert(u); + assert(unit_path); + assert(name); + assert(suffix); + + path = join(unit_path, "/", name, suffix, NULL); + if (!path) + return -ENOMEM; + + if (u->manager->unit_path_cache && + !set_get(u->manager->unit_path_cache, path)) + r = 0; + else + r = iterate_dir(u, path, dependency); + free(path); + + if (r < 0) + return r; + + if (u->instance) { + char *template; + /* Also try the template dir */ + + template = unit_name_template(name); + if (!template) + return -ENOMEM; + + path = join(unit_path, "/", template, suffix, NULL); + free(template); + + if (!path) + return -ENOMEM; + + if (u->manager->unit_path_cache && + !set_get(u->manager->unit_path_cache, path)) + r = 0; + else + r = iterate_dir(u, path, dependency); + free(path); + + if (r < 0) + return r; + } + + return 0; +} + +int unit_load_dropin(Unit *u) { + Iterator i; + char *t; + + assert(u); + + /* Load dependencies from supplementary drop-in directories */ + + SET_FOREACH(t, u->names, i) { + char **p; + + STRV_FOREACH(p, u->manager->lookup_paths.unit_path) { + int r; + + r = process_dir(u, *p, t, ".wants", UNIT_WANTS); + if (r < 0) + return r; + + r = process_dir(u, *p, t, ".requires", UNIT_REQUIRES); + if (r < 0) + return r; + } + } + + return 0; +} diff --git a/src/load-dropin.h b/src/load-dropin.h new file mode 100644 index 0000000..cf3a799 --- /dev/null +++ b/src/load-dropin.h @@ -0,0 +1,31 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooloaddropinhfoo +#define fooloaddropinhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "unit.h" + +/* Read service data supplementary drop-in directories */ + +int unit_load_dropin(Unit *u); + +#endif diff --git a/src/load-fragment-gperf.gperf.m4 b/src/load-fragment-gperf.gperf.m4 new file mode 100644 index 0000000..44ce4bb --- /dev/null +++ b/src/load-fragment-gperf.gperf.m4 @@ -0,0 +1,229 @@ +%{ +#include +#include "conf-parser.h" +#include "load-fragment.h" +#include "missing.h" +%} +struct ConfigPerfItem; +%null_strings +%language=ANSI-C +%define slot-name section_and_lvalue +%define hash-function-name load_fragment_gperf_hash +%define lookup-function-name load_fragment_gperf_lookup +%readonly-tables +%omit-struct-type +%struct-type +%includes +%% +m4_dnl Define the context options only once +m4_define(`EXEC_CONTEXT_CONFIG_ITEMS', +`$1.WorkingDirectory, config_parse_unit_path_printf, 0, offsetof($1, exec_context.working_directory) +$1.RootDirectory, config_parse_unit_path_printf, 0, offsetof($1, exec_context.root_directory) +$1.User, config_parse_unit_string_printf, 0, offsetof($1, exec_context.user) +$1.Group, config_parse_unit_string_printf, 0, offsetof($1, exec_context.group) +$1.SupplementaryGroups, config_parse_strv, 0, offsetof($1, exec_context.supplementary_groups) +$1.Nice, config_parse_exec_nice, 0, offsetof($1, exec_context) +$1.OOMScoreAdjust, config_parse_exec_oom_score_adjust, 0, offsetof($1, exec_context) +$1.IOSchedulingClass, config_parse_exec_io_class, 0, offsetof($1, exec_context) +$1.IOSchedulingPriority, config_parse_exec_io_priority, 0, offsetof($1, exec_context) +$1.CPUSchedulingPolicy, config_parse_exec_cpu_sched_policy, 0, offsetof($1, exec_context) +$1.CPUSchedulingPriority, config_parse_exec_cpu_sched_prio, 0, offsetof($1, exec_context) +$1.CPUSchedulingResetOnFork, config_parse_bool, 0, offsetof($1, exec_context.cpu_sched_reset_on_fork) +$1.CPUAffinity, config_parse_exec_cpu_affinity, 0, offsetof($1, exec_context) +$1.UMask, config_parse_mode, 0, offsetof($1, exec_context.umask) +$1.Environment, config_parse_unit_strv_printf, 0, offsetof($1, exec_context.environment) +$1.EnvironmentFile, config_parse_unit_env_file, 0, offsetof($1, exec_context.environment_files) +$1.StandardInput, config_parse_input, 0, offsetof($1, exec_context.std_input) +$1.StandardOutput, config_parse_output, 0, offsetof($1, exec_context.std_output) +$1.StandardError, config_parse_output, 0, offsetof($1, exec_context.std_error) +$1.TTYPath, config_parse_unit_path_printf, 0, offsetof($1, exec_context.tty_path) +$1.TTYReset, config_parse_bool, 0, offsetof($1, exec_context.tty_reset) +$1.TTYVHangup, config_parse_bool, 0, offsetof($1, exec_context.tty_vhangup) +$1.TTYVTDisallocate, config_parse_bool, 0, offsetof($1, exec_context.tty_vt_disallocate) +$1.SyslogIdentifier, config_parse_unit_string_printf, 0, offsetof($1, exec_context.syslog_identifier) +$1.SyslogFacility, config_parse_facility, 0, offsetof($1, exec_context.syslog_priority) +$1.SyslogLevel, config_parse_level, 0, offsetof($1, exec_context.syslog_priority) +$1.SyslogLevelPrefix, config_parse_bool, 0, offsetof($1, exec_context.syslog_level_prefix) +$1.Capabilities, config_parse_exec_capabilities, 0, offsetof($1, exec_context) +$1.SecureBits, config_parse_exec_secure_bits, 0, offsetof($1, exec_context) +$1.CapabilityBoundingSet, config_parse_exec_bounding_set, 0, offsetof($1, exec_context) +$1.TimerSlackNSec, config_parse_exec_timer_slack_nsec, 0, offsetof($1, exec_context) +$1.LimitCPU, config_parse_limit, RLIMIT_CPU, offsetof($1, exec_context.rlimit) +$1.LimitFSIZE, config_parse_limit, RLIMIT_FSIZE, offsetof($1, exec_context.rlimit) +$1.LimitDATA, config_parse_limit, RLIMIT_DATA, offsetof($1, exec_context.rlimit) +$1.LimitSTACK, config_parse_limit, RLIMIT_STACK, offsetof($1, exec_context.rlimit) +$1.LimitCORE, config_parse_limit, RLIMIT_CORE, offsetof($1, exec_context.rlimit) +$1.LimitRSS, config_parse_limit, RLIMIT_RSS, offsetof($1, exec_context.rlimit) +$1.LimitNOFILE, config_parse_limit, RLIMIT_NOFILE, offsetof($1, exec_context.rlimit) +$1.LimitAS, config_parse_limit, RLIMIT_AS, offsetof($1, exec_context.rlimit) +$1.LimitNPROC, config_parse_limit, RLIMIT_NPROC, offsetof($1, exec_context.rlimit) +$1.LimitMEMLOCK, config_parse_limit, RLIMIT_MEMLOCK, offsetof($1, exec_context.rlimit) +$1.LimitLOCKS, config_parse_limit, RLIMIT_LOCKS, offsetof($1, exec_context.rlimit) +$1.LimitSIGPENDING, config_parse_limit, RLIMIT_SIGPENDING, offsetof($1, exec_context.rlimit) +$1.LimitMSGQUEUE, config_parse_limit, RLIMIT_MSGQUEUE, offsetof($1, exec_context.rlimit) +$1.LimitNICE, config_parse_limit, RLIMIT_NICE, offsetof($1, exec_context.rlimit) +$1.LimitRTPRIO, config_parse_limit, RLIMIT_RTPRIO, offsetof($1, exec_context.rlimit) +$1.LimitRTTIME, config_parse_limit, RLIMIT_RTTIME, offsetof($1, exec_context.rlimit) +$1.ControlGroup, config_parse_unit_cgroup, 0, 0 +$1.ControlGroupAttribute, config_parse_unit_cgroup_attr, 0, 0 +$1.CPUShares, config_parse_unit_cpu_shares, 0, 0 +$1.MemoryLimit, config_parse_unit_memory_limit, 0, 0 +$1.MemorySoftLimit, config_parse_unit_memory_limit, 0, 0 +$1.DeviceAllow, config_parse_unit_device_allow, 0, 0 +$1.DeviceDeny, config_parse_unit_device_allow, 0, 0 +$1.BlockIOWeight, config_parse_unit_blkio_weight, 0, 0 +$1.BlockIOReadBandwidth, config_parse_unit_blkio_bandwidth, 0, 0 +$1.BlockIOWriteBandwidth, config_parse_unit_blkio_bandwidth, 0, 0 +$1.ReadWriteDirectories, config_parse_path_strv, 0, offsetof($1, exec_context.read_write_dirs) +$1.ReadOnlyDirectories, config_parse_path_strv, 0, offsetof($1, exec_context.read_only_dirs) +$1.InaccessibleDirectories, config_parse_path_strv, 0, offsetof($1, exec_context.inaccessible_dirs) +$1.PrivateTmp, config_parse_bool, 0, offsetof($1, exec_context.private_tmp) +$1.PrivateNetwork, config_parse_bool, 0, offsetof($1, exec_context.private_network) +$1.MountFlags, config_parse_exec_mount_flags, 0, offsetof($1, exec_context) +$1.TCPWrapName, config_parse_unit_string_printf, 0, offsetof($1, exec_context.tcpwrap_name) +$1.PAMName, config_parse_unit_string_printf, 0, offsetof($1, exec_context.pam_name) +$1.KillMode, config_parse_kill_mode, 0, offsetof($1, exec_context.kill_mode) +$1.KillSignal, config_parse_kill_signal, 0, offsetof($1, exec_context.kill_signal) +$1.SendSIGKILL, config_parse_bool, 0, offsetof($1, exec_context.send_sigkill) +$1.IgnoreSIGPIPE, config_parse_bool, 0, offsetof($1, exec_context.ignore_sigpipe) +$1.UtmpIdentifier, config_parse_unit_string_printf, 0, offsetof($1, exec_context.utmp_id) +$1.ControlGroupModify, config_parse_bool, 0, offsetof($1, exec_context.control_group_modify) +$1.ControlGroupPersistent, config_parse_tristate, 0, offsetof($1, exec_context.control_group_persistent)' +)m4_dnl +Unit.Names, config_parse_unit_names, 0, 0 +Unit.Description, config_parse_unit_string_printf, 0, offsetof(Unit, description) +Unit.Requires, config_parse_unit_deps, UNIT_REQUIRES, 0 +Unit.RequiresOverridable, config_parse_unit_deps, UNIT_REQUIRES_OVERRIDABLE, 0 +Unit.Requisite, config_parse_unit_deps, UNIT_REQUISITE, 0 +Unit.RequisiteOverridable, config_parse_unit_deps, UNIT_REQUISITE_OVERRIDABLE, 0 +Unit.Wants, config_parse_unit_deps, UNIT_WANTS, 0 +Unit.BindTo, config_parse_unit_deps, UNIT_BIND_TO, 0 +Unit.Conflicts, config_parse_unit_deps, UNIT_CONFLICTS, 0 +Unit.Before, config_parse_unit_deps, UNIT_BEFORE, 0 +Unit.After, config_parse_unit_deps, UNIT_AFTER, 0 +Unit.OnFailure, config_parse_unit_deps, UNIT_ON_FAILURE, 0 +Unit.PropagateReloadTo, config_parse_unit_deps, UNIT_PROPAGATE_RELOAD_TO, 0 +Unit.PropagateReloadFrom, config_parse_unit_deps, UNIT_PROPAGATE_RELOAD_FROM, 0 +Unit.StopWhenUnneeded, config_parse_bool, 0, offsetof(Unit, stop_when_unneeded) +Unit.RefuseManualStart, config_parse_bool, 0, offsetof(Unit, refuse_manual_start) +Unit.RefuseManualStop, config_parse_bool, 0, offsetof(Unit, refuse_manual_stop) +Unit.AllowIsolate, config_parse_bool, 0, offsetof(Unit, allow_isolate) +Unit.DefaultDependencies, config_parse_bool, 0, offsetof(Unit, default_dependencies) +Unit.OnFailureIsolate, config_parse_bool, 0, offsetof(Unit, on_failure_isolate) +Unit.IgnoreOnIsolate, config_parse_bool, 0, offsetof(Unit, ignore_on_isolate) +Unit.IgnoreOnSnapshot, config_parse_bool, 0, offsetof(Unit, ignore_on_snapshot) +Unit.JobTimeoutSec, config_parse_usec, 0, offsetof(Unit, job_timeout) +Unit.ConditionPathExists, config_parse_unit_condition_path, CONDITION_PATH_EXISTS, 0 +Unit.ConditionPathExistsGlob, config_parse_unit_condition_path, CONDITION_PATH_EXISTS_GLOB, 0 +Unit.ConditionPathIsDirectory, config_parse_unit_condition_path, CONDITION_PATH_IS_DIRECTORY, 0 +Unit.ConditionPathIsSymbolicLink,config_parse_unit_condition_path, CONDITION_PATH_IS_SYMBOLIC_LINK,0 +Unit.ConditionPathIsMountPoint, config_parse_unit_condition_path, CONDITION_PATH_IS_MOUNT_POINT, 0 +Unit.ConditionDirectoryNotEmpty, config_parse_unit_condition_path, CONDITION_DIRECTORY_NOT_EMPTY, 0 +Unit.ConditionFileIsExecutable, config_parse_unit_condition_path, CONDITION_FILE_IS_EXECUTABLE, 0 +Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, 0 +Unit.ConditionVirtualization, config_parse_unit_condition_string, CONDITION_VIRTUALIZATION, 0 +Unit.ConditionSecurity, config_parse_unit_condition_string, CONDITION_SECURITY, 0 +Unit.ConditionCapability, config_parse_unit_condition_string, CONDITION_CAPABILITY, 0 +Unit.ConditionNull, config_parse_unit_condition_null, 0, 0 +m4_dnl +Service.PIDFile, config_parse_unit_path_printf, 0, offsetof(Service, pid_file) +Service.ExecStartPre, config_parse_exec, SERVICE_EXEC_START_PRE, offsetof(Service, exec_command) +Service.ExecStart, config_parse_exec, SERVICE_EXEC_START, offsetof(Service, exec_command) +Service.ExecStartPost, config_parse_exec, SERVICE_EXEC_START_POST, offsetof(Service, exec_command) +Service.ExecReload, config_parse_exec, SERVICE_EXEC_RELOAD, offsetof(Service, exec_command) +Service.ExecStop, config_parse_exec, SERVICE_EXEC_STOP, offsetof(Service, exec_command) +Service.ExecStopPost, config_parse_exec, SERVICE_EXEC_STOP_POST, offsetof(Service, exec_command) +Service.RestartSec, config_parse_usec, 0, offsetof(Service, restart_usec) +Service.TimeoutSec, config_parse_usec, 0, offsetof(Service, timeout_usec) +Service.WatchdogSec, config_parse_usec, 0, offsetof(Service, watchdog_usec) +Service.StartLimitInterval, config_parse_usec, 0, offsetof(Service, start_limit.interval) +Service.StartLimitBurst, config_parse_unsigned, 0, offsetof(Service, start_limit.burst) +Service.StartLimitAction, config_parse_start_limit_action, 0, offsetof(Service, start_limit_action) +Service.Type, config_parse_service_type, 0, offsetof(Service, type) +Service.Restart, config_parse_service_restart, 0, offsetof(Service, restart) +Service.PermissionsStartOnly, config_parse_bool, 0, offsetof(Service, permissions_start_only) +Service.RootDirectoryStartOnly, config_parse_bool, 0, offsetof(Service, root_directory_start_only) +Service.RemainAfterExit, config_parse_bool, 0, offsetof(Service, remain_after_exit) +Service.GuessMainPID, config_parse_bool, 0, offsetof(Service, guess_main_pid) +m4_ifdef(`HAVE_SYSV_COMPAT', +`Service.SysVStartPriority, config_parse_sysv_priority, 0, offsetof(Service, sysv_start_priority)', +`Service.SysVStartPriority, config_parse_warn_compat, 0, 0') +Service.NonBlocking, config_parse_bool, 0, offsetof(Service, exec_context.non_blocking) +Service.BusName, config_parse_unit_string_printf, 0, offsetof(Service, bus_name) +Service.NotifyAccess, config_parse_notify_access, 0, offsetof(Service, notify_access) +Service.Sockets, config_parse_service_sockets, 0, 0 +Service.FsckPassNo, config_parse_fsck_passno, 0, offsetof(Service, fsck_passno) +EXEC_CONTEXT_CONFIG_ITEMS(Service)m4_dnl +m4_dnl +Socket.ListenStream, config_parse_socket_listen, 0, 0 +Socket.ListenDatagram, config_parse_socket_listen, 0, 0 +Socket.ListenSequentialPacket, config_parse_socket_listen, 0, 0 +Socket.ListenFIFO, config_parse_socket_listen, 0, 0 +Socket.ListenNetlink, config_parse_socket_listen, 0, 0 +Socket.ListenSpecial, config_parse_socket_listen, 0, 0 +Socket.ListenMessageQueue, config_parse_socket_listen, 0, 0 +Socket.BindIPv6Only, config_parse_socket_bind, 0, 0, +Socket.Backlog, config_parse_unsigned, 0, offsetof(Socket, backlog) +Socket.BindToDevice, config_parse_socket_bindtodevice, 0, 0 +Socket.ExecStartPre, config_parse_exec, SOCKET_EXEC_START_PRE, offsetof(Socket, exec_command) +Socket.ExecStartPost, config_parse_exec, SOCKET_EXEC_START_POST, offsetof(Socket, exec_command) +Socket.ExecStopPre, config_parse_exec, SOCKET_EXEC_STOP_PRE, offsetof(Socket, exec_command) +Socket.ExecStopPost, config_parse_exec, SOCKET_EXEC_STOP_POST, offsetof(Socket, exec_command) +Socket.TimeoutSec, config_parse_usec, 0, offsetof(Socket, timeout_usec) +Socket.DirectoryMode, config_parse_mode, 0, offsetof(Socket, directory_mode) +Socket.SocketMode, config_parse_mode, 0, offsetof(Socket, socket_mode) +Socket.Accept, config_parse_bool, 0, offsetof(Socket, accept) +Socket.MaxConnections, config_parse_unsigned, 0, offsetof(Socket, max_connections) +Socket.KeepAlive, config_parse_bool, 0, offsetof(Socket, keep_alive) +Socket.Priority, config_parse_int, 0, offsetof(Socket, priority) +Socket.ReceiveBuffer, config_parse_bytes_size, 0, offsetof(Socket, receive_buffer) +Socket.SendBuffer, config_parse_bytes_size, 0, offsetof(Socket, send_buffer) +Socket.IPTOS, config_parse_ip_tos, 0, offsetof(Socket, ip_tos) +Socket.IPTTL, config_parse_int, 0, offsetof(Socket, ip_ttl) +Socket.Mark, config_parse_int, 0, offsetof(Socket, mark) +Socket.PipeSize, config_parse_bytes_size, 0, offsetof(Socket, pipe_size) +Socket.FreeBind, config_parse_bool, 0, offsetof(Socket, free_bind) +Socket.Transparent, config_parse_bool, 0, offsetof(Socket, transparent) +Socket.Broadcast, config_parse_bool, 0, offsetof(Socket, broadcast) +Socket.PassCredentials, config_parse_bool, 0, offsetof(Socket, pass_cred) +Socket.TCPCongestion, config_parse_string, 0, offsetof(Socket, tcp_congestion) +Socket.MessageQueueMaxMessages, config_parse_long, 0, offsetof(Socket, mq_maxmsg) +Socket.MessageQueueMessageSize, config_parse_long, 0, offsetof(Socket, mq_msgsize) +Socket.Service, config_parse_socket_service, 0, 0 +EXEC_CONTEXT_CONFIG_ITEMS(Socket)m4_dnl +m4_dnl +Mount.What, config_parse_string, 0, offsetof(Mount, parameters_fragment.what) +Mount.Where, config_parse_path, 0, offsetof(Mount, where) +Mount.Options, config_parse_string, 0, offsetof(Mount, parameters_fragment.options) +Mount.Type, config_parse_string, 0, offsetof(Mount, parameters_fragment.fstype) +Mount.TimeoutSec, config_parse_usec, 0, offsetof(Mount, timeout_usec) +Mount.DirectoryMode, config_parse_mode, 0, offsetof(Mount, directory_mode) +EXEC_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl +m4_dnl +Automount.Where, config_parse_path, 0, offsetof(Automount, where) +Automount.DirectoryMode, config_parse_mode, 0, offsetof(Automount, directory_mode) +m4_dnl +Swap.What, config_parse_path, 0, offsetof(Swap, parameters_fragment.what) +Swap.Priority, config_parse_int, 0, offsetof(Swap, parameters_fragment.priority) +Swap.TimeoutSec, config_parse_usec, 0, offsetof(Swap, timeout_usec) +EXEC_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl +m4_dnl +Timer.OnActiveSec, config_parse_timer, 0, 0 +Timer.OnBootSec, config_parse_timer, 0, 0 +Timer.OnStartupSec, config_parse_timer, 0, 0 +Timer.OnUnitActiveSec, config_parse_timer, 0, 0 +Timer.OnUnitInactiveSec, config_parse_timer, 0, 0 +Timer.Unit, config_parse_timer_unit, 0, 0 +m4_dnl +Path.PathExists, config_parse_path_spec, 0, 0 +Path.PathExistsGlob, config_parse_path_spec, 0, 0 +Path.PathChanged, config_parse_path_spec, 0, 0 +Path.PathModified, config_parse_path_spec, 0, 0 +Path.DirectoryNotEmpty, config_parse_path_spec, 0, 0 +Path.Unit, config_parse_path_unit, 0, 0 +Path.MakeDirectory, config_parse_bool, 0, offsetof(Path, make_directory) +Path.DirectoryMode, config_parse_mode, 0, offsetof(Path, directory_mode) +m4_dnl The [Install] section is ignored here. +Install.Alias, NULL, 0, 0 +Install.WantedBy, NULL, 0, 0 +Install.Also, NULL, 0, 0 diff --git a/src/load-fragment.c b/src/load-fragment.c new file mode 100644 index 0000000..b963d7f --- /dev/null +++ b/src/load-fragment.c @@ -0,0 +1,2431 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "unit.h" +#include "strv.h" +#include "conf-parser.h" +#include "load-fragment.h" +#include "log.h" +#include "ioprio.h" +#include "securebits.h" +#include "missing.h" +#include "unit-name.h" +#include "bus-errors.h" + +#ifndef HAVE_SYSV_COMPAT +int config_parse_warn_compat( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + log_debug("[%s:%u] Support for option %s= has been disabled at compile time and is ignored", filename, line, lvalue); + return 0; +} +#endif + +int config_parse_unit_deps( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + UnitDependency d = ltype; + Unit *u = userdata; + char *w; + size_t l; + char *state; + + assert(filename); + assert(lvalue); + assert(rvalue); + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char *t, *k; + int r; + + t = strndup(w, l); + if (!t) + return -ENOMEM; + + k = unit_name_printf(u, t); + free(t); + + if (!k) + return -ENOMEM; + + r = unit_add_dependency_by_name(u, d, k, NULL, true); + if (r < 0) + log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s", filename, line, k, strerror(-r)); + + free(k); + } + + return 0; +} + +int config_parse_unit_names( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = userdata; + char *w; + size_t l; + char *state; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char *t, *k; + int r; + + if (!(t = strndup(w, l))) + return -ENOMEM; + + k = unit_name_printf(u, t); + free(t); + + if (!k) + return -ENOMEM; + + r = unit_merge_by_name(u, k); + + if (r < 0) { + log_error("Failed to add name %s, ignoring: %s", k, strerror(-r)); + free(k); + return 0; + } + + free(k); + } + + return 0; +} + +int config_parse_unit_string_printf( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = userdata; + char **s = data; + char *k; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(s); + assert(u); + + if (!(k = unit_full_printf(u, rvalue))) + return -ENOMEM; + + free(*s); + if (*k) + *s = k; + else { + free(k); + *s = NULL; + } + + return 0; +} + +int config_parse_unit_strv_printf( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = userdata; + char *k; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(u); + + k = unit_full_printf(u, rvalue); + if (!k) + return -ENOMEM; + + r = config_parse_strv(filename, line, section, lvalue, ltype, k, data, userdata); + free(k); + + return r; +} + +int config_parse_unit_path_printf( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = userdata; + char **s = data; + char *k; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(s); + assert(u); + + if (!(k = unit_full_printf(u, rvalue))) + return -ENOMEM; + + if (!path_is_absolute(k)) { + log_error("[%s:%u] Not an absolute path: %s", filename, line, k); + free(k); + return -EINVAL; + } + + path_kill_slashes(k); + + free(*s); + *s = k; + + return 0; +} + +int config_parse_socket_listen( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + SocketPort *p, *tail; + Socket *s; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + s = SOCKET(data); + + if (!(p = new0(SocketPort, 1))) + return -ENOMEM; + + if (streq(lvalue, "ListenFIFO")) { + p->type = SOCKET_FIFO; + + if (!(p->path = unit_full_printf(UNIT(s), rvalue))) { + free(p); + return -ENOMEM; + } + + path_kill_slashes(p->path); + + } else if (streq(lvalue, "ListenSpecial")) { + p->type = SOCKET_SPECIAL; + + if (!(p->path = unit_full_printf(UNIT(s), rvalue))) { + free(p); + return -ENOMEM; + } + + path_kill_slashes(p->path); + + } else if (streq(lvalue, "ListenMessageQueue")) { + + p->type = SOCKET_MQUEUE; + + if (!(p->path = unit_full_printf(UNIT(s), rvalue))) { + free(p); + return -ENOMEM; + } + + path_kill_slashes(p->path); + + } else if (streq(lvalue, "ListenNetlink")) { + char *k; + int r; + + p->type = SOCKET_SOCKET; + k = unit_full_printf(UNIT(s), rvalue); + r = socket_address_parse_netlink(&p->address, k); + free(k); + + if (r < 0) { + log_error("[%s:%u] Failed to parse address value, ignoring: %s", filename, line, rvalue); + free(p); + return 0; + } + + } else { + char *k; + int r; + + p->type = SOCKET_SOCKET; + k = unit_full_printf(UNIT(s), rvalue); + r = socket_address_parse(&p->address, k); + free(k); + + if (r < 0) { + log_error("[%s:%u] Failed to parse address value, ignoring: %s", filename, line, rvalue); + free(p); + return 0; + } + + if (streq(lvalue, "ListenStream")) + p->address.type = SOCK_STREAM; + else if (streq(lvalue, "ListenDatagram")) + p->address.type = SOCK_DGRAM; + else { + assert(streq(lvalue, "ListenSequentialPacket")); + p->address.type = SOCK_SEQPACKET; + } + + if (socket_address_family(&p->address) != AF_LOCAL && p->address.type == SOCK_SEQPACKET) { + log_error("[%s:%u] Address family not supported, ignoring: %s", filename, line, rvalue); + free(p); + return 0; + } + } + + p->fd = -1; + + if (s->ports) { + LIST_FIND_TAIL(SocketPort, port, s->ports, tail); + LIST_INSERT_AFTER(SocketPort, port, s->ports, tail, p); + } else + LIST_PREPEND(SocketPort, port, s->ports, p); + + return 0; +} + +int config_parse_socket_bind( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Socket *s; + SocketAddressBindIPv6Only b; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + s = SOCKET(data); + + if ((b = socket_address_bind_ipv6_only_from_string(rvalue)) < 0) { + int r; + + if ((r = parse_boolean(rvalue)) < 0) { + log_error("[%s:%u] Failed to parse bind IPv6 only value, ignoring: %s", filename, line, rvalue); + return 0; + } + + s->bind_ipv6_only = r ? SOCKET_ADDRESS_IPV6_ONLY : SOCKET_ADDRESS_BOTH; + } else + s->bind_ipv6_only = b; + + return 0; +} + +int config_parse_exec_nice( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + int priority; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atoi(rvalue, &priority) < 0) { + log_error("[%s:%u] Failed to parse nice priority, ignoring: %s. ", filename, line, rvalue); + return 0; + } + + if (priority < PRIO_MIN || priority >= PRIO_MAX) { + log_error("[%s:%u] Nice priority out of range, ignoring: %s", filename, line, rvalue); + return 0; + } + + c->nice = priority; + c->nice_set = true; + + return 0; +} + +int config_parse_exec_oom_score_adjust( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + int oa; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atoi(rvalue, &oa) < 0) { + log_error("[%s:%u] Failed to parse the OOM score adjust value, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (oa < OOM_SCORE_ADJ_MIN || oa > OOM_SCORE_ADJ_MAX) { + log_error("[%s:%u] OOM score adjust value out of range, ignoring: %s", filename, line, rvalue); + return 0; + } + + c->oom_score_adjust = oa; + c->oom_score_adjust_set = true; + + return 0; +} + +int config_parse_exec( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecCommand **e = data, *nce; + char *path, **n; + unsigned k; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(e); + + /* We accept an absolute path as first argument, or + * alternatively an absolute prefixed with @ to allow + * overriding of argv[0]. */ + + e += ltype; + + for (;;) { + char *w; + size_t l; + char *state; + bool honour_argv0 = false, ignore = false; + + path = NULL; + nce = NULL; + n = NULL; + + rvalue += strspn(rvalue, WHITESPACE); + + if (rvalue[0] == 0) + break; + + if (rvalue[0] == '-') { + ignore = true; + rvalue ++; + } + + if (rvalue[0] == '@') { + honour_argv0 = true; + rvalue ++; + } + + if (*rvalue != '/') { + log_error("[%s:%u] Invalid executable path in command line, ignoring: %s", filename, line, rvalue); + return 0; + } + + k = 0; + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + if (strncmp(w, ";", MAX(l, 1U)) == 0) + break; + + k++; + } + + if (!(n = new(char*, k + !honour_argv0))) + return -ENOMEM; + + k = 0; + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + if (strncmp(w, ";", MAX(l, 1U)) == 0) + break; + + if (honour_argv0 && w == rvalue) { + assert(!path); + if (!(path = cunescape_length(w, l))) + goto fail; + } else { + if (!(n[k++] = cunescape_length(w, l))) + goto fail; + } + } + + n[k] = NULL; + + if (!n[0]) { + log_error("[%s:%u] Invalid command line, ignoring: %s", filename, line, rvalue); + strv_free(n); + free(path); + return 0; + } + + if (!path) + if (!(path = strdup(n[0]))) + goto fail; + + assert(path_is_absolute(path)); + + if (!(nce = new0(ExecCommand, 1))) + goto fail; + + nce->argv = n; + nce->path = path; + nce->ignore = ignore; + + path_kill_slashes(nce->path); + + exec_command_append_list(e, nce); + + rvalue = state; + } + + return 0; + +fail: + n[k] = NULL; + strv_free(n); + free(path); + free(nce); + + return -ENOMEM; +} + +DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier"); + +int config_parse_socket_bindtodevice( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Socket *s = data; + char *n; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (rvalue[0] && !streq(rvalue, "*")) { + if (!(n = strdup(rvalue))) + return -ENOMEM; + } else + n = NULL; + + free(s->bind_to_device); + s->bind_to_device = n; + + return 0; +} + +DEFINE_CONFIG_PARSE_ENUM(config_parse_output, exec_output, ExecOutput, "Failed to parse output specifier"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_input, exec_input, ExecInput, "Failed to parse input specifier"); + +int config_parse_facility( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + + int *o = data, x; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((x = log_facility_unshifted_from_string(rvalue)) < 0) { + log_error("[%s:%u] Failed to parse log facility, ignoring: %s", filename, line, rvalue); + return 0; + } + + *o = (x << 3) | LOG_PRI(*o); + + return 0; +} + +int config_parse_level( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + + int *o = data, x; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((x = log_level_from_string(rvalue)) < 0) { + log_error("[%s:%u] Failed to parse log level, ignoring: %s", filename, line, rvalue); + return 0; + } + + *o = (*o & LOG_FACMASK) | x; + return 0; +} + +int config_parse_exec_io_class( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + int x; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((x = ioprio_class_from_string(rvalue)) < 0) { + log_error("[%s:%u] Failed to parse IO scheduling class, ignoring: %s", filename, line, rvalue); + return 0; + } + + c->ioprio = IOPRIO_PRIO_VALUE(x, IOPRIO_PRIO_DATA(c->ioprio)); + c->ioprio_set = true; + + return 0; +} + +int config_parse_exec_io_priority( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + int i; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atoi(rvalue, &i) < 0 || i < 0 || i >= IOPRIO_BE_NR) { + log_error("[%s:%u] Failed to parse io priority, ignoring: %s", filename, line, rvalue); + return 0; + } + + c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), i); + c->ioprio_set = true; + + return 0; +} + +int config_parse_exec_cpu_sched_policy( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + + ExecContext *c = data; + int x; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((x = sched_policy_from_string(rvalue)) < 0) { + log_error("[%s:%u] Failed to parse CPU scheduling policy, ignoring: %s", filename, line, rvalue); + return 0; + } + + c->cpu_sched_policy = x; + c->cpu_sched_set = true; + + return 0; +} + +int config_parse_exec_cpu_sched_prio( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + int i; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + /* On Linux RR/FIFO have the same range */ + if (safe_atoi(rvalue, &i) < 0 || i < sched_get_priority_min(SCHED_RR) || i > sched_get_priority_max(SCHED_RR)) { + log_error("[%s:%u] Failed to parse CPU scheduling priority, ignoring: %s", filename, line, rvalue); + return 0; + } + + c->cpu_sched_priority = i; + c->cpu_sched_set = true; + + return 0; +} + +int config_parse_exec_cpu_affinity( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + char *w; + size_t l; + char *state; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char *t; + int r; + unsigned cpu; + + if (!(t = strndup(w, l))) + return -ENOMEM; + + r = safe_atou(t, &cpu); + free(t); + + if (!(c->cpuset)) + if (!(c->cpuset = cpu_set_malloc(&c->cpuset_ncpus))) + return -ENOMEM; + + if (r < 0 || cpu >= c->cpuset_ncpus) { + log_error("[%s:%u] Failed to parse CPU affinity, ignoring: %s", filename, line, rvalue); + return 0; + } + + CPU_SET_S(cpu, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset); + } + + return 0; +} + +int config_parse_exec_capabilities( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + cap_t cap; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (!(cap = cap_from_text(rvalue))) { + if (errno == ENOMEM) + return -ENOMEM; + + log_error("[%s:%u] Failed to parse capabilities, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (c->capabilities) + cap_free(c->capabilities); + c->capabilities = cap; + + return 0; +} + +int config_parse_exec_secure_bits( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + char *w; + size_t l; + char *state; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + if (first_word(w, "keep-caps")) + c->secure_bits |= SECURE_KEEP_CAPS; + else if (first_word(w, "keep-caps-locked")) + c->secure_bits |= SECURE_KEEP_CAPS_LOCKED; + else if (first_word(w, "no-setuid-fixup")) + c->secure_bits |= SECURE_NO_SETUID_FIXUP; + else if (first_word(w, "no-setuid-fixup-locked")) + c->secure_bits |= SECURE_NO_SETUID_FIXUP_LOCKED; + else if (first_word(w, "noroot")) + c->secure_bits |= SECURE_NOROOT; + else if (first_word(w, "noroot-locked")) + c->secure_bits |= SECURE_NOROOT_LOCKED; + else { + log_error("[%s:%u] Failed to parse secure bits, ignoring: %s", filename, line, rvalue); + return 0; + } + } + + return 0; +} + +int config_parse_exec_bounding_set( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + char *w; + size_t l; + char *state; + bool invert = false; + uint64_t sum = 0; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (rvalue[0] == '~') { + invert = true; + rvalue++; + } + + /* Note that we store this inverted internally, since the + * kernel wants it like this. But we actually expose it + * non-inverted everywhere to have a fully normalized + * interface. */ + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char *t; + int r; + cap_value_t cap; + + if (!(t = strndup(w, l))) + return -ENOMEM; + + r = cap_from_name(t, &cap); + free(t); + + if (r < 0) { + log_error("[%s:%u] Failed to parse capability bounding set, ignoring: %s", filename, line, rvalue); + return 0; + } + + sum |= ((uint64_t) 1ULL) << (uint64_t) cap; + } + + if (invert) + c->capability_bounding_set_drop |= sum; + else + c->capability_bounding_set_drop |= ~sum; + + return 0; +} + +int config_parse_exec_timer_slack_nsec( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + unsigned long u; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atolu(rvalue, &u) < 0) { + log_error("[%s:%u] Failed to parse time slack value, ignoring: %s", filename, line, rvalue); + return 0; + } + + c->timer_slack_nsec = u; + + return 0; +} + +int config_parse_limit( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + struct rlimit **rl = data; + unsigned long long u; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + rl += ltype; + + if (streq(rvalue, "infinity")) + u = (unsigned long long) RLIM_INFINITY; + else if (safe_atollu(rvalue, &u) < 0) { + log_error("[%s:%u] Failed to parse resource value, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (!*rl) + if (!(*rl = new(struct rlimit, 1))) + return -ENOMEM; + + (*rl)->rlim_cur = (*rl)->rlim_max = (rlim_t) u; + return 0; +} + +int config_parse_unit_cgroup( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = userdata; + char *w; + size_t l; + char *state; + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char *t, *k; + int r; + + t = strndup(w, l); + if (!t) + return -ENOMEM; + + k = unit_full_printf(u, t); + free(t); + + if (!k) + return -ENOMEM; + + t = cunescape(k); + free(k); + + if (!t) + return -ENOMEM; + + r = unit_add_cgroup_from_text(u, t); + free(t); + + if (r < 0) { + log_error("[%s:%u] Failed to parse cgroup value, ignoring: %s", filename, line, rvalue); + return 0; + } + } + + return 0; +} + +#ifdef HAVE_SYSV_COMPAT +int config_parse_sysv_priority( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + int *priority = data; + int i; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atoi(rvalue, &i) < 0 || i < 0) { + log_error("[%s:%u] Failed to parse SysV start priority, ignoring: %s", filename, line, rvalue); + return 0; + } + + *priority = (int) i; + return 0; +} +#endif + +int config_parse_fsck_passno( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + int *passno = data; + int i; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atoi(rvalue, &i) || i < 0) { + log_error("[%s:%u] Failed to parse fsck pass number, ignoring: %s", filename, line, rvalue); + return 0; + } + + *passno = (int) i; + return 0; +} + +DEFINE_CONFIG_PARSE_ENUM(config_parse_kill_mode, kill_mode, KillMode, "Failed to parse kill mode"); + +int config_parse_kill_signal( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + int *sig = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(sig); + + if ((r = signal_from_string_try_harder(rvalue)) <= 0) { + log_error("[%s:%u] Failed to parse kill signal, ignoring: %s", filename, line, rvalue); + return 0; + } + + *sig = r; + return 0; +} + +int config_parse_exec_mount_flags( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + char *w; + size_t l; + char *state; + unsigned long flags = 0; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + if (strncmp(w, "shared", MAX(l, 6U)) == 0) + flags |= MS_SHARED; + else if (strncmp(w, "slave", MAX(l, 5U)) == 0) + flags |= MS_SLAVE; + else if (strncmp(w, "private", MAX(l, 7U)) == 0) + flags |= MS_PRIVATE; + else { + log_error("[%s:%u] Failed to parse mount flags, ignoring: %s", filename, line, rvalue); + return 0; + } + } + + c->mount_flags = flags; + return 0; +} + +int config_parse_timer( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Timer *t = data; + usec_t u; + TimerValue *v; + TimerBase b; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((b = timer_base_from_string(lvalue)) < 0) { + log_error("[%s:%u] Failed to parse timer base, ignoring: %s", filename, line, lvalue); + return 0; + } + + if (parse_usec(rvalue, &u) < 0) { + log_error("[%s:%u] Failed to parse timer value, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (!(v = new0(TimerValue, 1))) + return -ENOMEM; + + v->base = b; + v->value = u; + + LIST_PREPEND(TimerValue, value, t->values, v); + + return 0; +} + +int config_parse_timer_unit( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Timer *t = data; + int r; + DBusError error; + Unit *u; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + dbus_error_init(&error); + + if (endswith(rvalue, ".timer")) { + log_error("[%s:%u] Unit cannot be of type timer, ignoring: %s", filename, line, rvalue); + return 0; + } + + r = manager_load_unit(UNIT(t)->manager, rvalue, NULL, NULL, &u); + if (r < 0) { + log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r)); + dbus_error_free(&error); + return 0; + } + + unit_ref_set(&t->unit, u); + + return 0; +} + +int config_parse_path_spec( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Path *p = data; + PathSpec *s; + PathType b; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((b = path_type_from_string(lvalue)) < 0) { + log_error("[%s:%u] Failed to parse path type, ignoring: %s", filename, line, lvalue); + return 0; + } + + if (!path_is_absolute(rvalue)) { + log_error("[%s:%u] Path is not absolute, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (!(s = new0(PathSpec, 1))) + return -ENOMEM; + + if (!(s->path = strdup(rvalue))) { + free(s); + return -ENOMEM; + } + + path_kill_slashes(s->path); + + s->type = b; + s->inotify_fd = -1; + + LIST_PREPEND(PathSpec, spec, p->specs, s); + + return 0; +} + +int config_parse_path_unit( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Path *t = data; + int r; + DBusError error; + Unit *u; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + dbus_error_init(&error); + + if (endswith(rvalue, ".path")) { + log_error("[%s:%u] Unit cannot be of type path, ignoring: %s", filename, line, rvalue); + return 0; + } + + if ((r = manager_load_unit(UNIT(t)->manager, rvalue, NULL, &error, &u)) < 0) { + log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r)); + dbus_error_free(&error); + return 0; + } + + unit_ref_set(&t->unit, u); + + return 0; +} + +int config_parse_socket_service( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Socket *s = data; + int r; + DBusError error; + Unit *x; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + dbus_error_init(&error); + + if (!endswith(rvalue, ".service")) { + log_error("[%s:%u] Unit must be of type service, ignoring: %s", filename, line, rvalue); + return 0; + } + + r = manager_load_unit(UNIT(s)->manager, rvalue, NULL, &error, &x); + if (r < 0) { + log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r)); + dbus_error_free(&error); + return 0; + } + + unit_ref_set(&s->service, x); + + return 0; +} + +int config_parse_service_sockets( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Service *s = data; + int r; + char *state, *w; + size_t l; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char *t, *k; + + t = strndup(w, l); + if (!t) + return -ENOMEM; + + k = unit_name_printf(UNIT(s), t); + free(t); + + if (!k) + return -ENOMEM; + + if (!endswith(k, ".socket")) { + log_error("[%s:%u] Unit must be of type socket, ignoring: %s", filename, line, rvalue); + free(k); + continue; + } + + r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_WANTS, UNIT_AFTER, k, NULL, true); + if (r < 0) + log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s", filename, line, k, strerror(-r)); + + r = unit_add_dependency_by_name(UNIT(s), UNIT_TRIGGERED_BY, k, NULL, true); + if (r < 0) + return r; + + free(k); + } + + return 0; +} + +int config_parse_unit_env_file( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char ***env = data, **k; + Unit *u = userdata; + char *s; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + s = unit_full_printf(u, rvalue); + if (!s) + return -ENOMEM; + + if (!path_is_absolute(s[0] == '-' ? s + 1 : s)) { + log_error("[%s:%u] Path '%s' is not absolute, ignoring.", filename, line, s); + free(s); + return 0; + } + + k = strv_append(*env, s); + free(s); + if (!k) + return -ENOMEM; + + strv_free(*env); + *env = k; + + return 0; +} + +int config_parse_ip_tos( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + int *ip_tos = data, x; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((x = ip_tos_from_string(rvalue)) < 0) + if (safe_atoi(rvalue, &x) < 0) { + log_error("[%s:%u] Failed to parse IP TOS value, ignoring: %s", filename, line, rvalue); + return 0; + } + + *ip_tos = x; + return 0; +} + +int config_parse_unit_condition_path( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ConditionType cond = ltype; + Unit *u = data; + bool trigger, negate; + Condition *c; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + trigger = rvalue[0] == '|'; + if (trigger) + rvalue++; + + negate = rvalue[0] == '!'; + if (negate) + rvalue++; + + if (!path_is_absolute(rvalue)) { + log_error("[%s:%u] Path in condition not absolute, ignoring: %s", filename, line, rvalue); + return 0; + } + + c = condition_new(cond, rvalue, trigger, negate); + if (!c) + return -ENOMEM; + + LIST_PREPEND(Condition, conditions, u->conditions, c); + return 0; +} + +int config_parse_unit_condition_string( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ConditionType cond = ltype; + Unit *u = data; + bool trigger, negate; + Condition *c; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((trigger = rvalue[0] == '|')) + rvalue++; + + if ((negate = rvalue[0] == '!')) + rvalue++; + + if (!(c = condition_new(cond, rvalue, trigger, negate))) + return -ENOMEM; + + LIST_PREPEND(Condition, conditions, u->conditions, c); + return 0; +} + +int config_parse_unit_condition_null( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = data; + Condition *c; + bool trigger, negate; + int b; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if ((trigger = rvalue[0] == '|')) + rvalue++; + + if ((negate = rvalue[0] == '!')) + rvalue++; + + if ((b = parse_boolean(rvalue)) < 0) { + log_error("[%s:%u] Failed to parse boolean value in condition, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (!b) + negate = !negate; + + if (!(c = condition_new(CONDITION_NULL, NULL, trigger, negate))) + return -ENOMEM; + + LIST_PREPEND(Condition, conditions, u->conditions, c); + return 0; +} + +DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier"); +DEFINE_CONFIG_PARSE_ENUM(config_parse_start_limit_action, start_limit_action, StartLimitAction, "Failed to parse start limit action specifier"); + +int config_parse_unit_cgroup_attr( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Unit *u = data; + char **l; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + l = strv_split_quoted(rvalue); + if (!l) + return -ENOMEM; + + if (strv_length(l) != 2) { + log_error("[%s:%u] Failed to parse cgroup attribute value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + r = unit_add_cgroup_attribute(u, NULL, l[0], l[1], NULL); + strv_free(l); + + if (r < 0) { + log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_unit_cpu_shares(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { + Unit *u = data; + int r; + unsigned long ul; + char *t; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (safe_atolu(rvalue, &ul) < 0 || ul < 1) { + log_error("[%s:%u] Failed to parse CPU shares value, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (asprintf(&t, "%lu", ul) < 0) + return -ENOMEM; + + r = unit_add_cgroup_attribute(u, "cpu", "cpu.shares", t, NULL); + free(t); + + if (r < 0) { + log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_unit_memory_limit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { + Unit *u = data; + int r; + off_t sz; + char *t; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (parse_bytes(rvalue, &sz) < 0 || sz <= 0) { + log_error("[%s:%u] Failed to parse memory limit value, ignoring: %s", filename, line, rvalue); + return 0; + } + + if (asprintf(&t, "%llu", (unsigned long long) sz) < 0) + return -ENOMEM; + + r = unit_add_cgroup_attribute(u, + "memory", + streq(lvalue, "MemorySoftLimit") ? "memory.soft_limit_in_bytes" : "memory.limit_in_bytes", + t, NULL); + free(t); + + if (r < 0) { + log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +static int device_map(const char *controller, const char *name, const char *value, char **ret) { + char **l; + + assert(controller); + assert(name); + assert(value); + assert(ret); + + l = strv_split_quoted(value); + if (!l) + return -ENOMEM; + + assert(strv_length(l) >= 1); + + if (streq(l[0], "*")) { + + if (asprintf(ret, "a *:*%s%s", + isempty(l[1]) ? "" : " ", strempty(l[1])) < 0) { + strv_free(l); + return -ENOMEM; + } + + } else { + struct stat st; + + if (stat(l[0], &st) < 0) { + log_warning("Couldn't stat device %s", l[0]); + strv_free(l); + return -errno; + } + + if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) { + log_warning("%s is not a device.", l[0]); + strv_free(l); + return -ENODEV; + } + + if (asprintf(ret, "%c %u:%u%s%s", + S_ISCHR(st.st_mode) ? 'c' : 'b', + major(st.st_rdev), minor(st.st_rdev), + isempty(l[1]) ? "" : " ", strempty(l[1])) < 0) { + + strv_free(l); + return -ENOMEM; + } + } + + strv_free(l); + return 0; +} + +int config_parse_unit_device_allow(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { + Unit *u = data; + char **l; + int r; + unsigned k; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + l = strv_split_quoted(rvalue); + if (!l) + return -ENOMEM; + + k = strv_length(l); + if (k < 1 || k > 2) { + log_error("[%s:%u] Failed to parse device value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + if (!streq(l[0], "*") && !path_startswith(l[0], "/dev")) { + log_error("[%s:%u] Device node path not absolute, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + if (!isempty(l[1]) && !in_charset(l[1], "rwm")) { + log_error("[%s:%u] Device access string invalid, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + strv_free(l); + + r = unit_add_cgroup_attribute(u, "devices", + streq(lvalue, "DeviceAllow") ? "devices.allow" : "devices.deny", + rvalue, device_map); + + if (r < 0) { + log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +static int blkio_map(const char *controller, const char *name, const char *value, char **ret) { + struct stat st; + char **l; + dev_t d; + + assert(controller); + assert(name); + assert(value); + assert(ret); + + l = strv_split_quoted(value); + if (!l) + return -ENOMEM; + + assert(strv_length(l) == 2); + + if (stat(l[0], &st) < 0) { + log_warning("Couldn't stat device %s", l[0]); + strv_free(l); + return -errno; + } + + if (S_ISBLK(st.st_mode)) + d = st.st_rdev; + else if (major(st.st_dev) != 0) { + /* If this is not a device node then find the block + * device this file is stored on */ + d = st.st_dev; + + /* If this is a partition, try to get the originating + * block device */ + block_get_whole_disk(d, &d); + } else { + log_warning("%s is not a block device and file system block device cannot be determined or is not local.", l[0]); + strv_free(l); + return -ENODEV; + } + + if (asprintf(ret, "%u:%u %s", major(d), minor(d), l[1]) < 0) { + strv_free(l); + return -ENOMEM; + } + + strv_free(l); + return 0; +} + +int config_parse_unit_blkio_weight(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { + Unit *u = data; + int r; + unsigned long ul; + const char *device = NULL, *weight; + unsigned k; + char *t, **l; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + l = strv_split_quoted(rvalue); + if (!l) + return -ENOMEM; + + k = strv_length(l); + if (k < 1 || k > 2) { + log_error("[%s:%u] Failed to parse weight value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + if (k == 1) + weight = l[0]; + else { + device = l[0]; + weight = l[1]; + } + + if (device && !path_is_absolute(device)) { + log_error("[%s:%u] Failed to parse block device node value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + if (safe_atolu(weight, &ul) < 0 || ul < 10 || ul > 1000) { + log_error("[%s:%u] Failed to parse block IO weight value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + if (device) + r = asprintf(&t, "%s %lu", device, ul); + else + r = asprintf(&t, "%lu", ul); + strv_free(l); + + if (r < 0) + return -ENOMEM; + + if (device) + r = unit_add_cgroup_attribute(u, "blkio", "blkio.weight_device", t, blkio_map); + else + r = unit_add_cgroup_attribute(u, "blkio", "blkio.weight", t, NULL); + free(t); + + if (r < 0) { + log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + +int config_parse_unit_blkio_bandwidth(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { + Unit *u = data; + int r; + off_t bytes; + unsigned k; + char *t, **l; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + l = strv_split_quoted(rvalue); + if (!l) + return -ENOMEM; + + k = strv_length(l); + if (k != 2) { + log_error("[%s:%u] Failed to parse bandwidth value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + if (!path_is_absolute(l[0])) { + log_error("[%s:%u] Failed to parse block device node value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + if (parse_bytes(l[1], &bytes) < 0 || bytes <= 0) { + log_error("[%s:%u] Failed to parse block IO bandwith value, ignoring: %s", filename, line, rvalue); + strv_free(l); + return 0; + } + + r = asprintf(&t, "%s %llu", l[0], (unsigned long long) bytes); + strv_free(l); + + if (r < 0) + return -ENOMEM; + + r = unit_add_cgroup_attribute(u, "blkio", + streq(lvalue, "BlockIOReadBandwidth") ? "blkio.read_bps_device" : "blkio.write_bps_device", + t, blkio_map); + free(t); + + if (r < 0) { + log_error("[%s:%u] Failed to add cgroup attribute value, ignoring: %s", filename, line, rvalue); + return 0; + } + + return 0; +} + + +#define FOLLOW_MAX 8 + +static int open_follow(char **filename, FILE **_f, Set *names, char **_final) { + unsigned c = 0; + int fd, r; + FILE *f; + char *id = NULL; + + assert(filename); + assert(*filename); + assert(_f); + assert(names); + + /* This will update the filename pointer if the loaded file is + * reached by a symlink. The old string will be freed. */ + + for (;;) { + char *target, *name; + + if (c++ >= FOLLOW_MAX) + return -ELOOP; + + path_kill_slashes(*filename); + + /* Add the file name we are currently looking at to + * the names of this unit, but only if it is a valid + * unit name. */ + name = file_name_from_path(*filename); + + if (unit_name_is_valid(name, true)) { + + id = set_get(names, name); + if (!id) { + id = strdup(name); + if (!id) + return -ENOMEM; + + r = set_put(names, id); + if (r < 0) { + free(id); + return r; + } + } + } + + /* Try to open the file name, but don't if its a symlink */ + if ((fd = open(*filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW)) >= 0) + break; + + if (errno != ELOOP) + return -errno; + + /* Hmm, so this is a symlink. Let's read the name, and follow it manually */ + if ((r = readlink_and_make_absolute(*filename, &target)) < 0) + return r; + + free(*filename); + *filename = target; + } + + if (!(f = fdopen(fd, "re"))) { + r = -errno; + close_nointr_nofail(fd); + return r; + } + + *_f = f; + *_final = id; + return 0; +} + +static int merge_by_names(Unit **u, Set *names, const char *id) { + char *k; + int r; + + assert(u); + assert(*u); + assert(names); + + /* Let's try to add in all symlink names we found */ + while ((k = set_steal_first(names))) { + + /* First try to merge in the other name into our + * unit */ + if ((r = unit_merge_by_name(*u, k)) < 0) { + Unit *other; + + /* Hmm, we couldn't merge the other unit into + * ours? Then let's try it the other way + * round */ + + other = manager_get_unit((*u)->manager, k); + free(k); + + if (other) + if ((r = unit_merge(other, *u)) >= 0) { + *u = other; + return merge_by_names(u, names, NULL); + } + + return r; + } + + if (id == k) + unit_choose_id(*u, id); + + free(k); + } + + return 0; +} + +static int load_from_path(Unit *u, const char *path) { + int r; + Set *symlink_names; + FILE *f = NULL; + char *filename = NULL, *id = NULL; + Unit *merged; + struct stat st; + + assert(u); + assert(path); + + symlink_names = set_new(string_hash_func, string_compare_func); + if (!symlink_names) + return -ENOMEM; + + if (path_is_absolute(path)) { + + if (!(filename = strdup(path))) { + r = -ENOMEM; + goto finish; + } + + if ((r = open_follow(&filename, &f, symlink_names, &id)) < 0) { + free(filename); + filename = NULL; + + if (r != -ENOENT) + goto finish; + } + + } else { + char **p; + + STRV_FOREACH(p, u->manager->lookup_paths.unit_path) { + + /* Instead of opening the path right away, we manually + * follow all symlinks and add their name to our unit + * name set while doing so */ + if (!(filename = path_make_absolute(path, *p))) { + r = -ENOMEM; + goto finish; + } + + if (u->manager->unit_path_cache && + !set_get(u->manager->unit_path_cache, filename)) + r = -ENOENT; + else + r = open_follow(&filename, &f, symlink_names, &id); + + if (r < 0) { + char *sn; + + free(filename); + filename = NULL; + + if (r != -ENOENT) + goto finish; + + /* Empty the symlink names for the next run */ + while ((sn = set_steal_first(symlink_names))) + free(sn); + + continue; + } + + break; + } + } + + if (!filename) { + /* Hmm, no suitable file found? */ + r = 0; + goto finish; + } + + merged = u; + if ((r = merge_by_names(&merged, symlink_names, id)) < 0) + goto finish; + + if (merged != u) { + u->load_state = UNIT_MERGED; + r = 0; + goto finish; + } + + zero(st); + if (fstat(fileno(f), &st) < 0) { + r = -errno; + goto finish; + } + + if (null_or_empty(&st)) + u->load_state = UNIT_MASKED; + else { + /* Now, parse the file contents */ + r = config_parse(filename, f, UNIT_VTABLE(u)->sections, config_item_perf_lookup, (void*) load_fragment_gperf_lookup, false, u); + if (r < 0) + goto finish; + + u->load_state = UNIT_LOADED; + } + + free(u->fragment_path); + u->fragment_path = filename; + filename = NULL; + + u->fragment_mtime = timespec_load(&st.st_mtim); + + r = 0; + +finish: + set_free_free(symlink_names); + free(filename); + + if (f) + fclose(f); + + return r; +} + +int unit_load_fragment(Unit *u) { + int r; + Iterator i; + const char *t; + + assert(u); + assert(u->load_state == UNIT_STUB); + assert(u->id); + + /* First, try to find the unit under its id. We always look + * for unit files in the default directories, to make it easy + * to override things by placing things in /etc/systemd/system */ + if ((r = load_from_path(u, u->id)) < 0) + return r; + + /* Try to find an alias we can load this with */ + if (u->load_state == UNIT_STUB) + SET_FOREACH(t, u->names, i) { + + if (t == u->id) + continue; + + if ((r = load_from_path(u, t)) < 0) + return r; + + if (u->load_state != UNIT_STUB) + break; + } + + /* And now, try looking for it under the suggested (originally linked) path */ + if (u->load_state == UNIT_STUB && u->fragment_path) { + + if ((r = load_from_path(u, u->fragment_path)) < 0) + return r; + + if (u->load_state == UNIT_STUB) { + /* Hmm, this didn't work? Then let's get rid + * of the fragment path stored for us, so that + * we don't point to an invalid location. */ + free(u->fragment_path); + u->fragment_path = NULL; + } + } + + /* Look for a template */ + if (u->load_state == UNIT_STUB && u->instance) { + char *k; + + if (!(k = unit_name_template(u->id))) + return -ENOMEM; + + r = load_from_path(u, k); + free(k); + + if (r < 0) + return r; + + if (u->load_state == UNIT_STUB) + SET_FOREACH(t, u->names, i) { + + if (t == u->id) + continue; + + if (!(k = unit_name_template(t))) + return -ENOMEM; + + r = load_from_path(u, k); + free(k); + + if (r < 0) + return r; + + if (u->load_state != UNIT_STUB) + break; + } + } + + return 0; +} + +void unit_dump_config_items(FILE *f) { + static const struct { + const ConfigParserCallback callback; + const char *rvalue; + } table[] = { + { config_parse_int, "INTEGER" }, + { config_parse_unsigned, "UNSIGNED" }, + { config_parse_bytes_size, "SIZE" }, + { config_parse_bool, "BOOLEAN" }, + { config_parse_string, "STRING" }, + { config_parse_path, "PATH" }, + { config_parse_unit_path_printf, "PATH" }, + { config_parse_strv, "STRING [...]" }, + { config_parse_exec_nice, "NICE" }, + { config_parse_exec_oom_score_adjust, "OOMSCOREADJUST" }, + { config_parse_exec_io_class, "IOCLASS" }, + { config_parse_exec_io_priority, "IOPRIORITY" }, + { config_parse_exec_cpu_sched_policy, "CPUSCHEDPOLICY" }, + { config_parse_exec_cpu_sched_prio, "CPUSCHEDPRIO" }, + { config_parse_exec_cpu_affinity, "CPUAFFINITY" }, + { config_parse_mode, "MODE" }, + { config_parse_unit_env_file, "FILE" }, + { config_parse_output, "OUTPUT" }, + { config_parse_input, "INPUT" }, + { config_parse_facility, "FACILITY" }, + { config_parse_level, "LEVEL" }, + { config_parse_exec_capabilities, "CAPABILITIES" }, + { config_parse_exec_secure_bits, "SECUREBITS" }, + { config_parse_exec_bounding_set, "BOUNDINGSET" }, + { config_parse_exec_timer_slack_nsec, "TIMERSLACK" }, + { config_parse_limit, "LIMIT" }, + { config_parse_unit_cgroup, "CGROUP [...]" }, + { config_parse_unit_deps, "UNIT [...]" }, + { config_parse_unit_names, "UNIT [...]" }, + { config_parse_exec, "PATH [ARGUMENT [...]]" }, + { config_parse_service_type, "SERVICETYPE" }, + { config_parse_service_restart, "SERVICERESTART" }, +#ifdef HAVE_SYSV_COMPAT + { config_parse_sysv_priority, "SYSVPRIORITY" }, +#else + { config_parse_warn_compat, "NOTSUPPORTED" }, +#endif + { config_parse_kill_mode, "KILLMODE" }, + { config_parse_kill_signal, "SIGNAL" }, + { config_parse_socket_listen, "SOCKET [...]" }, + { config_parse_socket_bind, "SOCKETBIND" }, + { config_parse_socket_bindtodevice, "NETWORKINTERFACE" }, + { config_parse_usec, "SECONDS" }, + { config_parse_path_strv, "PATH [...]" }, + { config_parse_exec_mount_flags, "MOUNTFLAG [...]" }, + { config_parse_unit_string_printf, "STRING" }, + { config_parse_timer, "TIMER" }, + { config_parse_timer_unit, "NAME" }, + { config_parse_path_spec, "PATH" }, + { config_parse_path_unit, "UNIT" }, + { config_parse_notify_access, "ACCESS" }, + { config_parse_ip_tos, "TOS" }, + { config_parse_unit_condition_path, "CONDITION" }, + { config_parse_unit_condition_string, "CONDITION" }, + { config_parse_unit_condition_null, "CONDITION" }, + }; + + const char *prev = NULL; + const char *i; + + assert(f); + + NULSTR_FOREACH(i, load_fragment_gperf_nulstr) { + const char *rvalue = "OTHER", *lvalue; + unsigned j; + size_t prefix_len; + const char *dot; + const ConfigPerfItem *p; + + assert_se(p = load_fragment_gperf_lookup(i, strlen(i))); + + dot = strchr(i, '.'); + lvalue = dot ? dot + 1 : i; + prefix_len = dot-i; + + if (dot) + if (!prev || strncmp(prev, i, prefix_len+1) != 0) { + if (prev) + fputc('\n', f); + + fprintf(f, "[%.*s]\n", (int) prefix_len, i); + } + + for (j = 0; j < ELEMENTSOF(table); j++) + if (p->parse == table[j].callback) { + rvalue = table[j].rvalue; + break; + } + + fprintf(f, "%s=%s\n", lvalue, rvalue); + prev = i; + } +} diff --git a/src/load-fragment.h b/src/load-fragment.h new file mode 100644 index 0000000..79fc76d --- /dev/null +++ b/src/load-fragment.h @@ -0,0 +1,91 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooloadfragmenthfoo +#define fooloadfragmenthfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "unit.h" + +/* Read service data from .desktop file style configuration fragments */ + +int unit_load_fragment(Unit *u); + +void unit_dump_config_items(FILE *f); + +int config_parse_warn_compat(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_deps(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_names(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_string_printf(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_strv_printf(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_path_printf(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_socket_listen(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_socket_bind(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_nice(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_oom_score_adjust(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_service_type(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_service_restart(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_socket_bindtodevice(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_output(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_input(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_facility(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_level(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_io_class(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_io_priority(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_cpu_sched_policy(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_cpu_sched_prio(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_cpu_affinity(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_capabilities(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_secure_bits(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_bounding_set(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_timer_slack_nsec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_limit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_cgroup(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_sysv_priority(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_fsck_passno(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_kill_signal(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_exec_mount_flags(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_timer(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_timer_unit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_path_spec(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_path_unit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_socket_service(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_service_sockets(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_env_file(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_ip_tos(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_condition_path(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_condition_string(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_condition_null(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_kill_mode(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_notify_access(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_start_limit_action(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_cgroup_attr(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_cpu_shares(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_memory_limit(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_device_allow(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_blkio_weight(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_blkio_bandwidth(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + +/* gperf prototypes */ +const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length); +extern const char load_fragment_gperf_nulstr[]; + +#endif diff --git a/src/locale-setup.c b/src/locale-setup.c new file mode 100644 index 0000000..7f692e9 --- /dev/null +++ b/src/locale-setup.c @@ -0,0 +1,251 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "locale-setup.h" +#include "util.h" +#include "macro.h" +#include "virt.h" + +enum { + /* We don't list LC_ALL here on purpose. People should be + * using LANG instead. */ + + VARIABLE_LANG, + VARIABLE_LANGUAGE, + VARIABLE_LC_CTYPE, + VARIABLE_LC_NUMERIC, + VARIABLE_LC_TIME, + VARIABLE_LC_COLLATE, + VARIABLE_LC_MONETARY, + VARIABLE_LC_MESSAGES, + VARIABLE_LC_PAPER, + VARIABLE_LC_NAME, + VARIABLE_LC_ADDRESS, + VARIABLE_LC_TELEPHONE, + VARIABLE_LC_MEASUREMENT, + VARIABLE_LC_IDENTIFICATION, + _VARIABLE_MAX +}; + +static const char * const variable_names[_VARIABLE_MAX] = { + [VARIABLE_LANG] = "LANG", + [VARIABLE_LANGUAGE] = "LANGUAGE", + [VARIABLE_LC_CTYPE] = "LC_CTYPE", + [VARIABLE_LC_NUMERIC] = "LC_NUMERIC", + [VARIABLE_LC_TIME] = "LC_TIME", + [VARIABLE_LC_COLLATE] = "LC_COLLATE", + [VARIABLE_LC_MONETARY] = "LC_MONETARY", + [VARIABLE_LC_MESSAGES] = "LC_MESSAGES", + [VARIABLE_LC_PAPER] = "LC_PAPER", + [VARIABLE_LC_NAME] = "LC_NAME", + [VARIABLE_LC_ADDRESS] = "LC_ADDRESS", + [VARIABLE_LC_TELEPHONE] = "LC_TELEPHONE", + [VARIABLE_LC_MEASUREMENT] = "LC_MEASUREMENT", + [VARIABLE_LC_IDENTIFICATION] = "LC_IDENTIFICATION" +}; + +int locale_setup(void) { + char *variables[_VARIABLE_MAX]; + int r = 0, i; + + zero(variables); + + if (detect_container(NULL) <= 0) + if ((r = parse_env_file("/proc/cmdline", WHITESPACE, +#if defined(TARGET_FEDORA) || defined(TARGET_MEEGO) + "LANG", &variables[VARIABLE_LANG], +#endif + "locale.LANG", &variables[VARIABLE_LANG], + "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE], + "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE], + "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], + "locale.LC_TIME", &variables[VARIABLE_LC_TIME], + "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE], + "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY], + "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], + "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER], + "locale.LC_NAME", &variables[VARIABLE_LC_NAME], + "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], + "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], + "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], + "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION], + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /proc/cmdline: %s", strerror(-r)); + } + + /* Hmm, nothing set on the kernel cmd line? Then let's + * try /etc/locale.conf */ + if (r <= 0 && + (r = parse_env_file("/etc/locale.conf", NEWLINE, + "LANG", &variables[VARIABLE_LANG], + "LANGUAGE", &variables[VARIABLE_LANGUAGE], + "LC_CTYPE", &variables[VARIABLE_LC_CTYPE], + "LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], + "LC_TIME", &variables[VARIABLE_LC_TIME], + "LC_COLLATE", &variables[VARIABLE_LC_COLLATE], + "LC_MONETARY", &variables[VARIABLE_LC_MONETARY], + "LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], + "LC_PAPER", &variables[VARIABLE_LC_PAPER], + "LC_NAME", &variables[VARIABLE_LC_NAME], + "LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], + "LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], + "LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], + "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION], + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/locale.conf: %s", strerror(-r)); + } + +#if defined(TARGET_FEDORA) || defined(TARGET_ALTLINUX) || defined(TARGET_MEEGO) + if (r <= 0 && + (r = parse_env_file("/etc/sysconfig/i18n", NEWLINE, + "LANG", &variables[VARIABLE_LANG], + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r)); + } + +#elif defined(TARGET_SUSE) + if (r <= 0 && + (r = parse_env_file("/etc/sysconfig/language", NEWLINE, + "RC_LANG", &variables[VARIABLE_LANG], + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/language: %s", strerror(-r)); + } + +#elif defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM) + if (r <= 0 && + (r = parse_env_file("/etc/default/locale", NEWLINE, + "LANG", &variables[VARIABLE_LANG], + "LC_CTYPE", &variables[VARIABLE_LC_CTYPE], + "LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], + "LC_TIME", &variables[VARIABLE_LC_TIME], + "LC_COLLATE", &variables[VARIABLE_LC_COLLATE], + "LC_MONETARY", &variables[VARIABLE_LC_MONETARY], + "LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], + "LC_PAPER", &variables[VARIABLE_LC_PAPER], + "LC_NAME", &variables[VARIABLE_LC_NAME], + "LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], + "LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], + "LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], + "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION], + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/default/locale: %s", strerror(-r)); + } + +#elif defined(TARGET_ARCH) + if (r <= 0 && + (r = parse_env_file("/etc/rc.conf", NEWLINE, + "LOCALE", &variables[VARIABLE_LANG], + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/rc.conf: %s", strerror(-r)); + } + +#elif defined(TARGET_GENTOO) + /* Gentoo's openrc expects locale variables in /etc/env.d/ + * These files are later compiled by env-update into shell + * export commands at /etc/profile.env, with variables being + * exported by openrc's runscript (so /etc/init.d/) + */ + if (r <= 0 && + (r = parse_env_file("/etc/profile.env", NEWLINE, + "export LANG", &variables[VARIABLE_LANG], + "export LC_CTYPE", &variables[VARIABLE_LC_CTYPE], + "export LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], + "export LC_TIME", &variables[VARIABLE_LC_TIME], + "export LC_COLLATE", &variables[VARIABLE_LC_COLLATE], + "export LC_MONETARY", &variables[VARIABLE_LC_MONETARY], + "export LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], + "export LC_PAPER", &variables[VARIABLE_LC_PAPER], + "export LC_NAME", &variables[VARIABLE_LC_NAME], + "export LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], + "export LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], + "export LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], + "export LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION], + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/profile.env: %s", strerror(-r)); + } +#elif defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA ) + if (r <= 0 && + (r = parse_env_file("/etc/sysconfig/i18n", NEWLINE, + "LANG", &variables[VARIABLE_LANG], + "LC_CTYPE", &variables[VARIABLE_LC_CTYPE], + "LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC], + "LC_TIME", &variables[VARIABLE_LC_TIME], + "LC_COLLATE", &variables[VARIABLE_LC_COLLATE], + "LC_MONETARY", &variables[VARIABLE_LC_MONETARY], + "LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES], + "LC_PAPER", &variables[VARIABLE_LC_PAPER], + "LC_NAME", &variables[VARIABLE_LC_NAME], + "LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS], + "LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE], + "LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT], + "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION], + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r)); + } + +#endif + + if (!variables[VARIABLE_LANG]) { + if (!(variables[VARIABLE_LANG] = strdup("C"))) { + r = -ENOMEM; + goto finish; + } + } + + for (i = 0; i < _VARIABLE_MAX; i++) { + + if (variables[i]) { + if (setenv(variable_names[i], variables[i], 1) < 0) { + r = -errno; + goto finish; + } + } else + unsetenv(variable_names[i]); + } + + r = 0; + +finish: + for (i = 0; i < _VARIABLE_MAX; i++) + free(variables[i]); + + return r; +} diff --git a/src/locale-setup.h b/src/locale-setup.h new file mode 100644 index 0000000..09a6bc6 --- /dev/null +++ b/src/locale-setup.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foolocalesetuphfoo +#define foolocalesetuphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +int locale_setup(void); + +#endif diff --git a/src/locale/kbd-model-map b/src/locale/kbd-model-map new file mode 100644 index 0000000..a895880 --- /dev/null +++ b/src/locale/kbd-model-map @@ -0,0 +1,72 @@ +# Generated from system-config-keyboard's model list +# consolelayout xlayout xmodel xvariant xoptions +sg ch pc105 de_nodeadkeys terminate:ctrl_alt_bksp +nl nl pc105 - terminate:ctrl_alt_bksp +mk-utf mkd,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +trq tr pc105 - terminate:ctrl_alt_bksp +guj in,us pc105 guj terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +uk gb pc105 - terminate:ctrl_alt_bksp +is-latin1 is pc105 - terminate:ctrl_alt_bksp +de de pc105 - terminate:ctrl_alt_bksp +gur gur,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +la-latin1 latam pc105 - terminate:ctrl_alt_bksp +us us pc105+inet - terminate:ctrl_alt_bksp +ko kr pc105 - terminate:ctrl_alt_bksp +ro-std ro pc105 std terminate:ctrl_alt_bksp +de-latin1 de pc105 - terminate:ctrl_alt_bksp +tml-inscript in,us pc105 tam terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +slovene si pc105 - terminate:ctrl_alt_bksp +hu101 hu pc105 qwerty terminate:ctrl_alt_bksp +jp106 jp jp106 - terminate:ctrl_alt_bksp +croat hr pc105 - terminate:ctrl_alt_bksp +ben-probhat in,us pc105 ben_probhat terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +fi-latin1 fi pc105 - terminate:ctrl_alt_bksp +it2 it pc105 - terminate:ctrl_alt_bksp +hu hu pc105 - terminate:ctrl_alt_bksp +sr-latin rs pc105 latin terminate:ctrl_alt_bksp +fi fi pc105 - terminate:ctrl_alt_bksp +fr_CH ch pc105 fr terminate:ctrl_alt_bksp +dk-latin1 dk pc105 - terminate:ctrl_alt_bksp +fr fr pc105 - terminate:ctrl_alt_bksp +it it pc105 - terminate:ctrl_alt_bksp +tml-uni in,us pc105 tam_TAB terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +ua-utf ua,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +fr-latin1 fr pc105 - terminate:ctrl_alt_bksp +sg-latin1 ch pc105 de_nodeadkeys terminate:ctrl_alt_bksp +be-latin1 be pc105 - terminate:ctrl_alt_bksp +dk dk pc105 - terminate:ctrl_alt_bksp +fr-pc fr pc105 - terminate:ctrl_alt_bksp +bg_pho-utf8 bg,us pc105 ,phonetic terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +it-ibm it pc105 - terminate:ctrl_alt_bksp +cz-us-qwertz cz,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +ar-digits ara,us pc105 digits terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +br-abnt2 br abnt2 - terminate:ctrl_alt_bksp +ro ro pc105 - terminate:ctrl_alt_bksp +us-acentos us pc105 intl terminate:ctrl_alt_bksp +pt-latin1 pt pc105 - terminate:ctrl_alt_bksp +ro-std-cedilla ro pc105 std_cedilla terminate:ctrl_alt_bksp +tj tj pc105 - terminate:ctrl_alt_bksp +ar-qwerty ara,us pc105 qwerty terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +ar-azerty-digits ara,us pc105 azerty_digits terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +ben in,us pc105 ben terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +de-latin1-nodeadkeys de pc105 nodeadkeys terminate:ctrl_alt_bksp +no no pc105 - terminate:ctrl_alt_bksp +bg_bds-utf8 bg,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +dvorak us pc105 dvorak terminate:ctrl_alt_bksp +ru ru,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +cz-lat2 cz pc105 qwerty terminate:ctrl_alt_bksp +pl2 pl pc105 - terminate:ctrl_alt_bksp +es es pc105 - terminate:ctrl_alt_bksp +ro-cedilla ro pc105 cedilla terminate:ctrl_alt_bksp +ie ie pc105 - terminate:ctrl_alt_bksp +ar-azerty ara,us pc105 azerty terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +ar-qwerty-digits ara,us pc105 qwerty_digits terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +et ee pc105 - terminate:ctrl_alt_bksp +sk-qwerty sk pc105 - terminate:ctrl_alt_bksp,qwerty +dev dev,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll +fr-latin9 fr pc105 latin9 terminate:ctrl_alt_bksp +fr_CH-latin1 ch pc105 fr terminate:ctrl_alt_bksp +cf ca(fr) pc105 - terminate:ctrl_alt_bksp +sv-latin1 se pc105 - terminate:ctrl_alt_bksp +sr-cy rs pc105 - terminate:ctrl_alt_bksp +gr gr,us pc105 - terminate:ctrl_alt_bksp,grp:shifts_toggle,grp_led:scroll diff --git a/src/locale/localed.c b/src/locale/localed.c new file mode 100644 index 0000000..e9f9f86 --- /dev/null +++ b/src/locale/localed.c @@ -0,0 +1,1437 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include +#include +#include + +#include "util.h" +#include "strv.h" +#include "dbus-common.h" +#include "polkit.h" +#include "def.h" + +#define INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + BUS_PEER_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.locale1\0" + +const char locale_interface[] _introspect_("locale1") = INTERFACE; + +enum { + /* We don't list LC_ALL here on purpose. People should be + * using LANG instead. */ + + PROP_LANG, + PROP_LANGUAGE, + PROP_LC_CTYPE, + PROP_LC_NUMERIC, + PROP_LC_TIME, + PROP_LC_COLLATE, + PROP_LC_MONETARY, + PROP_LC_MESSAGES, + PROP_LC_PAPER, + PROP_LC_NAME, + PROP_LC_ADDRESS, + PROP_LC_TELEPHONE, + PROP_LC_MEASUREMENT, + PROP_LC_IDENTIFICATION, + _PROP_MAX +}; + +static const char * const names[_PROP_MAX] = { + [PROP_LANG] = "LANG", + [PROP_LANGUAGE] = "LANGUAGE", + [PROP_LC_CTYPE] = "LC_CTYPE", + [PROP_LC_NUMERIC] = "LC_NUMERIC", + [PROP_LC_TIME] = "LC_TIME", + [PROP_LC_COLLATE] = "LC_COLLATE", + [PROP_LC_MONETARY] = "LC_MONETARY", + [PROP_LC_MESSAGES] = "LC_MESSAGES", + [PROP_LC_PAPER] = "LC_PAPER", + [PROP_LC_NAME] = "LC_NAME", + [PROP_LC_ADDRESS] = "LC_ADDRESS", + [PROP_LC_TELEPHONE] = "LC_TELEPHONE", + [PROP_LC_MEASUREMENT] = "LC_MEASUREMENT", + [PROP_LC_IDENTIFICATION] = "LC_IDENTIFICATION" +}; + +static char *data[_PROP_MAX] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +typedef struct State { + char *x11_layout, *x11_model, *x11_variant, *x11_options; + char *vc_keymap, *vc_keymap_toggle; +} State; + +static State state; + +static usec_t remain_until = 0; + +static int free_and_set(char **s, const char *v) { + int r; + char *t; + + assert(s); + + r = strdup_or_null(isempty(v) ? NULL : v, &t); + if (r < 0) + return r; + + free(*s); + *s = t; + + return 0; +} + +static void free_data_locale(void) { + int p; + + for (p = 0; p < _PROP_MAX; p++) { + free(data[p]); + data[p] = NULL; + } +} + +static void free_data_x11(void) { + free(state.x11_layout); + free(state.x11_model); + free(state.x11_variant); + free(state.x11_options); + + state.x11_layout = state.x11_model = state.x11_variant = state.x11_options = NULL; +} + +static void free_data_vconsole(void) { + free(state.vc_keymap); + free(state.vc_keymap_toggle); + + state.vc_keymap = state.vc_keymap_toggle = NULL; +} + +static void simplify(void) { + int p; + + for (p = 1; p < _PROP_MAX; p++) + if (isempty(data[p]) || streq_ptr(data[PROP_LANG], data[p])) { + free(data[p]); + data[p] = NULL; + } +} + +static int read_data_locale(void) { + int r; + + free_data_locale(); + + r = parse_env_file("/etc/locale.conf", NEWLINE, + "LANG", &data[PROP_LANG], + "LANGUAGE", &data[PROP_LANGUAGE], + "LC_CTYPE", &data[PROP_LC_CTYPE], + "LC_NUMERIC", &data[PROP_LC_NUMERIC], + "LC_TIME", &data[PROP_LC_TIME], + "LC_COLLATE", &data[PROP_LC_COLLATE], + "LC_MONETARY", &data[PROP_LC_MONETARY], + "LC_MESSAGES", &data[PROP_LC_MESSAGES], + "LC_PAPER", &data[PROP_LC_PAPER], + "LC_NAME", &data[PROP_LC_NAME], + "LC_ADDRESS", &data[PROP_LC_ADDRESS], + "LC_TELEPHONE", &data[PROP_LC_TELEPHONE], + "LC_MEASUREMENT", &data[PROP_LC_MEASUREMENT], + "LC_IDENTIFICATION", &data[PROP_LC_IDENTIFICATION], + NULL); + + if (r == -ENOENT) { + int p; + + /* Fill in what we got passed from systemd. */ + + for (p = 0; p < _PROP_MAX; p++) { + char *e, *d; + + assert(names[p]); + + e = getenv(names[p]); + if (e) { + d = strdup(e); + if (!d) + return -ENOMEM; + } else + d = NULL; + + free(data[p]); + data[p] = d; + } + + r = 0; + } + + simplify(); + return r; +} + +static void free_data(void) { + free_data_locale(); + free_data_vconsole(); + free_data_x11(); +} + +static int read_data_vconsole(void) { + int r; + + free_data_vconsole(); + + r = parse_env_file("/etc/vconsole.conf", NEWLINE, + "KEYMAP", &state.vc_keymap, + "KEYMAP_TOGGLE", &state.vc_keymap_toggle, + NULL); + + if (r < 0 && r != -ENOENT) + return r; + + return 0; +} + +static int read_data_x11(void) { + FILE *f; + char line[LINE_MAX]; + bool in_section = false; + + free_data_x11(); + + f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re"); + if (!f) { + if (errno == ENOENT) { + +#ifdef TARGET_FEDORA + f = fopen("/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf", "re"); + if (!f) { + if (errno == ENOENT) + return 0; + else + return -errno; + } +#else + return 0; +#endif + + } else + return -errno; + } + + while (fgets(line, sizeof(line), f)) { + char *l; + + char_array_0(line); + l = strstrip(line); + + if (l[0] == 0 || l[0] == '#') + continue; + + if (in_section && first_word(l, "Option")) { + char **a; + + a = strv_split_quoted(l); + if (!a) { + fclose(f); + return -ENOMEM; + } + + if (strv_length(a) == 3) { + + if (streq(a[1], "XkbLayout")) { + free(state.x11_layout); + state.x11_layout = a[2]; + a[2] = NULL; + } else if (streq(a[1], "XkbModel")) { + free(state.x11_model); + state.x11_model = a[2]; + a[2] = NULL; + } else if (streq(a[1], "XkbVariant")) { + free(state.x11_variant); + state.x11_variant = a[2]; + a[2] = NULL; + } else if (streq(a[1], "XkbOptions")) { + free(state.x11_options); + state.x11_options = a[2]; + a[2] = NULL; + } + } + + strv_free(a); + + } else if (!in_section && first_word(l, "Section")) { + char **a; + + a = strv_split_quoted(l); + if (!a) { + fclose(f); + return -ENOMEM; + } + + if (strv_length(a) == 2 && streq(a[1], "InputClass")) + in_section = true; + + strv_free(a); + } else if (in_section && first_word(l, "EndSection")) + in_section = false; + } + + fclose(f); + + return 0; +} + +static int read_data(void) { + int r, q, p; + + r = read_data_locale(); + q = read_data_vconsole(); + p = read_data_x11(); + + return r < 0 ? r : q < 0 ? q : p; +} + +static int write_data_locale(void) { + int r, p; + char **l = NULL; + + r = load_env_file("/etc/locale.conf", &l); + if (r < 0 && r != -ENOENT) + return r; + + for (p = 0; p < _PROP_MAX; p++) { + char *t, **u; + + assert(names[p]); + + if (isempty(data[p])) { + l = strv_env_unset(l, names[p]); + continue; + } + + if (asprintf(&t, "%s=%s", names[p], data[p]) < 0) { + strv_free(l); + return -ENOMEM; + } + + u = strv_env_set(l, t); + free(t); + strv_free(l); + + if (!u) + return -ENOMEM; + + l = u; + } + + if (strv_isempty(l)) { + strv_free(l); + + if (unlink("/etc/locale.conf") < 0) + return errno == ENOENT ? 0 : -errno; + + return 0; + } + + r = write_env_file("/etc/locale.conf", l); + strv_free(l); + + return r; +} + +static void push_data(DBusConnection *bus) { + char **l_set = NULL, **l_unset = NULL, **t; + int c_set = 0, c_unset = 0, p; + DBusError error; + DBusMessage *m = NULL, *reply = NULL; + DBusMessageIter iter, sub; + + dbus_error_init(&error); + + assert(bus); + + l_set = new0(char*, _PROP_MAX); + l_unset = new0(char*, _PROP_MAX); + if (!l_set || !l_unset) { + log_error("Out of memory"); + goto finish; + } + + for (p = 0; p < _PROP_MAX; p++) { + assert(names[p]); + + if (isempty(data[p])) + l_unset[c_set++] = (char*) names[p]; + else { + char *s; + + if (asprintf(&s, "%s=%s", names[p], data[p]) < 0) { + log_error("Out of memory"); + goto finish; + } + + l_set[c_unset++] = s; + } + } + + assert(c_set + c_unset == _PROP_MAX); + m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnsetAndSetEnvironment"); + if (!m) { + log_error("Could not allocate message."); + goto finish; + } + + dbus_message_iter_init_append(m, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) { + log_error("Out of memory."); + goto finish; + } + + STRV_FOREACH(t, l_unset) + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, t)) { + log_error("Out of memory."); + goto finish; + } + + if (!dbus_message_iter_close_container(&iter, &sub) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) { + log_error("Out of memory."); + goto finish; + } + + STRV_FOREACH(t, l_set) + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, t)) { + log_error("Out of memory."); + goto finish; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) { + log_error("Out of memory."); + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to set locale information: %s", bus_error_message(&error)); + goto finish; + } + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + strv_free(l_set); + free(l_unset); +} + +static int write_data_vconsole(void) { + int r; + char **l = NULL; + + r = load_env_file("/etc/vconsole.conf", &l); + if (r < 0 && r != -ENOENT) + return r; + + if (isempty(state.vc_keymap)) + l = strv_env_unset(l, "KEYMAP"); + else { + char *s, **u; + + s = strappend("KEYMAP=", state.vc_keymap); + if (!s) { + strv_free(l); + return -ENOMEM; + } + + u = strv_env_set(l, s); + free(s); + strv_free(l); + + if (!u) + return -ENOMEM; + + l = u; + } + + if (isempty(state.vc_keymap_toggle)) + l = strv_env_unset(l, "KEYMAP_TOGGLE"); + else { + char *s, **u; + + s = strappend("KEYMAP_TOGGLE=", state.vc_keymap_toggle); + if (!s) { + strv_free(l); + return -ENOMEM; + } + + u = strv_env_set(l, s); + free(s); + strv_free(l); + + if (!u) + return -ENOMEM; + + l = u; + } + + if (strv_isempty(l)) { + strv_free(l); + + if (unlink("/etc/vconsole.conf") < 0) + return errno == ENOENT ? 0 : -errno; + + return 0; + } + + r = write_env_file("/etc/vconsole.conf", l); + strv_free(l); + + return r; +} + +static int write_data_x11(void) { + FILE *f; + char *temp_path; + int r; + + if (isempty(state.x11_layout) && + isempty(state.x11_model) && + isempty(state.x11_variant) && + isempty(state.x11_options)) { + +#ifdef TARGET_FEDORA + unlink("/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf"); + + /* Symlink this to /dev/null, so that s-s-k (if it is + * still running) doesn't recreate this. */ + symlink("/dev/null", "/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf"); +#endif + + if (unlink("/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) + return errno == ENOENT ? 0 : -errno; + + return 0; + } + + mkdir_parents("/etc/X11/xorg.conf.d", 0755); + + r = fopen_temporary("/etc/X11/xorg.conf.d/00-keyboard.conf", &f, &temp_path); + if (r < 0) + return r; + + fchmod(fileno(f), 0644); + + fputs("# Read and parsed by systemd-localed. It's probably wise not to edit this file\n" + "# manually too freely.\n" + "Section \"InputClass\"\n" + " Identifier \"system-keyboard\"\n" + " MatchIsKeyboard \"on\"\n", f); + + if (!isempty(state.x11_layout)) + fprintf(f, " Option \"XkbLayout\" \"%s\"\n", state.x11_layout); + + if (!isempty(state.x11_model)) + fprintf(f, " Option \"XkbModel\" \"%s\"\n", state.x11_model); + + if (!isempty(state.x11_variant)) + fprintf(f, " Option \"XkbVariant\" \"%s\"\n", state.x11_variant); + + if (!isempty(state.x11_options)) + fprintf(f, " Option \"XkbOptions\" \"%s\"\n", state.x11_options); + + fputs("EndSection\n", f); + fflush(f); + + if (ferror(f) || rename(temp_path, "/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) { + r = -errno; + unlink("/etc/X11/xorg.conf.d/00-keyboard.conf"); + unlink(temp_path); + } else { + +#ifdef TARGET_FEDORA + unlink("/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf"); + + /* Symlink this to /dev/null, so that s-s-k (if it is + * still running) doesn't recreate this. */ + symlink("/dev/null", "/etc/X11/xorg.conf.d/00-system-setup-keyboard.conf"); +#endif + + r = 0; + } + + fclose(f); + free(temp_path); + + return r; +} + +static int load_vconsole_keymap(DBusConnection *bus, DBusError *error) { + DBusMessage *m = NULL, *reply = NULL; + const char *name = "systemd-vconsole-setup.service", *mode = "replace"; + int r; + DBusError _error; + + assert(bus); + + if (!error) { + dbus_error_init(&_error); + error = &_error; + } + + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "RestartUnit"); + if (!m) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(error)); + r = -EIO; + goto finish; + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + if (error == &_error) + dbus_error_free(error); + + return r; +} + +static char *strnulldash(const char *s) { + return s == NULL || *s == 0 || (s[0] == '-' && s[1] == 0) ? NULL : (char*) s; +} + +static int read_next_mapping(FILE *f, unsigned *n, char ***a) { + assert(f); + assert(n); + assert(a); + + for (;;) { + char line[LINE_MAX]; + char *l, **b; + + errno = 0; + if (!fgets(line, sizeof(line), f)) { + + if (ferror(f)) + return errno ? -errno : -EIO; + + return 0; + } + + (*n) ++; + + l = strstrip(line); + if (l[0] == 0 || l[0] == '#') + continue; + + b = strv_split_quoted(l); + if (!b) + return -ENOMEM; + + if (strv_length(b) < 5) { + log_error("Invalid line "SYSTEMD_KBD_MODEL_MAP":%u, ignoring.", *n); + strv_free(b); + continue; + + } + + *a = b; + return 1; + } +} + +static int convert_vconsole_to_x11(DBusConnection *connection) { + bool modified = false; + + assert(connection); + + if (isempty(state.vc_keymap)) { + + modified = + !isempty(state.x11_layout) || + !isempty(state.x11_model) || + !isempty(state.x11_variant) || + !isempty(state.x11_options); + + free_data_x11(); + } else { + FILE *f; + unsigned n = 0; + + f = fopen(SYSTEMD_KBD_MODEL_MAP, "re"); + if (!f) + return -errno; + + for (;;) { + char **a; + int r; + + r = read_next_mapping(f, &n, &a); + if (r < 0) { + fclose(f); + return r; + } + + if (r == 0) + break; + + if (!streq(state.vc_keymap, a[0])) { + strv_free(a); + continue; + } + + if (!streq_ptr(state.x11_layout, strnulldash(a[1])) || + !streq_ptr(state.x11_model, strnulldash(a[2])) || + !streq_ptr(state.x11_variant, strnulldash(a[3])) || + !streq_ptr(state.x11_options, strnulldash(a[4]))) { + + if (free_and_set(&state.x11_layout, strnulldash(a[1])) < 0 || + free_and_set(&state.x11_model, strnulldash(a[2])) < 0 || + free_and_set(&state.x11_variant, strnulldash(a[3])) < 0 || + free_and_set(&state.x11_options, strnulldash(a[4])) < 0) { + strv_free(a); + fclose(f); + return -ENOMEM; + } + + modified = true; + } + + strv_free(a); + break; + } + + fclose(f); + } + + if (modified) { + dbus_bool_t b; + DBusMessage *changed; + int r; + + r = write_data_x11(); + if (r < 0) + log_error("Failed to set X11 keyboard layout: %s", strerror(-r)); + + changed = bus_properties_changed_new( + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + "X11Layout\0" + "X11Model\0" + "X11Variant\0" + "X11Options\0"); + + if (!changed) + return -ENOMEM; + + b = dbus_connection_send(connection, changed, NULL); + dbus_message_unref(changed); + + if (!b) + return -ENOMEM; + } + + return 0; +} + +static int convert_x11_to_vconsole(DBusConnection *connection) { + bool modified = false; + + assert(connection); + + if (isempty(state.x11_layout)) { + + modified = + !isempty(state.vc_keymap) || + !isempty(state.vc_keymap_toggle); + + free_data_x11(); + } else { + FILE *f; + unsigned n = 0; + unsigned best_matching = 0; + char *new_keymap = NULL; + + f = fopen(SYSTEMD_KBD_MODEL_MAP, "re"); + if (!f) + return -errno; + + for (;;) { + char **a; + unsigned matching = 0; + int r; + + r = read_next_mapping(f, &n, &a); + if (r < 0) { + fclose(f); + return r; + } + + if (r == 0) + break; + + /* Determine how well matching this entry is */ + if (streq_ptr(state.x11_layout, a[1])) + /* If we got an exact match, this is best */ + matching = 10; + else { + size_t x; + + x = strcspn(state.x11_layout, ","); + + /* We have multiple X layouts, look + * for an entry that matches our key + * with the everything but the first + * layout stripped off. */ + if (x > 0 && + strlen(a[1]) == x && + strncmp(state.x11_layout, a[1], x) == 0) + matching = 5; + else { + size_t w; + + /* If that didn't work, strip + * off the other layouts from + * the entry, too */ + + w = strcspn(a[1], ","); + + if (x > 0 && x == w && + memcmp(state.x11_layout, a[1], x) == 0) + matching = 1; + } + } + + if (matching > 0 && + streq_ptr(state.x11_model, a[2])) { + matching++; + + if (streq_ptr(state.x11_variant, a[3])) { + matching++; + + if (streq_ptr(state.x11_options, a[4])) + matching++; + } + } + + /* The best matching entry so far, then let's + * save that */ + if (matching > best_matching) { + best_matching = matching; + + free(new_keymap); + new_keymap = strdup(a[0]); + + if (!new_keymap) { + strv_free(a); + fclose(f); + return -ENOMEM; + } + } + + strv_free(a); + } + + fclose(f); + + if (!streq_ptr(state.vc_keymap, new_keymap)) { + free(state.vc_keymap); + state.vc_keymap = new_keymap; + + free(state.vc_keymap_toggle); + state.vc_keymap_toggle = NULL; + + modified = true; + } else + free(new_keymap); + } + + if (modified) { + dbus_bool_t b; + DBusMessage *changed; + int r; + + r = write_data_vconsole(); + if (r < 0) + log_error("Failed to set virtual console keymap: %s", strerror(-r)); + + changed = bus_properties_changed_new( + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + "VConsoleKeymap\0" + "VConsoleKeymapToggle\0"); + + if (!changed) + return -ENOMEM; + + b = dbus_connection_send(connection, changed, NULL); + dbus_message_unref(changed); + + if (!b) + return -ENOMEM; + + return load_vconsole_keymap(connection, NULL); + } + + return 0; +} + +static int append_locale(DBusMessageIter *i, const char *property, void *userdata) { + int r, c = 0, p; + char **l; + + l = new0(char*, _PROP_MAX+1); + if (!l) + return -ENOMEM; + + for (p = 0; p < _PROP_MAX; p++) { + char *t; + + if (isempty(data[p])) + continue; + + if (asprintf(&t, "%s=%s", names[p], data[p]) < 0) { + strv_free(l); + return -ENOMEM; + } + + l[c++] = t; + } + + r = bus_property_append_strv(i, property, (void*) l); + strv_free(l); + + return r; +} + +static const BusProperty bus_locale_properties[] = { + { "Locale", append_locale, "as", 0 }, + { "X11Layout", bus_property_append_string, "s", offsetof(State, x11_layout), true }, + { "X11Model", bus_property_append_string, "s", offsetof(State, x11_model), true }, + { "X11Variant", bus_property_append_string, "s", offsetof(State, x11_variant), true }, + { "X11Options", bus_property_append_string, "s", offsetof(State, x11_options), true }, + { "VConsoleKeymap", bus_property_append_string, "s", offsetof(State, vc_keymap), true }, + { "VConsoleKeymapToggle", bus_property_append_string, "s", offsetof(State, vc_keymap_toggle), true }, + { NULL, } +}; + +static const BusBoundProperties bps[] = { + { "org.freedesktop.locale1", bus_locale_properties, &state }, + { NULL, } +}; + +static DBusHandlerResult locale_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + DBusMessage *reply = NULL, *changed = NULL; + DBusError error; + int r; + + assert(connection); + assert(message); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.locale1", "SetLocale")) { + char **l = NULL, **i; + dbus_bool_t interactive; + DBusMessageIter iter; + bool modified = false; + bool passed[_PROP_MAX]; + int p; + + if (!dbus_message_iter_init(message, &iter)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + r = bus_parse_strv_iter(&iter, &l); + if (r < 0) { + if (r == -ENOMEM) + goto oom; + + return bus_send_error_reply(connection, message, NULL, r); + } + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN) { + strv_free(l); + return bus_send_error_reply(connection, message, NULL, -EINVAL); + } + + dbus_message_iter_get_basic(&iter, &interactive); + + zero(passed); + + /* Check whether a variable changed and if so valid */ + STRV_FOREACH(i, l) { + bool valid = false; + + for (p = 0; p < _PROP_MAX; p++) { + size_t k; + + k = strlen(names[p]); + if (startswith(*i, names[p]) && (*i)[k] == '=') { + valid = true; + passed[p] = true; + + if (!streq_ptr(*i + k + 1, data[p])) + modified = true; + + break; + } + } + + if (!valid) { + strv_free(l); + return bus_send_error_reply(connection, message, NULL, -EINVAL); + } + } + + /* Check whether a variable is unset */ + if (!modified) { + for (p = 0; p < _PROP_MAX; p++) + if (!isempty(data[p]) && !passed[p]) { + modified = true; + break; + } + } + + if (modified) { + + r = verify_polkit(connection, message, "org.freedesktop.locale1.set-locale", interactive, NULL, &error); + if (r < 0) { + strv_free(l); + return bus_send_error_reply(connection, message, &error, r); + } + + STRV_FOREACH(i, l) { + for (p = 0; p < _PROP_MAX; p++) { + size_t k; + + k = strlen(names[p]); + if (startswith(*i, names[p]) && (*i)[k] == '=') { + char *t; + + t = strdup(*i + k + 1); + if (!t) { + strv_free(l); + goto oom; + } + + free(data[p]); + data[p] = t; + + break; + } + } + } + + strv_free(l); + + for (p = 0; p < _PROP_MAX; p++) { + if (passed[p]) + continue; + + free(data[p]); + data[p] = NULL; + } + + simplify(); + + r = write_data_locale(); + if (r < 0) { + log_error("Failed to set locale: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + push_data(connection); + + log_info("Changed locale information."); + + changed = bus_properties_changed_new( + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + "Locale\0"); + if (!changed) + goto oom; + } + } else if (dbus_message_is_method_call(message, "org.freedesktop.locale1", "SetVConsoleKeyboard")) { + + const char *keymap, *keymap_toggle; + dbus_bool_t convert, interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &keymap, + DBUS_TYPE_STRING, &keymap_toggle, + DBUS_TYPE_BOOLEAN, &convert, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(keymap)) + keymap = NULL; + + if (isempty(keymap_toggle)) + keymap_toggle = NULL; + + if (!streq_ptr(keymap, state.vc_keymap) || + !streq_ptr(keymap_toggle, state.vc_keymap_toggle)) { + + r = verify_polkit(connection, message, "org.freedesktop.locale1.set-keyboard", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (free_and_set(&state.vc_keymap, keymap) < 0 || + free_and_set(&state.vc_keymap_toggle, keymap_toggle) < 0) + goto oom; + + r = write_data_vconsole(); + if (r < 0) { + log_error("Failed to set virtual console keymap: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + log_info("Changed virtual console keymap to '%s'", strempty(state.vc_keymap)); + + r = load_vconsole_keymap(connection, NULL); + if (r < 0) + log_error("Failed to request keymap reload: %s", strerror(-r)); + + changed = bus_properties_changed_new( + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + "VConsoleKeymap\0" + "VConsoleKeymapToggle\0"); + if (!changed) + goto oom; + + if (convert) { + r = convert_vconsole_to_x11(connection); + + if (r < 0) + log_error("Failed to convert keymap data: %s", strerror(-r)); + } + } + + } else if (dbus_message_is_method_call(message, "org.freedesktop.locale1", "SetX11Keyboard")) { + + const char *layout, *model, *variant, *options; + dbus_bool_t convert, interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &layout, + DBUS_TYPE_STRING, &model, + DBUS_TYPE_STRING, &variant, + DBUS_TYPE_STRING, &options, + DBUS_TYPE_BOOLEAN, &convert, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(layout)) + layout = NULL; + + if (isempty(model)) + model = NULL; + + if (isempty(variant)) + variant = NULL; + + if (isempty(options)) + options = NULL; + + if (!streq_ptr(layout, state.x11_layout) || + !streq_ptr(model, state.x11_model) || + !streq_ptr(variant, state.x11_variant) || + !streq_ptr(options, state.x11_options)) { + + r = verify_polkit(connection, message, "org.freedesktop.locale1.set-keyboard", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (free_and_set(&state.x11_layout, layout) < 0 || + free_and_set(&state.x11_model, model) < 0 || + free_and_set(&state.x11_variant, variant) < 0 || + free_and_set(&state.x11_options, options) < 0) + goto oom; + + r = write_data_x11(); + if (r < 0) { + log_error("Failed to set X11 keyboard layout: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + log_info("Changed X11 keyboard layout to '%s'", strempty(state.x11_layout)); + + changed = bus_properties_changed_new( + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + "X11Layout\0" + "X11Model\0" + "X11Variant\0" + "X11Options\0"); + if (!changed) + goto oom; + + if (convert) { + r = convert_x11_to_vconsole(connection); + + if (r < 0) + log_error("Failed to convert keymap data: %s", strerror(-r)); + } + } + } else + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + reply = NULL; + + if (changed) { + + if (!dbus_connection_send(connection, changed, NULL)) + goto oom; + + dbus_message_unref(changed); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + if (changed) + dbus_message_unref(changed); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static int connect_bus(DBusConnection **_bus) { + static const DBusObjectPathVTable locale_vtable = { + .message_function = locale_message_handler + }; + DBusError error; + DBusConnection *bus = NULL; + int r; + + assert(_bus); + + dbus_error_init(&error); + + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!bus) { + log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error)); + r = -ECONNREFUSED; + goto fail; + } + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + if (!dbus_connection_register_object_path(bus, "/org/freedesktop/locale1", &locale_vtable, NULL) || + !dbus_connection_add_filter(bus, bus_exit_idle_filter, &remain_until, NULL)) { + log_error("Not enough memory"); + r = -ENOMEM; + goto fail; + } + + r = dbus_bus_request_name(bus, "org.freedesktop.locale1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to register name on bus: %s", bus_error_message(&error)); + r = -EEXIST; + goto fail; + } + + if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + log_error("Failed to acquire name."); + r = -EEXIST; + goto fail; + } + + if (_bus) + *_bus = bus; + + return 0; + +fail: + dbus_connection_close(bus); + dbus_connection_unref(bus); + + dbus_error_free(&error); + + return r; +} + +int main(int argc, char *argv[]) { + int r; + DBusConnection *bus = NULL; + bool exiting = false; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc == 2 && streq(argv[1], "--introspect")) { + fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + "\n", stdout); + fputs(locale_interface, stdout); + fputs("\n", stdout); + return 0; + } + + if (argc != 1) { + log_error("This program takes no arguments."); + r = -EINVAL; + goto finish; + } + + r = read_data(); + if (r < 0) { + log_error("Failed to read locale data: %s", strerror(-r)); + goto finish; + } + + r = connect_bus(&bus); + if (r < 0) + goto finish; + + remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC; + for (;;) { + + if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC))) + break; + + if (!exiting && remain_until < now(CLOCK_MONOTONIC)) { + exiting = true; + bus_async_unregister_and_exit(bus, "org.freedesktop.locale1"); + } + } + + r = 0; + +finish: + free_data(); + + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/locale/org.freedesktop.locale1.conf b/src/locale/org.freedesktop.locale1.conf new file mode 100644 index 0000000..6827331 --- /dev/null +++ b/src/locale/org.freedesktop.locale1.conf @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/locale/org.freedesktop.locale1.policy.in b/src/locale/org.freedesktop.locale1.policy.in new file mode 100644 index 0000000..1ac50bf --- /dev/null +++ b/src/locale/org.freedesktop.locale1.policy.in @@ -0,0 +1,39 @@ + + + + + + + + The systemd Project + http://www.freedesktop.org/wiki/Software/systemd + + + <_description>Set system locale + <_message>Authentication is required to set the system locale. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Set system keyboard settings + <_message>Authentication is required to set the system keyboard settings. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + diff --git a/src/locale/org.freedesktop.locale1.service b/src/locale/org.freedesktop.locale1.service new file mode 100644 index 0000000..29bd582 --- /dev/null +++ b/src/locale/org.freedesktop.locale1.service @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# systemd 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. + +[D-BUS Service] +Name=org.freedesktop.locale1 +Exec=/bin/false +User=root +SystemdService=dbus-org.freedesktop.locale1.service diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000..c37ab22 --- /dev/null +++ b/src/log.c @@ -0,0 +1,727 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "macro.h" +#include "socket-util.h" + +#define SNDBUF_SIZE (8*1024*1024) + +static LogTarget log_target = LOG_TARGET_CONSOLE; +static int log_max_level = LOG_INFO; + +static int console_fd = STDERR_FILENO; +static int syslog_fd = -1; +static int kmsg_fd = -1; +static int journal_fd = -1; + +static bool syslog_is_stream = false; + +static bool show_color = false; +static bool show_location = false; + +/* Akin to glibc's __abort_msg; which is private and we hence cannot + * use here. */ +static char *log_abort_msg = NULL; + +void log_close_console(void) { + + if (console_fd < 0) + return; + + if (getpid() == 1) { + if (console_fd >= 3) + close_nointr_nofail(console_fd); + + console_fd = -1; + } +} + +static int log_open_console(void) { + + if (console_fd >= 0) + return 0; + + if (getpid() == 1) { + + console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (console_fd < 0) { + log_error("Failed to open /dev/console for logging: %s", strerror(-console_fd)); + return console_fd; + } + + log_debug("Successfully opened /dev/console for logging."); + } else + console_fd = STDERR_FILENO; + + return 0; +} + +void log_close_kmsg(void) { + + if (kmsg_fd < 0) + return; + + close_nointr_nofail(kmsg_fd); + kmsg_fd = -1; +} + +static int log_open_kmsg(void) { + + if (kmsg_fd >= 0) + return 0; + + kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (kmsg_fd < 0) { + log_error("Failed to open /dev/kmsg for logging: %s", strerror(errno)); + return -errno; + } + + log_debug("Successfully opened /dev/kmsg for logging."); + + return 0; +} + +void log_close_syslog(void) { + + if (syslog_fd < 0) + return; + + close_nointr_nofail(syslog_fd); + syslog_fd = -1; +} + +static int create_log_socket(int type) { + int fd; + + /* All output to the syslog/journal fds we do asynchronously, + * and if the buffers are full we just drop the messages */ + + fd = socket(AF_UNIX, type|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + if (fd < 0) + return -errno; + + fd_inc_sndbuf(fd, SNDBUF_SIZE); + + return fd; +} + +static int log_open_syslog(void) { + union sockaddr_union sa; + int r; + + if (syslog_fd >= 0) + return 0; + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/dev/log", sizeof(sa.un.sun_path)); + + syslog_fd = create_log_socket(SOCK_DGRAM); + if (syslog_fd < 0) { + r = syslog_fd; + goto fail; + } + + if (connect(syslog_fd, &sa.sa, sizeof(sa)) < 0) { + close_nointr_nofail(syslog_fd); + + /* Some legacy syslog systems still use stream + * sockets. They really shouldn't. But what can we + * do... */ + syslog_fd = create_log_socket(SOCK_STREAM); + if (syslog_fd < 0) { + r = syslog_fd; + goto fail; + } + + if (connect(syslog_fd, &sa.sa, sizeof(sa)) < 0) { + r = -errno; + goto fail; + } + + syslog_is_stream = true; + } else + syslog_is_stream = false; + + log_debug("Successfully opened syslog for logging."); + + return 0; + +fail: + log_close_syslog(); + log_debug("Failed to open syslog for logging: %s", strerror(-r)); + return r; +} + +void log_close_journal(void) { + + if (journal_fd < 0) + return; + + close_nointr_nofail(journal_fd); + journal_fd = -1; +} + +static int log_open_journal(void) { + union sockaddr_union sa; + int r; + + if (journal_fd >= 0) + return 0; + + journal_fd = create_log_socket(SOCK_DGRAM); + if (journal_fd < 0) { + r = journal_fd; + goto fail; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path)); + + if (connect(journal_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) { + r = -errno; + goto fail; + } + + log_debug("Successfully opened journal for logging."); + + return 0; + +fail: + log_close_journal(); + log_debug("Failed to open journal for logging: %s", strerror(-r)); + return r; +} + +int log_open(void) { + int r; + + /* If we don't use the console we close it here, to not get + * killed by SAK. If we don't use syslog we close it here so + * that we are not confused by somebody deleting the socket in + * the fs. If we don't use /dev/kmsg we still keep it open, + * because there is no reason to close it. */ + + if (log_target == LOG_TARGET_NULL) { + log_close_journal(); + log_close_syslog(); + log_close_console(); + return 0; + } + + if (log_target != LOG_TARGET_AUTO || + getpid() == 1 || + isatty(STDERR_FILENO) <= 0) { + + if (log_target == LOG_TARGET_AUTO || + log_target == LOG_TARGET_JOURNAL_OR_KMSG || + log_target == LOG_TARGET_JOURNAL) { + r = log_open_journal(); + if (r >= 0) { + log_close_syslog(); + log_close_console(); + return r; + } + } + + if (log_target == LOG_TARGET_SYSLOG_OR_KMSG || + log_target == LOG_TARGET_SYSLOG) { + r = log_open_syslog(); + if (r >= 0) { + log_close_journal(); + log_close_console(); + return r; + } + } + + if (log_target == LOG_TARGET_AUTO || + log_target == LOG_TARGET_JOURNAL_OR_KMSG || + log_target == LOG_TARGET_SYSLOG_OR_KMSG || + log_target == LOG_TARGET_KMSG) { + r = log_open_kmsg(); + if (r >= 0) { + log_close_journal(); + log_close_syslog(); + log_close_console(); + return r; + } + } + } + + log_close_journal(); + log_close_syslog(); + + /* Get the real /dev/console if we are PID=1, hence reopen */ + log_close_console(); + return log_open_console(); +} + +void log_set_target(LogTarget target) { + assert(target >= 0); + assert(target < _LOG_TARGET_MAX); + + log_target = target; +} + +void log_close(void) { + log_close_journal(); + log_close_syslog(); + log_close_kmsg(); + log_close_console(); +} + +void log_forget_fds(void) { + console_fd = kmsg_fd = syslog_fd = journal_fd = -1; +} + +void log_set_max_level(int level) { + assert((level & LOG_PRIMASK) == level); + + log_max_level = level; +} + +static int write_to_console( + int level, + const char*file, + int line, + const char *func, + const char *buffer) { + + char location[64]; + struct iovec iovec[5]; + unsigned n = 0; + bool highlight; + + if (console_fd < 0) + return 0; + + highlight = LOG_PRI(level) <= LOG_ERR && show_color; + + zero(iovec); + + if (show_location) { + snprintf(location, sizeof(location), "(%s:%u) ", file, line); + char_array_0(location); + IOVEC_SET_STRING(iovec[n++], location); + } + + if (highlight) + IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_RED_ON); + IOVEC_SET_STRING(iovec[n++], buffer); + if (highlight) + IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_OFF); + IOVEC_SET_STRING(iovec[n++], "\n"); + + if (writev(console_fd, iovec, n) < 0) + return -errno; + + return 1; +} + +static int write_to_syslog( + int level, + const char*file, + int line, + const char *func, + const char *buffer) { + + char header_priority[16], header_time[64], header_pid[16]; + struct iovec iovec[5]; + struct msghdr msghdr; + time_t t; + struct tm *tm; + + if (syslog_fd < 0) + return 0; + + snprintf(header_priority, sizeof(header_priority), "<%i>", level); + char_array_0(header_priority); + + t = (time_t) (now(CLOCK_REALTIME) / USEC_PER_SEC); + if (!(tm = localtime(&t))) + return -EINVAL; + + if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0) + return -EINVAL; + + snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid()); + char_array_0(header_pid); + + zero(iovec); + IOVEC_SET_STRING(iovec[0], header_priority); + IOVEC_SET_STRING(iovec[1], header_time); + IOVEC_SET_STRING(iovec[2], program_invocation_short_name); + IOVEC_SET_STRING(iovec[3], header_pid); + IOVEC_SET_STRING(iovec[4], buffer); + + /* When using syslog via SOCK_STREAM separate the messages by NUL chars */ + if (syslog_is_stream) + iovec[4].iov_len++; + + zero(msghdr); + msghdr.msg_iov = iovec; + msghdr.msg_iovlen = ELEMENTSOF(iovec); + + for (;;) { + ssize_t n; + + n = sendmsg(syslog_fd, &msghdr, MSG_NOSIGNAL); + if (n < 0) + return -errno; + + if (!syslog_is_stream || + (size_t) n >= IOVEC_TOTAL_SIZE(iovec, ELEMENTSOF(iovec))) + break; + + IOVEC_INCREMENT(iovec, ELEMENTSOF(iovec), n); + } + + return 1; +} + +static int write_to_kmsg( + int level, + const char*file, + int line, + const char *func, + const char *buffer) { + + char header_priority[16], header_pid[16]; + struct iovec iovec[5]; + + if (kmsg_fd < 0) + return 0; + + snprintf(header_priority, sizeof(header_priority), "<%i>", level); + char_array_0(header_priority); + + snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) getpid()); + char_array_0(header_pid); + + zero(iovec); + IOVEC_SET_STRING(iovec[0], header_priority); + IOVEC_SET_STRING(iovec[1], program_invocation_short_name); + IOVEC_SET_STRING(iovec[2], header_pid); + IOVEC_SET_STRING(iovec[3], buffer); + IOVEC_SET_STRING(iovec[4], "\n"); + + if (writev(kmsg_fd, iovec, ELEMENTSOF(iovec)) < 0) + return -errno; + + return 1; +} + +static int write_to_journal( + int level, + const char*file, + int line, + const char *func, + const char *buffer) { + + char header[LINE_MAX]; + struct iovec iovec[3]; + struct msghdr mh; + + if (journal_fd < 0) + return 0; + + snprintf(header, sizeof(header), + "PRIORITY=%i\n" + "CODE_FILE=%s\n" + "CODE_LINE=%i\n" + "CODE_FUNCTION=%s\n" + "MESSAGE=", + LOG_PRI(level), + file, + line, + func); + + char_array_0(header); + + zero(iovec); + IOVEC_SET_STRING(iovec[0], header); + IOVEC_SET_STRING(iovec[1], buffer); + IOVEC_SET_STRING(iovec[2], "\n"); + + zero(mh); + mh.msg_iov = iovec; + mh.msg_iovlen = ELEMENTSOF(iovec); + + if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0) + return -errno; + + return 1; +} + +static int log_dispatch( + int level, + const char*file, + int line, + const char *func, + char *buffer) { + + int r = 0; + + if (log_target == LOG_TARGET_NULL) + return 0; + + /* Patch in LOG_DAEMON facility if necessary */ + if ((level & LOG_FACMASK) == 0) + level = LOG_DAEMON | LOG_PRI(level); + + do { + char *e; + int k = 0; + + buffer += strspn(buffer, NEWLINE); + + if (buffer[0] == 0) + break; + + if ((e = strpbrk(buffer, NEWLINE))) + *(e++) = 0; + + if (log_target == LOG_TARGET_AUTO || + log_target == LOG_TARGET_JOURNAL_OR_KMSG || + log_target == LOG_TARGET_JOURNAL) { + + k = write_to_journal(level, file, line, func, buffer); + if (k < 0) { + if (k != -EAGAIN) + log_close_journal(); + log_open_kmsg(); + } else if (k > 0) + r++; + } + + if (log_target == LOG_TARGET_SYSLOG_OR_KMSG || + log_target == LOG_TARGET_SYSLOG) { + + k = write_to_syslog(level, file, line, func, buffer); + if (k < 0) { + if (k != -EAGAIN) + log_close_syslog(); + log_open_kmsg(); + } else if (k > 0) + r++; + } + + if (k <= 0 && + (log_target == LOG_TARGET_AUTO || + log_target == LOG_TARGET_SYSLOG_OR_KMSG || + log_target == LOG_TARGET_KMSG)) { + + k = write_to_kmsg(level, file, line, func, buffer); + if (k < 0) { + log_close_kmsg(); + log_open_console(); + } else if (k > 0) + r++; + } + + if (k <= 0) { + k = write_to_console(level, file, line, func, buffer); + if (k < 0) + return k; + } + + buffer = e; + } while (buffer); + + return r; +} + +int log_dump_internal( + int level, + const char*file, + int line, + const char *func, + char *buffer) { + + int saved_errno, r; + + /* This modifies the buffer... */ + + if (_likely_(LOG_PRI(level) > log_max_level)) + return 0; + + saved_errno = errno; + r = log_dispatch(level, file, line, func, buffer); + errno = saved_errno; + + return r; +} + +int log_meta( + int level, + const char*file, + int line, + const char *func, + const char *format, ...) { + + char buffer[LINE_MAX]; + int saved_errno, r; + va_list ap; + + if (_likely_(LOG_PRI(level) > log_max_level)) + return 0; + + saved_errno = errno; + + va_start(ap, format); + vsnprintf(buffer, sizeof(buffer), format, ap); + va_end(ap); + + char_array_0(buffer); + + r = log_dispatch(level, file, line, func, buffer); + errno = saved_errno; + + return r; +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +_noreturn_ static void log_assert(const char *text, const char *file, int line, const char *func, const char *format) { + static char buffer[LINE_MAX]; + + snprintf(buffer, sizeof(buffer), format, text, file, line, func); + + char_array_0(buffer); + log_abort_msg = buffer; + + log_dispatch(LOG_CRIT, file, line, func, buffer); + abort(); +} +#pragma GCC diagnostic pop + +void log_assert_failed(const char *text, const char *file, int line, const char *func) { + log_assert(text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting."); +} + +void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) { + log_assert(text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting."); +} + +int log_set_target_from_string(const char *e) { + LogTarget t; + + t = log_target_from_string(e); + if (t < 0) + return -EINVAL; + + log_set_target(t); + return 0; +} + +int log_set_max_level_from_string(const char *e) { + int t; + + t = log_level_from_string(e); + if (t < 0) + return t; + + log_set_max_level(t); + return 0; +} + +void log_parse_environment(void) { + const char *e; + + if ((e = getenv("SYSTEMD_LOG_TARGET"))) + if (log_set_target_from_string(e) < 0) + log_warning("Failed to parse log target %s. Ignoring.", e); + + if ((e = getenv("SYSTEMD_LOG_LEVEL"))) + if (log_set_max_level_from_string(e) < 0) + log_warning("Failed to parse log level %s. Ignoring.", e); + + if ((e = getenv("SYSTEMD_LOG_COLOR"))) + if (log_show_color_from_string(e) < 0) + log_warning("Failed to parse bool %s. Ignoring.", e); + + if ((e = getenv("SYSTEMD_LOG_LOCATION"))) + if (log_show_location_from_string(e) < 0) + log_warning("Failed to parse bool %s. Ignoring.", e); +} + +LogTarget log_get_target(void) { + return log_target; +} + +int log_get_max_level(void) { + return log_max_level; +} + +void log_show_color(bool b) { + show_color = b; +} + +void log_show_location(bool b) { + show_location = b; +} + +int log_show_color_from_string(const char *e) { + int t; + + t = parse_boolean(e); + if (t < 0) + return t; + + log_show_color(t); + return 0; +} + +int log_show_location_from_string(const char *e) { + int t; + + t = parse_boolean(e); + if (t < 0) + return t; + + log_show_location(t); + return 0; +} + +static const char *const log_target_table[] = { + [LOG_TARGET_CONSOLE] = "console", + [LOG_TARGET_KMSG] = "kmsg", + [LOG_TARGET_JOURNAL] = "journal", + [LOG_TARGET_JOURNAL_OR_KMSG] = "journal-or-kmsg", + [LOG_TARGET_SYSLOG] = "syslog", + [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg", + [LOG_TARGET_AUTO] = "auto", + [LOG_TARGET_NULL] = "null" +}; + +DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget); diff --git a/src/log.h b/src/log.h new file mode 100644 index 0000000..7028a13 --- /dev/null +++ b/src/log.h @@ -0,0 +1,101 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foologhfoo +#define foologhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "macro.h" + +typedef enum LogTarget{ + LOG_TARGET_CONSOLE, + LOG_TARGET_KMSG, + LOG_TARGET_JOURNAL, + LOG_TARGET_JOURNAL_OR_KMSG, + LOG_TARGET_SYSLOG, + LOG_TARGET_SYSLOG_OR_KMSG, + LOG_TARGET_AUTO, /* console if stderr is tty, JOURNAL_OR_KMSG otherwise */ + LOG_TARGET_NULL, + _LOG_TARGET_MAX, + _LOG_TARGET_INVALID = -1 +} LogTarget; + +void log_set_target(LogTarget target); +void log_set_max_level(int level); + +int log_set_target_from_string(const char *e); +int log_set_max_level_from_string(const char *e); + +void log_show_color(bool b); +void log_show_location(bool b); + +int log_show_color_from_string(const char *e); +int log_show_location_from_string(const char *e); + +LogTarget log_get_target(void); +int log_get_max_level(void); + +int log_open(void); +void log_close(void); +void log_forget_fds(void); + +void log_close_syslog(void); +void log_close_journal(void); +void log_close_kmsg(void); +void log_close_console(void); + +void log_parse_environment(void); + +int log_meta( + int level, + const char*file, + int line, + const char *func, + const char *format, ...) _printf_attr_(5,6); + +_noreturn_ void log_assert_failed(const char *text, const char *file, int line, const char *func); +_noreturn_ void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func); + +/* This modifies the buffer passed! */ +int log_dump_internal( + int level, + const char*file, + int line, + const char *func, + char *buffer); + +#define log_full(level, ...) log_meta(level, __FILE__, __LINE__, __func__, __VA_ARGS__) + +#define log_debug(...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, __VA_ARGS__) +#define log_info(...) log_meta(LOG_INFO, __FILE__, __LINE__, __func__, __VA_ARGS__) +#define log_notice(...) log_meta(LOG_NOTICE, __FILE__, __LINE__, __func__, __VA_ARGS__) +#define log_warning(...) log_meta(LOG_WARNING, __FILE__, __LINE__, __func__, __VA_ARGS__) +#define log_error(...) log_meta(LOG_ERR, __FILE__, __LINE__, __func__, __VA_ARGS__) + +/* This modifies the buffer passed! */ +#define log_dump(level, buffer) log_dump_internal(level, __FILE__, __LINE__, __func__, buffer) + +const char *log_target_to_string(LogTarget target); +LogTarget log_target_from_string(const char *s); + +#endif diff --git a/src/login/70-uaccess.rules b/src/login/70-uaccess.rules new file mode 100644 index 0000000..6932492 --- /dev/null +++ b/src/login/70-uaccess.rules @@ -0,0 +1,72 @@ +# This file is part of systemd. +# +# systemd 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. + +ACTION=="remove", GOTO="uaccess_end" +ENV{MAJOR}=="", GOTO="uaccess_end" + +# PTP/MTP protocol devices, cameras, portable media players +SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="", ENV{DEVTYPE}=="usb_device", IMPORT{program}="usb_id --export %p" +SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="*:060101:*", TAG+="uaccess" + +# Digicams with proprietary protocol +ENV{ID_GPHOTO2}=="*?", TAG+="uaccess" + +# SCSI and USB scanners +ENV{libsane_matched}=="yes", TAG+="uaccess" + +# HPLIP devices (necessary for ink level check and HP tool maintenance) +ENV{ID_HPLIP}=="1", TAG+="uaccess" + +# optical drives +SUBSYSTEM=="block", ENV{ID_CDROM}=="1", TAG+="uaccess" +SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", TAG+="uaccess" + +# Sound devices +SUBSYSTEM=="sound", TAG+="uaccess" + +# ffado is an userspace driver for firewire sound cards +SUBSYSTEM=="firewire", ENV{ID_FFADO}=="1", TAG+="uaccess" + +# Webcams, frame grabber, TV cards +SUBSYSTEM=="video4linux", TAG+="uaccess" +SUBSYSTEM=="dvb", TAG+="uaccess" + +# IIDC devices: industrial cameras and some webcams +SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x00010*", TAG+="uaccess" +SUBSYSTEM=="firewire", ATTR{units}=="*0x00b09d:0x00010*", TAG+="uaccess" +# AV/C devices: camcorders, set-top boxes, TV sets, audio devices, and more +SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x010001*", TAG+="uaccess" +SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x014001*", TAG+="uaccess" + +# DRI video devices +SUBSYSTEM=="drm", KERNEL=="card*", TAG+="uaccess" + +# KVM +SUBSYSTEM=="misc", KERNEL=="kvm", TAG+="uaccess" + +# smart-card readers +ENV{ID_SMARTCARD_READER}=="*?", TAG+="uaccess" + +# PDA devices +ENV{ID_PDA}=="*?", TAG+="uaccess" + +# Programmable remote control +ENV{ID_REMOTE_CONTROL}=="1", TAG+="uaccess" + +# joysticks +SUBSYSTEM=="input", ENV{ID_INPUT_JOYSTICK}=="?*", TAG+="uaccess" + +# color measurement devices +ENV{COLOR_MEASUREMENT_DEVICE}=="*?", TAG+="uaccess" + +# DDC/CI device, usually high-end monitors such as the DreamColor +ENV{DDC_DEVICE}=="*?", TAG+="uaccess" + +# media player raw devices (for user-mode drivers, Android SDK, etc.) +SUBSYSTEM=="usb", ENV{ID_MEDIA_PLAYER}=="?*", TAG+="uaccess" + +LABEL="uaccess_end" diff --git a/src/login/71-seat.rules b/src/login/71-seat.rules new file mode 100644 index 0000000..99425ad --- /dev/null +++ b/src/login/71-seat.rules @@ -0,0 +1,22 @@ +# This file is part of systemd. +# +# systemd 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. + +ACTION=="remove", GOTO="seat_end" + +TAG=="uaccess", SUBSYSTEM!="sound", TAG+="seat" +SUBSYSTEM=="sound", KERNEL=="card*", TAG+="seat" +SUBSYSTEM=="input", KERNEL=="input*", TAG+="seat" +SUBSYSTEM=="graphics", KERNEL=="fb[0-9]*", TAG+="seat" +SUBSYSTEM=="usb", ATTR{bDeviceClass}=="09", TAG+="seat" + +# 'Plugable' USB hub, sound, network, graphics adapter +SUBSYSTEM=="usb", ATTR{idVendor}=="2230", ATTR{idProduct}=="000[13]", ENV{ID_AUTOSEAT}="1" + +TAG=="seat", ENV{ID_PATH}=="", IMPORT{program}="path_id %p" +TAG=="seat", ENV{ID_FOR_SEAT}=="", ENV{ID_PATH_TAG}!="", ENV{ID_FOR_SEAT}="$env{SUBSYSTEM}-$env{ID_PATH_TAG}" + +LABEL="seat_end" diff --git a/src/login/73-seat-late.rules.in b/src/login/73-seat-late.rules.in new file mode 100644 index 0000000..0847932 --- /dev/null +++ b/src/login/73-seat-late.rules.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd 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. + +ACTION=="remove", GOTO="seat_late_end" + +ENV{ID_SEAT}=="", ENV{ID_AUTOSEAT}=="1", ENV{ID_FOR_SEAT}!="", ENV{ID_SEAT}="seat-$env{ID_FOR_SEAT}" +ENV{ID_SEAT}=="", IMPORT{parent}="ID_SEAT" + +ENV{ID_SEAT}!="", TAG+="$env{ID_SEAT}" + +TAG=="uaccess", ENV{MAJOR}!="", RUN+="@rootlibexecdir@/systemd-uaccess $env{DEVNAME} $env{ID_SEAT}" + +LABEL="seat_late_end" diff --git a/src/login/libsystemd-login.pc.in b/src/login/libsystemd-login.pc.in new file mode 100644 index 0000000..cd36a9c --- /dev/null +++ b/src/login/libsystemd-login.pc.in @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: systemd +Description: systemd Login Utility Library +URL: @PACKAGE_URL@ +Version: @PACKAGE_VERSION@ +Libs: -L${libdir} -lsystemd-login +Cflags: -I${includedir} diff --git a/src/login/libsystemd-login.sym b/src/login/libsystemd-login.sym new file mode 100644 index 0000000..a5e6c1e --- /dev/null +++ b/src/login/libsystemd-login.sym @@ -0,0 +1,48 @@ +/*** + This file is part of systemd. + + systemd 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. +***/ + +/* Original symbols from systemd v31 */ + +LIBSYSTEMD_LOGIN_31 { +global: + sd_get_seats; + sd_get_sessions; + sd_get_uids; + sd_login_monitor_flush; + sd_login_monitor_get_fd; + sd_login_monitor_new; + sd_login_monitor_unref; + sd_pid_get_owner_uid; + sd_pid_get_session; + sd_seat_can_multi_session; + sd_seat_get_active; + sd_seat_get_sessions; + sd_session_get_seat; + sd_session_get_uid; + sd_session_is_active; + sd_uid_get_seats; + sd_uid_get_sessions; + sd_uid_get_state; + sd_uid_is_on_seat; +local: + *; +}; + +LIBSYSTEMD_LOGIN_38 { +global: + sd_pid_get_unit; + sd_session_get_service; +} LIBSYSTEMD_LOGIN_31; + +LIBSYSTEMD_LOGIN_43 { +global: + sd_session_get_type; + sd_session_get_class; + sd_session_get_display; +} LIBSYSTEMD_LOGIN_38; diff --git a/src/login/loginctl.c b/src/login/loginctl.c new file mode 100644 index 0000000..30e97e3 --- /dev/null +++ b/src/login/loginctl.c @@ -0,0 +1,1926 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "macro.h" +#include "pager.h" +#include "dbus-common.h" +#include "build.h" +#include "strv.h" +#include "cgroup-show.h" +#include "sysfs-show.h" + +static char **arg_property = NULL; +static bool arg_all = false; +static bool arg_no_pager = false; +static const char *arg_kill_who = NULL; +static int arg_signal = SIGTERM; +static enum transport { + TRANSPORT_NORMAL, + TRANSPORT_SSH, + TRANSPORT_POLKIT +} arg_transport = TRANSPORT_NORMAL; +static const char *arg_host = NULL; + +static bool on_tty(void) { + static int t = -1; + + /* Note that this is invoked relatively early, before we start + * the pager. That means the value we return reflects whether + * we originally were started on a tty, not if we currently + * are. But this is intended, since we want colour and so on + * when run in our own pager. */ + + if (_unlikely_(t < 0)) + t = isatty(STDOUT_FILENO) > 0; + + return t; +} + +static void pager_open_if_enabled(void) { + + /* Cache result before we open the pager */ + on_tty(); + + if (!arg_no_pager) + pager_open(); +} + +static int list_sessions(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; + DBusMessageIter iter, sub, sub2; + unsigned k = 0; + + dbus_error_init(&error); + + assert(bus); + + pager_open_if_enabled(); + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "ListSessions"); + if (!m) { + log_error("Could not allocate message."); + return -ENOMEM; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (on_tty()) + printf("%10s %10s %-16s %-16s\n", "SESSION", "UID", "USER", "SEAT"); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *id, *user, *seat, *object; + uint32_t uid; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &uid, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &user, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &seat, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + printf("%10s %10u %-16s %-16s\n", id, (unsigned) uid, user, seat); + + k++; + + dbus_message_iter_next(&sub); + } + + if (on_tty()) + printf("\n%u sessions listed.\n", k); + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int list_users(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; + DBusMessageIter iter, sub, sub2; + unsigned k = 0; + + dbus_error_init(&error); + + assert(bus); + + pager_open_if_enabled(); + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "ListUsers"); + if (!m) { + log_error("Could not allocate message."); + return -ENOMEM; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (on_tty()) + printf("%10s %-16s\n", "UID", "USER"); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *user, *object; + uint32_t uid; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &uid, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &user, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + printf("%10u %-16s\n", (unsigned) uid, user); + + k++; + + dbus_message_iter_next(&sub); + } + + if (on_tty()) + printf("\n%u users listed.\n", k); + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int list_seats(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; + DBusMessageIter iter, sub, sub2; + unsigned k = 0; + + dbus_error_init(&error); + + assert(bus); + + pager_open_if_enabled(); + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "ListSeats"); + if (!m) { + log_error("Could not allocate message."); + return -ENOMEM; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (on_tty()) + printf("%-16s\n", "SEAT"); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *seat, *object; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &seat, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &object, false) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + printf("%-16s\n", seat); + + k++; + + dbus_message_iter_next(&sub); + } + + if (on_tty()) + printf("\n%u seats listed.\n", k); + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +typedef struct SessionStatusInfo { + const char *id; + uid_t uid; + const char *name; + usec_t timestamp; + const char *control_group; + int vtnr; + const char *seat; + const char *tty; + const char *display; + bool remote; + const char *remote_host; + const char *remote_user; + const char *service; + pid_t leader; + const char *type; + const char *class; + bool active; +} SessionStatusInfo; + +typedef struct UserStatusInfo { + uid_t uid; + const char *name; + usec_t timestamp; + const char *control_group; + const char *state; + char **sessions; + const char *display; +} UserStatusInfo; + +typedef struct SeatStatusInfo { + const char *id; + const char *active_session; + char **sessions; +} SeatStatusInfo; + +static void print_session_status_info(SessionStatusInfo *i) { + char since1[FORMAT_TIMESTAMP_PRETTY_MAX], *s1; + char since2[FORMAT_TIMESTAMP_MAX], *s2; + assert(i); + + printf("%s - ", strna(i->id)); + + if (i->name) + printf("%s (%u)\n", i->name, (unsigned) i->uid); + else + printf("%u\n", (unsigned) i->uid); + + s1 = format_timestamp_pretty(since1, sizeof(since1), i->timestamp); + s2 = format_timestamp(since2, sizeof(since2), i->timestamp); + + if (s1) + printf("\t Since: %s; %s\n", s2, s1); + else if (s2) + printf("\t Since: %s\n", s2); + + if (i->leader > 0) { + char *t = NULL; + + printf("\t Leader: %u", (unsigned) i->leader); + + get_process_comm(i->leader, &t); + if (t) { + printf(" (%s)", t); + free(t); + } + + printf("\n"); + } + + if (i->seat) { + printf("\t Seat: %s", i->seat); + + if (i->vtnr > 0) + printf("; vc%i", i->vtnr); + + printf("\n"); + } + + if (i->tty) + printf("\t TTY: %s\n", i->tty); + else if (i->display) + printf("\t Display: %s\n", i->display); + + if (i->remote_host && i->remote_user) + printf("\t Remote: %s@%s\n", i->remote_user, i->remote_host); + else if (i->remote_host) + printf("\t Remote: %s\n", i->remote_host); + else if (i->remote_user) + printf("\t Remote: user %s\n", i->remote_user); + else if (i->remote) + printf("\t Remote: Yes\n"); + + if (i->service) { + printf("\t Service: %s", i->service); + + if (i->type) + printf("; type %s", i->type); + + if (i->class) + printf("; class %s", i->class); + + printf("\n"); + } else if (i->type) { + printf("\t Type: %s\n", i->type); + + if (i->class) + printf("; class %s", i->class); + } else if (i->class) + printf("\t Class: %s\n", i->class); + + + printf("\t Active: %s\n", yes_no(i->active)); + + if (i->control_group) { + unsigned c; + + printf("\t CGroup: %s\n", i->control_group); + + if (arg_transport != TRANSPORT_SSH) { + c = columns(); + if (c > 18) + c -= 18; + else + c = 0; + + show_cgroup_by_path(i->control_group, "\t\t ", c, false); + } + } +} + +static void print_user_status_info(UserStatusInfo *i) { + char since1[FORMAT_TIMESTAMP_PRETTY_MAX], *s1; + char since2[FORMAT_TIMESTAMP_MAX], *s2; + assert(i); + + if (i->name) + printf("%s (%u)\n", i->name, (unsigned) i->uid); + else + printf("%u\n", (unsigned) i->uid); + + s1 = format_timestamp_pretty(since1, sizeof(since1), i->timestamp); + s2 = format_timestamp(since2, sizeof(since2), i->timestamp); + + if (s1) + printf("\t Since: %s; %s\n", s2, s1); + else if (s2) + printf("\t Since: %s\n", s2); + + if (!isempty(i->state)) + printf("\t State: %s\n", i->state); + + if (!strv_isempty(i->sessions)) { + char **l; + printf("\tSessions:"); + + STRV_FOREACH(l, i->sessions) { + if (streq_ptr(*l, i->display)) + printf(" *%s", *l); + else + printf(" %s", *l); + } + + printf("\n"); + } + + if (i->control_group) { + unsigned c; + + printf("\t CGroup: %s\n", i->control_group); + + if (arg_transport != TRANSPORT_SSH) { + c = columns(); + if (c > 18) + c -= 18; + else + c = 0; + + show_cgroup_by_path(i->control_group, "\t\t ", c, false); + } + } +} + +static void print_seat_status_info(SeatStatusInfo *i) { + assert(i); + + printf("%s\n", strna(i->id)); + + if (!strv_isempty(i->sessions)) { + char **l; + printf("\tSessions:"); + + STRV_FOREACH(l, i->sessions) { + if (streq_ptr(*l, i->active_session)) + printf(" *%s", *l); + else + printf(" %s", *l); + } + + printf("\n"); + } + + if (arg_transport != TRANSPORT_SSH) { + unsigned c; + + c = columns(); + if (c > 21) + c -= 21; + else + c = 0; + + printf("\t Devices:\n"); + + show_sysfs(i->id, "\t\t ", c); + } +} + +static int status_property_session(const char *name, DBusMessageIter *iter, SessionStatusInfo *i) { + assert(name); + assert(iter); + assert(i); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + + dbus_message_iter_get_basic(iter, &s); + + if (!isempty(s)) { + if (streq(name, "Id")) + i->id = s; + else if (streq(name, "Name")) + i->name = s; + else if (streq(name, "ControlGroupPath")) + i->control_group = s; + else if (streq(name, "TTY")) + i->tty = s; + else if (streq(name, "Display")) + i->display = s; + else if (streq(name, "RemoteHost")) + i->remote_host = s; + else if (streq(name, "RemoteUser")) + i->remote_user = s; + else if (streq(name, "Service")) + i->service = s; + else if (streq(name, "Type")) + i->type = s; + else if (streq(name, "Class")) + i->class = s; + } + break; + } + + case DBUS_TYPE_UINT32: { + uint32_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "VTNr")) + i->vtnr = (int) u; + else if (streq(name, "Leader")) + i->leader = (pid_t) u; + + break; + } + + case DBUS_TYPE_BOOLEAN: { + dbus_bool_t b; + + dbus_message_iter_get_basic(iter, &b); + + if (streq(name, "Remote")) + i->remote = b; + else if (streq(name, "Active")) + i->active = b; + + break; + } + + case DBUS_TYPE_UINT64: { + uint64_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "Timestamp")) + i->timestamp = (usec_t) u; + + break; + } + + case DBUS_TYPE_STRUCT: { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32 && streq(name, "User")) { + uint32_t u; + + dbus_message_iter_get_basic(&sub, &u); + i->uid = (uid_t) u; + + } else if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "Seat")) { + const char *s; + + dbus_message_iter_get_basic(&sub, &s); + + if (!isempty(s)) + i->seat = s; + } + + break; + } + } + + return 0; +} + +static int status_property_user(const char *name, DBusMessageIter *iter, UserStatusInfo *i) { + assert(name); + assert(iter); + assert(i); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + + dbus_message_iter_get_basic(iter, &s); + + if (!isempty(s)) { + if (streq(name, "Name")) + i->name = s; + else if (streq(name, "ControlGroupPath")) + i->control_group = s; + else if (streq(name, "State")) + i->state = s; + } + break; + } + + case DBUS_TYPE_UINT32: { + uint32_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "UID")) + i->uid = (uid_t) u; + + break; + } + + case DBUS_TYPE_UINT64: { + uint64_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "Timestamp")) + i->timestamp = (usec_t) u; + + break; + } + + case DBUS_TYPE_STRUCT: { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "Display")) { + const char *s; + + dbus_message_iter_get_basic(&sub, &s); + + if (!isempty(s)) + i->display = s; + } + + break; + } + + case DBUS_TYPE_ARRAY: { + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Sessions")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *id; + const char *path; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &path, false) >= 0) { + char **l; + + l = strv_append(i->sessions, id); + if (!l) + return -ENOMEM; + + strv_free(i->sessions); + i->sessions = l; + } + + dbus_message_iter_next(&sub); + } + + return 0; + } + } + } + + return 0; +} + +static int status_property_seat(const char *name, DBusMessageIter *iter, SeatStatusInfo *i) { + assert(name); + assert(iter); + assert(i); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + + dbus_message_iter_get_basic(iter, &s); + + if (!isempty(s)) { + if (streq(name, "Id")) + i->id = s; + } + break; + } + + case DBUS_TYPE_STRUCT: { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "ActiveSession")) { + const char *s; + + dbus_message_iter_get_basic(&sub, &s); + + if (!isempty(s)) + i->active_session = s; + } + + break; + } + + case DBUS_TYPE_ARRAY: { + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Sessions")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *id; + const char *path; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &path, false) >= 0) { + char **l; + + l = strv_append(i->sessions, id); + if (!l) + return -ENOMEM; + + strv_free(i->sessions); + i->sessions = l; + } + + dbus_message_iter_next(&sub); + } + + return 0; + } + } + } + + return 0; +} + +static int print_property(const char *name, DBusMessageIter *iter) { + assert(name); + assert(iter); + + if (arg_property && !strv_find(arg_property, name)) + return 0; + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRUCT: { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && + (streq(name, "Display") || streq(name, "ActiveSession"))) { + const char *s; + + dbus_message_iter_get_basic(&sub, &s); + + if (arg_all || !isempty(s)) + printf("%s=%s\n", name, s); + return 0; + } + break; + } + + case DBUS_TYPE_ARRAY: + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Sessions")) { + DBusMessageIter sub, sub2; + bool found = false; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *id; + const char *path; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &path, false) >= 0) { + if (found) + printf(" %s", id); + else { + printf("%s=%s", name, id); + found = true; + } + } + + dbus_message_iter_next(&sub); + } + + if (!found && arg_all) + printf("%s=\n", name); + else if (found) + printf("\n"); + + return 0; + } + + break; + } + + if (generic_print_property(name, iter, arg_all) > 0) + return 0; + + if (arg_all) + printf("%s=[unprintable]\n", name); + + return 0; +} + +static int show_one(const char *verb, DBusConnection *bus, const char *path, bool show_properties, bool *new_line) { + DBusMessage *m = NULL, *reply = NULL; + const char *interface = ""; + int r; + DBusError error; + DBusMessageIter iter, sub, sub2, sub3; + SessionStatusInfo session_info; + UserStatusInfo user_info; + SeatStatusInfo seat_info; + + assert(bus); + assert(path); + assert(new_line); + + zero(session_info); + zero(user_info); + zero(seat_info); + + dbus_error_init(&error); + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + path, + "org.freedesktop.DBus.Properties", + "GetAll"); + if (!m) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (*new_line) + printf("\n"); + + *new_line = true; + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *name; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub2, &sub3); + + if (show_properties) + r = print_property(name, &sub3); + else if (strstr(verb, "session")) + r = status_property_session(name, &sub3, &session_info); + else if (strstr(verb, "user")) + r = status_property_user(name, &sub3, &user_info); + else + r = status_property_seat(name, &sub3, &seat_info); + + if (r < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_next(&sub); + } + + if (!show_properties) { + if (strstr(verb, "session")) + print_session_status_info(&session_info); + else if (strstr(verb, "user")) + print_user_status_info(&user_info); + else + print_seat_status_info(&seat_info); + } + + strv_free(seat_info.sessions); + strv_free(user_info.sessions); + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int show(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *m = NULL, *reply = NULL; + int r, ret = 0; + DBusError error; + unsigned i; + bool show_properties, new_line = false; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + show_properties = !strstr(args[0], "status"); + + if (show_properties) + pager_open_if_enabled(); + + if (show_properties && n <= 1) { + /* If not argument is specified inspect the manager + * itself */ + + ret = show_one(args[0], bus, "/org/freedesktop/login1", show_properties, &new_line); + goto finish; + } + + for (i = 1; i < n; i++) { + const char *path = NULL; + + if (strstr(args[0], "session")) { + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "GetSession"); + if (!m) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + + } else if (strstr(args[0], "user")) { + uid_t uid; + uint32_t u; + + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL); + if (ret < 0) { + log_error("User %s unknown.", args[i]); + goto finish; + } + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "GetUser"); + if (!m) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + u = (uint32_t) uid; + if (!dbus_message_append_args(m, + DBUS_TYPE_UINT32, &u, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + } else { + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "GetSeat"); + if (!m) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + + r = show_one(args[0], bus, path, show_properties, &new_line); + if (r != 0) + ret = r; + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + } + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return ret; +} + +static int activate(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *m = NULL; + int ret = 0; + DBusError error; + unsigned i; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + for (i = 1; i < n; i++) { + DBusMessage *reply; + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + streq(args[0], "lock-session") ? "LockSession" : + streq(args[0], "unlock-session") ? "UnlockSession" : + streq(args[0], "terminate-session") ? "TerminateSession" : + "ActivateSession"); + if (!m) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + } + +finish: + if (m) + dbus_message_unref(m); + + dbus_error_free(&error); + + return ret; +} + +static int kill_session(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *m = NULL; + int ret = 0; + DBusError error; + unsigned i; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + if (!arg_kill_who) + arg_kill_who = "all"; + + for (i = 1; i < n; i++) { + DBusMessage *reply; + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "KillSession"); + if (!m) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_STRING, &arg_kill_who, + DBUS_TYPE_INT32, arg_signal, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + } + +finish: + if (m) + dbus_message_unref(m); + + dbus_error_free(&error); + + return ret; +} + +static int enable_linger(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *m = NULL; + int ret = 0; + DBusError error; + unsigned i; + dbus_bool_t b, interactive = true; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + b = streq(args[0], "enable-linger"); + + for (i = 1; i < n; i++) { + DBusMessage *reply; + uint32_t u; + uid_t uid; + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "SetUserLinger"); + if (!m) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL); + if (ret < 0) { + log_error("Failed to resolve user %s: %s", args[i], strerror(-ret)); + goto finish; + } + + u = (uint32_t) uid; + if (!dbus_message_append_args(m, + DBUS_TYPE_UINT32, &u, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + } + + ret = 0; + +finish: + if (m) + dbus_message_unref(m); + + dbus_error_free(&error); + + return ret; +} + +static int terminate_user(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *m = NULL; + int ret = 0; + DBusError error; + unsigned i; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + for (i = 1; i < n; i++) { + uint32_t u; + uid_t uid; + DBusMessage *reply; + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "TerminateUser"); + if (!m) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL); + if (ret < 0) { + log_error("Failed to look up user %s: %s", args[i], strerror(-ret)); + goto finish; + } + + u = (uint32_t) uid; + if (!dbus_message_append_args(m, + DBUS_TYPE_UINT32, &u, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + } + + ret = 0; + +finish: + if (m) + dbus_message_unref(m); + + dbus_error_free(&error); + + return ret; +} + +static int kill_user(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *m = NULL; + int ret = 0; + DBusError error; + unsigned i; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + if (!arg_kill_who) + arg_kill_who = "all"; + + for (i = 1; i < n; i++) { + DBusMessage *reply; + uid_t uid; + uint32_t u; + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "KillUser"); + if (!m) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL); + if (ret < 0) { + log_error("Failed to look up user %s: %s", args[i], strerror(-ret)); + goto finish; + } + + u = (uint32_t) uid; + if (!dbus_message_append_args(m, + DBUS_TYPE_UINT32, &u, + DBUS_TYPE_INT32, arg_signal, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + } + + ret = 0; + +finish: + if (m) + dbus_message_unref(m); + + dbus_error_free(&error); + + return ret; +} + +static int attach(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *m = NULL; + int ret = 0; + DBusError error; + unsigned i; + dbus_bool_t interactive = true; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + for (i = 2; i < n; i++) { + DBusMessage *reply; + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "AttachDevice"); + if (!m) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &args[1], + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + } + +finish: + if (m) + dbus_message_unref(m); + + dbus_error_free(&error); + + return ret; +} + +static int flush_devices(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *m = NULL, *reply = NULL; + int ret = 0; + DBusError error; + dbus_bool_t interactive = true; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "FlushDevices"); + if (!m) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return ret; +} + +static int terminate_seat(DBusConnection *bus, char **args, unsigned n) { + DBusMessage *m = NULL; + int ret = 0; + DBusError error; + unsigned i; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + for (i = 1; i < n; i++) { + DBusMessage *reply; + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "TerminateSeat"); + if (!m) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + } + +finish: + if (m) + dbus_message_unref(m); + + dbus_error_free(&error); + + return ret; +} + +static int help(void) { + + printf("%s [OPTIONS...] {COMMAND} ...\n\n" + "Send control commands to or query the login manager.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " -p --property=NAME Show only properties by this name\n" + " -a --all Show all properties, including empty ones\n" + " --kill-who=WHO Who to send signal to\n" + " -s --signal=SIGNAL Which signal to send\n" + " -H --host=[USER@]HOST\n" + " Show information for remote host\n" + " -P --privileged Acquire privileges before execution\n" + " --no-pager Do not pipe output into a pager\n\n" + "Commands:\n" + " list-sessions List sessions\n" + " session-status [ID...] Show session status\n" + " show-session [ID...] Show properties of one or more sessions\n" + " activate [ID] Activate a session\n" + " lock-session [ID...] Screen lock one or more sessions\n" + " unlock-session [ID...] Screen unlock one or more sessions\n" + " terminate-session [ID...] Terminate one or more sessions\n" + " kill-session [ID...] Send signal to processes of a session\n" + " list-users List users\n" + " user-status [USER...] Show user status\n" + " show-user [USER...] Show properties of one or more users\n" + " enable-linger [USER...] Enable linger state of one or more users\n" + " disable-linger [USER...] Disable linger state of one or more users\n" + " terminate-user [USER...] Terminate all sessions of one or more users\n" + " kill-user [USER...] Send signal to processes of a user\n" + " list-seats List seats\n" + " seat-status [NAME...] Show seat status\n" + " show-seat [NAME...] Show properties of one or more seats\n" + " attach [NAME] [DEVICE...] Attach one or more devices to a seat\n" + " flush-devices Flush all device associations\n" + " terminate-seat [NAME...] Terminate all sessions on one or more seats\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_VERSION = 0x100, + ARG_NO_PAGER, + ARG_KILL_WHO + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "property", required_argument, NULL, 'p' }, + { "all", no_argument, NULL, 'a' }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "kill-who", required_argument, NULL, ARG_KILL_WHO }, + { "signal", required_argument, NULL, 's' }, + { "host", required_argument, NULL, 'H' }, + { "privileged",no_argument, NULL, 'P' }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "hp:as:H:P", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(DISTRIBUTION); + puts(SYSTEMD_FEATURES); + return 0; + + case 'p': { + char **l; + + l = strv_append(arg_property, optarg); + if (!l) + return -ENOMEM; + + strv_free(arg_property); + arg_property = l; + + /* If the user asked for a particular + * property, show it to him, even if it is + * empty. */ + arg_all = true; + break; + } + + case 'a': + arg_all = true; + break; + + case ARG_NO_PAGER: + arg_no_pager = true; + break; + + case ARG_KILL_WHO: + arg_kill_who = optarg; + break; + + case 's': + arg_signal = signal_from_string_try_harder(optarg); + if (arg_signal < 0) { + log_error("Failed to parse signal string %s.", optarg); + return -EINVAL; + } + break; + + case 'P': + arg_transport = TRANSPORT_POLKIT; + break; + + case 'H': + arg_transport = TRANSPORT_SSH; + arg_host = optarg; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +static int loginctl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) { + + static const struct { + const char* verb; + const enum { + MORE, + LESS, + EQUAL + } argc_cmp; + const int argc; + int (* const dispatch)(DBusConnection *bus, char **args, unsigned n); + } verbs[] = { + { "list-sessions", LESS, 1, list_sessions }, + { "session-status", MORE, 2, show }, + { "show-session", MORE, 1, show }, + { "activate", EQUAL, 2, activate }, + { "lock-session", MORE, 2, activate }, + { "unlock-session", MORE, 2, activate }, + { "terminate-session", MORE, 2, activate }, + { "kill-session", MORE, 2, kill_session }, + { "list-users", EQUAL, 1, list_users }, + { "user-status", MORE, 2, show }, + { "show-user", MORE, 1, show }, + { "enable-linger", MORE, 2, enable_linger }, + { "disable-linger", MORE, 2, enable_linger }, + { "terminate-user", MORE, 2, terminate_user }, + { "kill-user", MORE, 2, kill_user }, + { "list-seats", EQUAL, 1, list_seats }, + { "seat-status", MORE, 2, show }, + { "show-seat", MORE, 1, show }, + { "attach", MORE, 3, attach }, + { "flush-devices", EQUAL, 1, flush_devices }, + { "terminate-seat", MORE, 2, terminate_seat }, + }; + + int left; + unsigned i; + + assert(argc >= 0); + assert(argv); + assert(error); + + left = argc - optind; + + if (left <= 0) + /* Special rule: no arguments means "list-sessions" */ + i = 0; + else { + if (streq(argv[optind], "help")) { + help(); + return 0; + } + + for (i = 0; i < ELEMENTSOF(verbs); i++) + if (streq(argv[optind], verbs[i].verb)) + break; + + if (i >= ELEMENTSOF(verbs)) { + log_error("Unknown operation %s", argv[optind]); + return -EINVAL; + } + } + + switch (verbs[i].argc_cmp) { + + case EQUAL: + if (left != verbs[i].argc) { + log_error("Invalid number of arguments."); + return -EINVAL; + } + + break; + + case MORE: + if (left < verbs[i].argc) { + log_error("Too few arguments."); + return -EINVAL; + } + + break; + + case LESS: + if (left > verbs[i].argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + break; + + default: + assert_not_reached("Unknown comparison operator."); + } + + if (!bus) { + log_error("Failed to get D-Bus connection: %s", error->message); + return -EIO; + } + + return verbs[i].dispatch(bus, argv + optind, left); +} + +int main(int argc, char*argv[]) { + int r, retval = EXIT_FAILURE; + DBusConnection *bus = NULL; + DBusError error; + + dbus_error_init(&error); + + log_parse_environment(); + log_open(); + + r = parse_argv(argc, argv); + if (r < 0) + goto finish; + else if (r == 0) { + retval = EXIT_SUCCESS; + goto finish; + } + + if (arg_transport == TRANSPORT_NORMAL) + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + else if (arg_transport == TRANSPORT_POLKIT) + bus_connect_system_polkit(&bus, &error); + else if (arg_transport == TRANSPORT_SSH) + bus_connect_system_ssh(NULL, arg_host, &bus, &error); + else + assert_not_reached("Uh, invalid transport..."); + + r = loginctl_main(bus, argc, argv, &error); + retval = r < 0 ? EXIT_FAILURE : r; + +finish: + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + dbus_error_free(&error); + dbus_shutdown(); + + strv_free(arg_property); + + pager_close(); + + return retval; +} diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c new file mode 100644 index 0000000..eb8a48d --- /dev/null +++ b/src/login/logind-acl.c @@ -0,0 +1,248 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "logind-acl.h" +#include "util.h" +#include "acl-util.h" + +static int flush_acl(acl_t acl) { + acl_entry_t i; + int found; + bool changed = false; + + assert(acl); + + for (found = acl_get_entry(acl, ACL_FIRST_ENTRY, &i); + found > 0; + found = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) { + + acl_tag_t tag; + + if (acl_get_tag_type(i, &tag) < 0) + return -errno; + + if (tag != ACL_USER) + continue; + + if (acl_delete_entry(acl, i) < 0) + return -errno; + + changed = true; + } + + if (found < 0) + return -errno; + + return changed; +} + +int devnode_acl(const char *path, + bool flush, + bool del, uid_t old_uid, + bool add, uid_t new_uid) { + + acl_t acl; + int r = 0; + bool changed = false; + + assert(path); + + acl = acl_get_file(path, ACL_TYPE_ACCESS); + if (!acl) + return -errno; + + if (flush) { + + r = flush_acl(acl); + if (r < 0) + goto finish; + if (r > 0) + changed = true; + + } else if (del && old_uid > 0) { + acl_entry_t entry; + + r = acl_find_uid(acl, old_uid, &entry); + if (r < 0) + goto finish; + + if (r > 0) { + if (acl_delete_entry(acl, entry) < 0) { + r = -errno; + goto finish; + } + + changed = true; + } + } + + if (add && new_uid > 0) { + acl_entry_t entry; + acl_permset_t permset; + int rd, wt; + + r = acl_find_uid(acl, new_uid, &entry); + if (r < 0) + goto finish; + + if (r == 0) { + if (acl_create_entry(&acl, &entry) < 0) { + r = -errno; + goto finish; + } + + if (acl_set_tag_type(entry, ACL_USER) < 0 || + acl_set_qualifier(entry, &new_uid) < 0) { + r = -errno; + goto finish; + } + } + + if (acl_get_permset(entry, &permset) < 0) { + r = -errno; + goto finish; + } + + rd = acl_get_perm(permset, ACL_READ); + if (rd < 0) { + r = -errno; + goto finish; + } + + wt = acl_get_perm(permset, ACL_WRITE); + if (wt < 0) { + r = -errno; + goto finish; + } + + if (!rd || !wt) { + + if (acl_add_perm(permset, ACL_READ|ACL_WRITE) < 0) { + r = -errno; + goto finish; + } + + changed = true; + } + } + + if (!changed) + goto finish; + + if (acl_calc_mask(&acl) < 0) { + r = -errno; + goto finish; + } + + if (acl_set_file(path, ACL_TYPE_ACCESS, acl) < 0) { + r = -errno; + goto finish; + } + + r = 0; + +finish: + acl_free(acl); + + return r; +} + +int devnode_acl_all(struct udev *udev, + const char *seat, + bool flush, + bool del, uid_t old_uid, + bool add, uid_t new_uid) { + + struct udev_list_entry *item = NULL, *first = NULL; + struct udev_enumerate *e; + int r; + + assert(udev); + + if (isempty(seat)) + seat = "seat0"; + + e = udev_enumerate_new(udev); + if (!e) + return -ENOMEM; + + /* We can only match by one tag in libudev. We choose + * "uaccess" for that. If we could match for two tags here we + * could add the seat name as second match tag, but this would + * be hardly optimizable in libudev, and hence checking the + * second tag manually in our loop is a good solution. */ + + r = udev_enumerate_add_match_tag(e, "uaccess"); + if (r < 0) + goto finish; + + r = udev_enumerate_scan_devices(e); + if (r < 0) + goto finish; + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + struct udev_device *d; + const char *node, *sn; + + d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); + if (!d) { + r = -ENOMEM; + goto finish; + } + + sn = udev_device_get_property_value(d, "ID_SEAT"); + if (isempty(sn)) + sn = "seat0"; + + if (!streq(seat, sn)) { + udev_device_unref(d); + continue; + } + + node = udev_device_get_devnode(d); + if (!node) { + /* In case people mistag devices with nodes, we need to ignore this */ + udev_device_unref(d); + continue; + } + + log_debug("Fixing up %s for seat %s...", node, sn); + + r = devnode_acl(node, flush, del, old_uid, add, new_uid); + udev_device_unref(d); + + if (r < 0) + goto finish; + } + +finish: + if (e) + udev_enumerate_unref(e); + + return r; +} diff --git a/src/login/logind-acl.h b/src/login/logind-acl.h new file mode 100644 index 0000000..72740f5 --- /dev/null +++ b/src/login/logind-acl.h @@ -0,0 +1,60 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foologindaclhfoo +#define foologindaclhfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#ifdef HAVE_ACL + +int devnode_acl(const char *path, + bool flush, + bool del, uid_t old_uid, + bool add, uid_t new_uid); + +int devnode_acl_all(struct udev *udev, + const char *seat, + bool flush, + bool del, uid_t old_uid, + bool add, uid_t new_uid); +#else + +static inline int devnode_acl(const char *path, + bool flush, + bool del, uid_t old_uid, + bool add, uid_t new_uid) { + return 0; +} + +static inline int devnode_acl_all(struct udev *udev, + const char *seat, + bool flush, + bool del, uid_t old_uid, + bool add, uid_t new_uid) { + return 0; +} + +#endif + +#endif diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c new file mode 100644 index 0000000..d8f4d89 --- /dev/null +++ b/src/login/logind-dbus.c @@ -0,0 +1,1667 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "logind.h" +#include "dbus-common.h" +#include "strv.h" +#include "polkit.h" +#include "special.h" + +#define BUS_MANAGER_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION_BEGIN \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_MANAGER_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE + +#define INTROSPECTION_END \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.login1.Manager\0" + +static int bus_manager_append_idle_hint(DBusMessageIter *i, const char *property, void *data) { + Manager *m = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(m); + + b = manager_get_idle_hint(m, NULL) > 0; + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) { + Manager *m = data; + dual_timestamp t; + uint64_t u; + + assert(i); + assert(property); + assert(m); + + manager_get_idle_hint(m, &t); + u = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u)) + return -ENOMEM; + + return 0; +} + +static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMessage **_reply) { + Session *session = NULL; + User *user = NULL; + const char *type, *class, *seat, *tty, *display, *remote_user, *remote_host, *service; + uint32_t uid, leader, audit_id = 0; + dbus_bool_t remote, kill_processes; + char **controllers = NULL, **reset_controllers = NULL; + SessionType t; + SessionClass c; + Seat *s; + DBusMessageIter iter; + int r; + char *id = NULL, *p; + uint32_t vtnr = 0; + int fifo_fd = -1; + DBusMessage *reply = NULL; + bool b; + + assert(m); + assert(message); + assert(_reply); + + if (!dbus_message_iter_init(message, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &uid); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &leader); + + if (leader <= 0 || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &service); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &type); + t = session_type_from_string(type); + + if (t < 0 || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &class); + if (isempty(class)) + c = SESSION_USER; + else + c = session_class_from_string(class); + + if (c < 0 || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &seat); + + if (isempty(seat)) + s = NULL; + else { + s = hashmap_get(m->seats, seat); + if (!s) + return -ENOENT; + } + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &vtnr); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &tty); + + if (tty_is_vc(tty)) { + int v; + + if (!s) + s = m->vtconsole; + else if (s != m->vtconsole) + return -EINVAL; + + v = vtnr_from_tty(tty); + + if (v <= 0) + return v < 0 ? v : -EINVAL; + + if (vtnr <= 0) + vtnr = (uint32_t) v; + else if (vtnr != (uint32_t) v) + return -EINVAL; + + } else if (!isempty(tty) && s && seat_is_vtconsole(s)) + return -EINVAL; + + if (s) { + if (seat_can_multi_session(s)) { + if (vtnr <= 0 || vtnr > 63) + return -EINVAL; + } else { + if (vtnr > 0) + return -EINVAL; + } + } + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &display); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &remote); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &remote_user); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &remote_host); + + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + r = bus_parse_strv_iter(&iter, &controllers); + if (r < 0) + return -EINVAL; + + if (strv_contains(controllers, "systemd") || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING) { + r = -EINVAL; + goto fail; + } + + r = bus_parse_strv_iter(&iter, &reset_controllers); + if (r < 0) + goto fail; + + if (strv_contains(reset_controllers, "systemd") || + !dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN) { + r = -EINVAL; + goto fail; + } + + dbus_message_iter_get_basic(&iter, &kill_processes); + + r = manager_add_user_by_uid(m, uid, &user); + if (r < 0) + goto fail; + + audit_session_from_pid(leader, &audit_id); + + if (audit_id > 0) { + asprintf(&id, "%lu", (unsigned long) audit_id); + + if (!id) { + r = -ENOMEM; + goto fail; + } + + session = hashmap_get(m->sessions, id); + + if (session) { + free(id); + + fifo_fd = session_create_fifo(session); + if (fifo_fd < 0) { + r = fifo_fd; + goto fail; + } + + /* Session already exists, client is probably + * something like "su" which changes uid but + * is still the same audit session */ + + reply = dbus_message_new_method_return(message); + if (!reply) { + r = -ENOMEM; + goto fail; + } + + p = session_bus_path(session); + if (!p) { + r = -ENOMEM; + goto fail; + } + + seat = session->seat ? session->seat->id : ""; + vtnr = session->vtnr; + b = dbus_message_append_args( + reply, + DBUS_TYPE_STRING, &session->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_STRING, &session->user->runtime_path, + DBUS_TYPE_UNIX_FD, &fifo_fd, + DBUS_TYPE_STRING, &seat, + DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_INVALID); + free(p); + + if (!b) { + r = -ENOMEM; + goto fail; + } + + close_nointr_nofail(fifo_fd); + *_reply = reply; + + strv_free(controllers); + strv_free(reset_controllers); + + return 0; + } + + } else { + do { + free(id); + asprintf(&id, "c%lu", ++m->session_counter); + + if (!id) { + r = -ENOMEM; + goto fail; + } + + } while (hashmap_get(m->sessions, id)); + } + + r = manager_add_session(m, user, id, &session); + free(id); + if (r < 0) + goto fail; + + session->leader = leader; + session->audit_id = audit_id; + session->type = t; + session->class = c; + session->remote = remote; + session->controllers = controllers; + session->reset_controllers = reset_controllers; + session->kill_processes = kill_processes; + session->vtnr = vtnr; + + controllers = reset_controllers = NULL; + + if (!isempty(tty)) { + session->tty = strdup(tty); + if (!session->tty) { + r = -ENOMEM; + goto fail; + } + } + + if (!isempty(display)) { + session->display = strdup(display); + if (!session->display) { + r = -ENOMEM; + goto fail; + } + } + + if (!isempty(remote_user)) { + session->remote_user = strdup(remote_user); + if (!session->remote_user) { + r = -ENOMEM; + goto fail; + } + } + + if (!isempty(remote_host)) { + session->remote_host = strdup(remote_host); + if (!session->remote_host) { + r = -ENOMEM; + goto fail; + } + } + + if (!isempty(service)) { + session->service = strdup(service); + if (!session->service) { + r = -ENOMEM; + goto fail; + } + } + + fifo_fd = session_create_fifo(session); + if (fifo_fd < 0) { + r = fifo_fd; + goto fail; + } + + if (s) { + r = seat_attach_session(s, session); + if (r < 0) + goto fail; + } + + r = session_start(session); + if (r < 0) + goto fail; + + reply = dbus_message_new_method_return(message); + if (!reply) { + r = -ENOMEM; + goto fail; + } + + p = session_bus_path(session); + if (!p) { + r = -ENOMEM; + goto fail; + } + + seat = s ? s->id : ""; + b = dbus_message_append_args( + reply, + DBUS_TYPE_STRING, &session->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_STRING, &session->user->runtime_path, + DBUS_TYPE_UNIX_FD, &fifo_fd, + DBUS_TYPE_STRING, &seat, + DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_INVALID); + free(p); + + if (!b) { + r = -ENOMEM; + goto fail; + } + + close_nointr_nofail(fifo_fd); + *_reply = reply; + + return 0; + +fail: + strv_free(controllers); + strv_free(reset_controllers); + + if (session) + session_add_to_gc_queue(session); + + if (user) + user_add_to_gc_queue(user); + + if (fifo_fd >= 0) + close_nointr_nofail(fifo_fd); + + if (reply) + dbus_message_unref(reply); + + return r; +} + +static int trigger_device(Manager *m, struct udev_device *d) { + struct udev_enumerate *e; + struct udev_list_entry *first, *item; + int r; + + assert(m); + + e = udev_enumerate_new(m->udev); + if (!e) { + r = -ENOMEM; + goto finish; + } + + if (d) { + if (udev_enumerate_add_match_parent(e, d) < 0) { + r = -EIO; + goto finish; + } + } + + if (udev_enumerate_scan_devices(e) < 0) { + r = -EIO; + goto finish; + } + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + char *t; + const char *p; + + p = udev_list_entry_get_name(item); + + t = strappend(p, "/uevent"); + if (!t) { + r = -ENOMEM; + goto finish; + } + + write_one_line_file(t, "change"); + free(t); + } + + r = 0; + +finish: + if (e) + udev_enumerate_unref(e); + + return r; +} + +static int attach_device(Manager *m, const char *seat, const char *sysfs) { + struct udev_device *d; + char *rule = NULL, *file = NULL; + const char *id_for_seat; + int r; + + assert(m); + assert(seat); + assert(sysfs); + + d = udev_device_new_from_syspath(m->udev, sysfs); + if (!d) + return -ENODEV; + + if (!udev_device_has_tag(d, "seat")) { + r = -ENODEV; + goto finish; + } + + id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT"); + if (!id_for_seat) { + r = -ENODEV; + goto finish; + } + + if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0) { + r = -ENOMEM; + goto finish; + } + + if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0) { + r = -ENOMEM; + goto finish; + } + + mkdir_p("/etc/udev/rules.d", 0755); + r = write_one_line_file_atomic(file, rule); + if (r < 0) + goto finish; + + r = trigger_device(m, d); + +finish: + free(rule); + free(file); + + if (d) + udev_device_unref(d); + + return r; +} + +static int flush_devices(Manager *m) { + DIR *d; + + assert(m); + + d = opendir("/etc/udev/rules.d"); + if (!d) { + if (errno != ENOENT) + log_warning("Failed to open /etc/udev/rules.d: %m"); + } else { + struct dirent *de; + + while ((de = readdir(d))) { + + if (!dirent_is_file(de)) + continue; + + if (!startswith(de->d_name, "72-seat-")) + continue; + + if (!endswith(de->d_name, ".rules")) + continue; + + if (unlinkat(dirfd(d), de->d_name, 0) < 0) + log_warning("Failed to unlink %s: %m", de->d_name); + } + + closedir(d); + } + + return trigger_device(m, NULL); +} + +static int have_multiple_sessions( + DBusConnection *connection, + Manager *m, + DBusMessage *message, + DBusError *error) { + + Session *s; + + assert(m); + + if (hashmap_size(m->sessions) > 1) + return true; + + /* Hmm, there's only one session, but let's make sure it + * actually belongs to the user who is asking. If not, better + * be safe than sorry. */ + + s = hashmap_first(m->sessions); + if (s) { + unsigned long ul; + + ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), error); + if (ul == (unsigned long) -1) + return -EIO; + + return s->user->uid != ul; + } + + return false; +} + +static const BusProperty bus_login_manager_properties[] = { + { "ControlGroupHierarchy", bus_property_append_string, "s", offsetof(Manager, cgroup_path), true }, + { "Controllers", bus_property_append_strv, "as", offsetof(Manager, controllers), true }, + { "ResetControllers", bus_property_append_strv, "as", offsetof(Manager, reset_controllers), true }, + { "NAutoVTs", bus_property_append_unsigned, "u", offsetof(Manager, n_autovts) }, + { "KillOnlyUsers", bus_property_append_strv, "as", offsetof(Manager, kill_only_users), true }, + { "KillExcludeUsers", bus_property_append_strv, "as", offsetof(Manager, kill_exclude_users), true }, + { "KillUserProcesses", bus_property_append_bool, "b", offsetof(Manager, kill_user_processes) }, + { "IdleHint", bus_manager_append_idle_hint, "b", 0 }, + { "IdleSinceHint", bus_manager_append_idle_hint_since, "t", 0 }, + { "IdleSinceHintMonotonic", bus_manager_append_idle_hint_since, "t", 0 }, + { NULL, } +}; + +static DBusHandlerResult manager_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *m = userdata; + + DBusError error; + DBusMessage *reply = NULL; + int r; + + assert(connection); + assert(message); + assert(m); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetSession")) { + const char *name; + char *p; + Session *session; + bool b; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(m->sessions, name); + if (!session) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + p = session_bus_path(session); + if (!p) + goto oom; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID); + free(p); + + if (!b) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetSessionByPID")) { + uint32_t pid; + char *p; + Session *session; + bool b; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &pid, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = manager_get_session_by_pid(m, pid, &session); + if (r <= 0) + return bus_send_error_reply(connection, message, NULL, r < 0 ? r : -ENOENT); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + p = session_bus_path(session); + if (!p) + goto oom; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID); + free(p); + + if (!b) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetUser")) { + uint32_t uid; + char *p; + User *user; + bool b; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid)); + if (!user) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + p = user_bus_path(user); + if (!p) + goto oom; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID); + free(p); + + if (!b) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetSeat")) { + const char *name; + char *p; + Seat *seat; + bool b; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + seat = hashmap_get(m->seats, name); + if (!seat) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + p = seat_bus_path(seat); + if (!p) + goto oom; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID); + free(p); + + if (!b) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListSessions")) { + char *p; + Session *session; + Iterator i; + DBusMessageIter iter, sub; + const char *empty = ""; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(susso)", &sub)) + goto oom; + + HASHMAP_FOREACH(session, m->sessions, i) { + DBusMessageIter sub2; + uint32_t uid; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + goto oom; + + uid = session->user->uid; + + p = session_bus_path(session); + if (!p) + goto oom; + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &session->id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &uid) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &session->user->name) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, session->seat ? (const char**) &session->seat->id : &empty) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + goto oom; + } + + free(p); + + if (!dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListUsers")) { + char *p; + User *user; + Iterator i; + DBusMessageIter iter, sub; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(uso)", &sub)) + goto oom; + + HASHMAP_FOREACH(user, m->users, i) { + DBusMessageIter sub2; + uint32_t uid; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + goto oom; + + uid = user->uid; + + p = user_bus_path(user); + if (!p) + goto oom; + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &uid) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &user->name) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + goto oom; + } + + free(p); + + if (!dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListSeats")) { + char *p; + Seat *seat; + Iterator i; + DBusMessageIter iter, sub; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + dbus_message_iter_init_append(reply, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(so)", &sub)) + goto oom; + + HASHMAP_FOREACH(seat, m->seats, i) { + DBusMessageIter sub2; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + goto oom; + + p = seat_bus_path(seat); + if (!p) + goto oom; + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &seat->id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + goto oom; + } + + free(p); + + if (!dbus_message_iter_close_container(&sub, &sub2)) + goto oom; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CreateSession")) { + + r = bus_manager_create_session(m, message, &reply); + + /* Don't delay the work on OOM here, since it might be + * triggered by a low RLIMIT_NOFILE here (since we + * send a dupped fd to the client), and we'd rather + * see this fail quickly then be retried later */ + + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ActivateSession")) { + const char *name; + Session *session; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(m->sessions, name); + if (!session) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = session_activate(session); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ActivateSessionOnSeat")) { + const char *session_name, *seat_name; + Session *session; + Seat *seat; + + /* Same as ActivateSession() but refuses to work if + * the seat doesn't match */ + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &session_name, + DBUS_TYPE_STRING, &seat_name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(m->sessions, session_name); + if (!session) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + seat = hashmap_get(m->seats, seat_name); + if (!seat) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + if (session->seat != seat) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = session_activate(session); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "LockSession") || + dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "UnlockSession")) { + const char *name; + Session *session; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(m->sessions, name); + if (!session) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + if (session_send_lock(session, streq(dbus_message_get_member(message), "LockSession")) < 0) + goto oom; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "KillSession")) { + const char *swho; + int32_t signo; + KillWho who; + const char *name; + Session *session; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &swho, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(swho)) + who = KILL_ALL; + else { + who = kill_who_from_string(swho); + if (who < 0) + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(m->sessions, name); + if (!session) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = session_kill(session, who, signo); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "KillUser")) { + uint32_t uid; + User *user; + int32_t signo; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid)); + if (!user) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = user_kill(user, signo); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateSession")) { + const char *name; + Session *session; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(m->sessions, name); + if (!session) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = session_stop(session); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateUser")) { + uint32_t uid; + User *user; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid)); + if (!user) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = user_stop(user); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateSeat")) { + const char *name; + Seat *seat; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + seat = hashmap_get(m->seats, name); + if (!seat) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = seat_stop_sessions(seat); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "SetUserLinger")) { + uint32_t uid; + struct passwd *pw; + dbus_bool_t b, interactive; + char *path; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + errno = 0; + pw = getpwuid(uid); + if (!pw) + return bus_send_error_reply(connection, message, NULL, errno ? -errno : -EINVAL); + + r = verify_polkit(connection, message, "org.freedesktop.login1.set-user-linger", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + mkdir_p("/var/lib/systemd", 0755); + + r = safe_mkdir("/var/lib/systemd/linger", 0755, 0, 0); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + path = strappend("/var/lib/systemd/linger/", pw->pw_name); + if (!path) + goto oom; + + if (b) { + User *u; + + r = touch(path); + free(path); + + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (manager_add_user_by_uid(m, uid, &u) >= 0) + user_start(u); + + } else { + User *u; + + r = unlink(path); + free(path); + + if (r < 0 && errno != ENOENT) + return bus_send_error_reply(connection, message, &error, -errno); + + u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid)); + if (u) + user_add_to_gc_queue(u); + } + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "AttachDevice")) { + const char *sysfs, *seat; + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &seat, + DBUS_TYPE_STRING, &sysfs, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (!path_startswith(sysfs, "/sys") || !seat_name_is_valid(seat)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + r = verify_polkit(connection, message, "org.freedesktop.login1.attach-device", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + r = attach_device(m, seat, sysfs); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "FlushDevices")) { + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = verify_polkit(connection, message, "org.freedesktop.login1.flush-devices", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + r = flush_devices(m); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "PowerOff") || + dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Reboot")) { + dbus_bool_t interactive; + bool multiple_sessions; + DBusMessage *forward, *freply; + const char *name; + const char *mode = "replace"; + const char *action; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = have_multiple_sessions(connection, m, message, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + multiple_sessions = r > 0; + + if (streq(dbus_message_get_member(message), "PowerOff")) { + if (multiple_sessions) + action = "org.freedesktop.login1.power-off-multiple-sessions"; + else + action = "org.freedesktop.login1.power-off"; + + name = SPECIAL_POWEROFF_TARGET; + } else { + if (multiple_sessions) + action = "org.freedesktop.login1.reboot-multiple-sessions"; + else + action = "org.freedesktop.login1.reboot"; + + name = SPECIAL_REBOOT_TARGET; + } + + r = verify_polkit(connection, message, action, interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + forward = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "StartUnit"); + if (!forward) + return bus_send_error_reply(connection, message, NULL, -ENOMEM); + + if (!dbus_message_append_args(forward, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)) { + dbus_message_unref(forward); + return bus_send_error_reply(connection, message, NULL, -ENOMEM); + } + + freply = dbus_connection_send_with_reply_and_block(connection, forward, -1, &error); + dbus_message_unref(forward); + + if (!freply) + return bus_send_error_reply(connection, message, &error, -EIO); + + dbus_message_unref(freply); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanPowerOff") || + dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanReboot")) { + + bool multiple_sessions, challenge, b; + const char *t, *action; + + r = have_multiple_sessions(connection, m, message, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + multiple_sessions = r > 0; + + if (streq(dbus_message_get_member(message), "CanPowerOff")) { + if (multiple_sessions) + action = "org.freedesktop.login1.power-off-multiple-sessions"; + else + action = "org.freedesktop.login1.power-off"; + + } else { + if (multiple_sessions) + action = "org.freedesktop.login1.reboot-multiple-sessions"; + else + action = "org.freedesktop.login1.reboot"; + } + + r = verify_polkit(connection, message, action, false, &challenge, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + t = r > 0 ? "yes" : + challenge ? "challenge" : + "no"; + + b = dbus_message_append_args( + reply, + DBUS_TYPE_STRING, &t, + DBUS_TYPE_INVALID); + if (!b) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) { + char *introspection = NULL; + FILE *f; + Iterator i; + Session *session; + Seat *seat; + User *user; + size_t size; + char *p; + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + /* We roll our own introspection code here, instead of + * relying on bus_default_message_handler() because we + * need to generate our introspection string + * dynamically. */ + + if (!(f = open_memstream(&introspection, &size))) + goto oom; + + fputs(INTROSPECTION_BEGIN, f); + + HASHMAP_FOREACH(seat, m->seats, i) { + p = bus_path_escape(seat->id); + + if (p) { + fprintf(f, "", p); + free(p); + } + } + + HASHMAP_FOREACH(user, m->users, i) + fprintf(f, "", (unsigned long long) user->uid); + + HASHMAP_FOREACH(session, m->sessions, i) { + p = bus_path_escape(session->id); + + if (p) { + fprintf(f, "", p); + free(p); + } + } + + fputs(INTROSPECTION_END, f); + + if (ferror(f)) { + fclose(f); + free(introspection); + goto oom; + } + + fclose(f); + + if (!introspection) + goto oom; + + if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) { + free(introspection); + goto oom; + } + + free(introspection); + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.login1.Manager", bus_login_manager_properties, m }, + { NULL, } + }; + return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, bps); + } + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +const DBusObjectPathVTable bus_manager_vtable = { + .message_function = manager_message_handler +}; + +DBusHandlerResult bus_message_filter( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *m = userdata; + DBusError error; + + assert(m); + assert(connection); + assert(message); + + dbus_error_init(&error); + + if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) { + const char *cgroup; + + if (!dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &cgroup, + DBUS_TYPE_INVALID)) + log_error("Failed to parse Released message: %s", bus_error_message(&error)); + else + manager_cgroup_notify_empty(m, cgroup); + } + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +int manager_send_changed(Manager *manager, const char *properties) { + DBusMessage *m; + int r = -ENOMEM; + + assert(manager); + + m = bus_properties_changed_new("/org/freedesktop/login1", "org.freedesktop.login1.Manager", properties); + if (!m) + goto finish; + + if (!dbus_connection_send(manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + return r; +} diff --git a/src/login/logind-device.c b/src/login/logind-device.c new file mode 100644 index 0000000..bbd370f --- /dev/null +++ b/src/login/logind-device.c @@ -0,0 +1,86 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "logind-device.h" +#include "util.h" + +Device* device_new(Manager *m, const char *sysfs) { + Device *d; + + assert(m); + assert(sysfs); + + d = new0(Device, 1); + if (!d) + return NULL; + + d->sysfs = strdup(sysfs); + if (!d->sysfs) { + free(d); + return NULL; + } + + if (hashmap_put(m->devices, d->sysfs, d) < 0) { + free(d->sysfs); + free(d); + return NULL; + } + + d->manager = m; + dual_timestamp_get(&d->timestamp); + + return d; +} + +void device_free(Device *d) { + assert(d); + + device_detach(d); + + hashmap_remove(d->manager->devices, d->sysfs); + + free(d->sysfs); + free(d); +} + +void device_detach(Device *d) { + assert(d); + + if (d->seat) + LIST_REMOVE(Device, devices, d->seat->devices, d); + + seat_add_to_gc_queue(d->seat); + d->seat = NULL; +} + +void device_attach(Device *d, Seat *s) { + assert(d); + assert(s); + + if (d->seat) + device_detach(d); + + d->seat = s; + LIST_PREPEND(Device, devices, s->devices, d); +} diff --git a/src/login/logind-device.h b/src/login/logind-device.h new file mode 100644 index 0000000..e25a534 --- /dev/null +++ b/src/login/logind-device.h @@ -0,0 +1,48 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foologinddevicehfoo +#define foologinddevicehfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct Device Device; + +#include "list.h" +#include "util.h" +#include "logind.h" +#include "logind-seat.h" + +struct Device { + Manager *manager; + + char *sysfs; + Seat *seat; + + dual_timestamp timestamp; + + LIST_FIELDS(struct Device, devices); +}; + +Device* device_new(Manager *m, const char *sysfs); +void device_free(Device *d); +void device_attach(Device *d, Seat *s); +void device_detach(Device *d); + +#endif diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf new file mode 100644 index 0000000..940fe10 --- /dev/null +++ b/src/login/logind-gperf.gperf @@ -0,0 +1,22 @@ +%{ +#include +#include "conf-parser.h" +#include "logind.h" +%} +struct ConfigPerfItem; +%null_strings +%language=ANSI-C +%define slot-name section_and_lvalue +%define hash-function-name logind_gperf_hash +%define lookup-function-name logind_gperf_lookup +%readonly-tables +%omit-struct-type +%struct-type +%includes +%% +Login.NAutoVTs, config_parse_unsigned, 0, offsetof(Manager, n_autovts) +Login.KillUserProcesses, config_parse_bool, 0, offsetof(Manager, kill_user_processes) +Login.KillOnlyUsers, config_parse_strv, 0, offsetof(Manager, kill_only_users) +Login.KillExcludeUsers, config_parse_strv, 0, offsetof(Manager, kill_exclude_users) +Login.Controllers, config_parse_strv, 0, offsetof(Manager, controllers) +Login.ResetControllers, config_parse_strv, 0, offsetof(Manager, reset_controllers) diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c new file mode 100644 index 0000000..95ef5ff --- /dev/null +++ b/src/login/logind-seat-dbus.c @@ -0,0 +1,408 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "logind.h" +#include "logind-seat.h" +#include "dbus-common.h" +#include "util.h" + +#define BUS_SEAT_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_SEAT_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.login1.Seat\0" + +static int bus_seat_append_active(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub; + Seat *s = data; + const char *id, *path; + char *p = NULL; + + assert(i); + assert(property); + assert(s); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) + return -ENOMEM; + + if (s->active) { + id = s->active->id; + path = p = session_bus_path(s->active); + + if (!p) + return -ENOMEM; + } else { + id = ""; + path = "/"; + } + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &path)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_seat_append_sessions(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub, sub2; + Seat *s = data; + Session *session; + + assert(i); + assert(property); + assert(s); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(so)", &sub)) + return -ENOMEM; + + LIST_FOREACH(sessions_by_seat, session, s->sessions) { + char *p; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + return -ENOMEM; + + p = session_bus_path(session); + if (!p) + return -ENOMEM; + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &session->id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(&sub, &sub2)) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_seat_append_multi_session(DBusMessageIter *i, const char *property, void *data) { + Seat *s = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(s); + + b = seat_can_multi_session(s); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_seat_append_idle_hint(DBusMessageIter *i, const char *property, void *data) { + Seat *s = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(s); + + b = seat_get_idle_hint(s, NULL) > 0; + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_seat_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) { + Seat *s = data; + dual_timestamp t; + uint64_t k; + + assert(i); + assert(property); + assert(s); + + seat_get_idle_hint(s, &t); + k = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &k)) + return -ENOMEM; + + return 0; +} + +static int get_seat_for_path(Manager *m, const char *path, Seat **_s) { + Seat *s; + char *id; + + assert(m); + assert(path); + assert(_s); + + if (!startswith(path, "/org/freedesktop/login1/seat/")) + return -EINVAL; + + id = bus_path_unescape(path + 29); + if (!id) + return -ENOMEM; + + s = hashmap_get(m->seats, id); + free(id); + + if (!s) + return -ENOENT; + + *_s = s; + return 0; +} + +static const BusProperty bus_login_seat_properties[] = { + { "Id", bus_property_append_string, "s", offsetof(Seat, id), true }, + { "ActiveSession", bus_seat_append_active, "(so)", 0 }, + { "CanMultiSession", bus_seat_append_multi_session, "b", 0 }, + { "Sessions", bus_seat_append_sessions, "a(so)", 0 }, + { "IdleHint", bus_seat_append_idle_hint, "b", 0 }, + { "IdleSinceHint", bus_seat_append_idle_hint_since, "t", 0 }, + { "IdleSinceHintMonotonic", bus_seat_append_idle_hint_since, "t", 0 }, + { NULL, } +}; + +static DBusHandlerResult seat_message_dispatch( + Seat *s, + DBusConnection *connection, + DBusMessage *message) { + + DBusError error; + DBusMessage *reply = NULL; + int r; + + assert(s); + assert(connection); + assert(message); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.login1.Seat", "Terminate")) { + + r = seat_stop_sessions(s); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Seat", "ActivateSession")) { + const char *name; + Session *session; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + session = hashmap_get(s->manager->sessions, name); + if (!session || session->seat != s) + return bus_send_error_reply(connection, message, &error, -ENOENT); + + r = session_activate(session); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.login1.Seat", bus_login_seat_properties, s }, + { NULL, } + }; + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + } + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult seat_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *m = userdata; + Seat *s; + int r; + + r = get_seat_for_path(m, dbus_message_get_path(message), &s); + if (r < 0) { + + if (r == -ENOMEM) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (r == -ENOENT) { + DBusError e; + + dbus_error_init(&e); + dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown seat"); + return bus_send_error_reply(connection, message, &e, r); + } + + return bus_send_error_reply(connection, message, NULL, r); + } + + return seat_message_dispatch(s, connection, message); +} + +const DBusObjectPathVTable bus_seat_vtable = { + .message_function = seat_message_handler +}; + +char *seat_bus_path(Seat *s) { + char *t, *r; + + assert(s); + + t = bus_path_escape(s->id); + if (!t) + return NULL; + + r = strappend("/org/freedesktop/login1/seat/", t); + free(t); + + return r; +} + +int seat_send_signal(Seat *s, bool new_seat) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(s); + + m = dbus_message_new_signal("/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + new_seat ? "SeatNew" : "SeatRemoved"); + + if (!m) + return -ENOMEM; + + p = seat_bus_path(s); + if (!p) + goto finish; + + if (!dbus_message_append_args( + m, + DBUS_TYPE_STRING, &s->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + goto finish; + + if (!dbus_connection_send(s->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + dbus_message_unref(m); + free(p); + + return r; +} + +int seat_send_changed(Seat *s, const char *properties) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(s); + + if (!s->started) + return 0; + + p = seat_bus_path(s); + if (!p) + return -ENOMEM; + + m = bus_properties_changed_new(p, "org.freedesktop.login1.Seat", properties); + if (!m) + goto finish; + + if (!dbus_connection_send(s->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + free(p); + + return r; +} diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c new file mode 100644 index 0000000..be37c1c --- /dev/null +++ b/src/login/logind-seat.c @@ -0,0 +1,514 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "logind-seat.h" +#include "logind-acl.h" +#include "util.h" + +Seat *seat_new(Manager *m, const char *id) { + Seat *s; + + assert(m); + assert(id); + + s = new0(Seat, 1); + if (!s) + return NULL; + + s->state_file = strappend("/run/systemd/seats/", id); + if (!s->state_file) { + free(s); + return NULL; + } + + s->id = file_name_from_path(s->state_file); + s->manager = m; + + if (hashmap_put(m->seats, s->id, s) < 0) { + free(s->state_file); + free(s); + return NULL; + } + + return s; +} + +void seat_free(Seat *s) { + assert(s); + + if (s->in_gc_queue) + LIST_REMOVE(Seat, gc_queue, s->manager->seat_gc_queue, s); + + while (s->sessions) + session_free(s->sessions); + + assert(!s->active); + + while (s->devices) + device_free(s->devices); + + hashmap_remove(s->manager->seats, s->id); + + free(s->state_file); + free(s); +} + +int seat_save(Seat *s) { + int r; + FILE *f; + char *temp_path; + + assert(s); + + if (!s->started) + return 0; + + r = safe_mkdir("/run/systemd/seats", 0755, 0, 0); + if (r < 0) + goto finish; + + r = fopen_temporary(s->state_file, &f, &temp_path); + if (r < 0) + goto finish; + + fchmod(fileno(f), 0644); + + fprintf(f, + "# This is private data. Do not parse.\n" + "IS_VTCONSOLE=%i\n" + "CAN_MULTI_SESSION=%i\n", + seat_is_vtconsole(s), + seat_can_multi_session(s)); + + if (s->active) { + assert(s->active->user); + + fprintf(f, + "ACTIVE=%s\n" + "ACTIVE_UID=%lu\n", + s->active->id, + (unsigned long) s->active->user->uid); + } + + if (s->sessions) { + Session *i; + + fputs("SESSIONS=", f); + LIST_FOREACH(sessions_by_seat, i, s->sessions) { + fprintf(f, + "%s%c", + i->id, + i->sessions_by_seat_next ? ' ' : '\n'); + } + + fputs("UIDS=", f); + LIST_FOREACH(sessions_by_seat, i, s->sessions) + fprintf(f, + "%lu%c", + (unsigned long) i->user->uid, + i->sessions_by_seat_next ? ' ' : '\n'); + } + + fflush(f); + + if (ferror(f) || rename(temp_path, s->state_file) < 0) { + r = -errno; + unlink(s->state_file); + unlink(temp_path); + } + + fclose(f); + free(temp_path); + +finish: + if (r < 0) + log_error("Failed to save seat data for %s: %s", s->id, strerror(-r)); + + return r; +} + +int seat_load(Seat *s) { + assert(s); + + /* There isn't actually anything to read here ... */ + + return 0; +} + +static int vt_allocate(int vtnr) { + int fd, r; + char *p; + + assert(vtnr >= 1); + + if (asprintf(&p, "/dev/tty%i", vtnr) < 0) + return -ENOMEM; + + fd = open_terminal(p, O_RDWR|O_NOCTTY|O_CLOEXEC); + free(p); + + r = fd < 0 ? -errno : 0; + + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +int seat_preallocate_vts(Seat *s) { + int r = 0; + unsigned i; + + assert(s); + assert(s->manager); + + log_debug("Preallocating VTs..."); + + if (s->manager->n_autovts <= 0) + return 0; + + if (!seat_can_multi_session(s)) + return 0; + + for (i = 1; i <= s->manager->n_autovts; i++) { + int q; + + q = vt_allocate(i); + if (q < 0) { + log_error("Failed to preallocate VT %i: %s", i, strerror(-q)); + r = q; + } + } + + return r; +} + +int seat_apply_acls(Seat *s, Session *old_active) { + int r; + + assert(s); + + r = devnode_acl_all(s->manager->udev, + s->id, + false, + !!old_active, old_active ? old_active->user->uid : 0, + !!s->active, s->active ? s->active->user->uid : 0); + + if (r < 0) + log_error("Failed to apply ACLs: %s", strerror(-r)); + + return r; +} + +int seat_set_active(Seat *s, Session *session) { + Session *old_active; + + assert(s); + assert(!session || session->seat == s); + + if (session == s->active) + return 0; + + old_active = s->active; + s->active = session; + + seat_apply_acls(s, old_active); + + if (session && session->started) + session_send_changed(session, "Active\0"); + + if (!session || session->started) + seat_send_changed(s, "ActiveSession\0"); + + seat_save(s); + + if (session) { + session_save(session); + user_save(session->user); + } + + if (old_active) { + session_save(old_active); + user_save(old_active->user); + } + + return 0; +} + +int seat_active_vt_changed(Seat *s, int vtnr) { + Session *i, *new_active = NULL; + int r; + + assert(s); + assert(vtnr >= 1); + + if (!seat_can_multi_session(s)) + return -EINVAL; + + log_debug("VT changed to %i", vtnr); + + LIST_FOREACH(sessions_by_seat, i, s->sessions) + if (i->vtnr == vtnr) { + new_active = i; + break; + } + + r = seat_set_active(s, new_active); + manager_spawn_autovt(s->manager, vtnr); + + return r; +} + +int seat_read_active_vt(Seat *s) { + char t[64]; + ssize_t k; + int r, vtnr; + + assert(s); + + if (!seat_can_multi_session(s)) + return 0; + + lseek(s->manager->console_active_fd, SEEK_SET, 0); + + k = read(s->manager->console_active_fd, t, sizeof(t)-1); + if (k <= 0) { + log_error("Failed to read current console: %s", k < 0 ? strerror(-errno) : "EOF"); + return k < 0 ? -errno : -EIO; + } + + t[k] = 0; + truncate_nl(t); + + if (!startswith(t, "tty")) { + log_error("Hm, /sys/class/tty/tty0/active is badly formatted."); + return -EIO; + } + + r = safe_atoi(t+3, &vtnr); + if (r < 0) { + log_error("Failed to parse VT number %s", t+3); + return r; + } + + if (vtnr <= 0) { + log_error("VT number invalid: %s", t+3); + return -EIO; + } + + return seat_active_vt_changed(s, vtnr); +} + +int seat_start(Seat *s) { + assert(s); + + if (s->started) + return 0; + + log_info("New seat %s.", s->id); + + /* Initialize VT magic stuff */ + seat_preallocate_vts(s); + + /* Read current VT */ + seat_read_active_vt(s); + + s->started = true; + + /* Save seat data */ + seat_save(s); + + seat_send_signal(s, true); + + return 0; +} + +int seat_stop(Seat *s) { + int r = 0; + + assert(s); + + if (s->started) + log_info("Removed seat %s.", s->id); + + seat_stop_sessions(s); + + unlink(s->state_file); + seat_add_to_gc_queue(s); + + if (s->started) + seat_send_signal(s, false); + + s->started = false; + + return r; +} + +int seat_stop_sessions(Seat *s) { + Session *session; + int r = 0, k; + + assert(s); + + LIST_FOREACH(sessions_by_seat, session, s->sessions) { + k = session_stop(session); + if (k < 0) + r = k; + } + + return r; +} + +int seat_attach_session(Seat *s, Session *session) { + assert(s); + assert(session); + assert(!session->seat); + + session->seat = s; + LIST_PREPEND(Session, sessions_by_seat, s->sessions, session); + + seat_send_changed(s, "Sessions\0"); + + /* Note that even if a seat is not multi-session capable it + * still might have multiple sessions on it since old, dead + * sessions might continue to be tracked until all their + * processes are gone. The most recently added session + * (i.e. the first in s->sessions) is the one that matters. */ + + if (!seat_can_multi_session(s)) + seat_set_active(s, session); + + return 0; +} + +bool seat_is_vtconsole(Seat *s) { + assert(s); + + return s->manager->vtconsole == s; +} + +bool seat_can_multi_session(Seat *s) { + assert(s); + + if (!seat_is_vtconsole(s)) + return false; + + /* If we can't watch which VT is in the foreground, we don't + * support VT switching */ + + return s->manager->console_active_fd >= 0; +} + +int seat_get_idle_hint(Seat *s, dual_timestamp *t) { + Session *session; + bool idle_hint = true; + dual_timestamp ts = { 0, 0 }; + + assert(s); + + LIST_FOREACH(sessions_by_seat, session, s->sessions) { + dual_timestamp k; + int ih; + + ih = session_get_idle_hint(session, &k); + if (ih < 0) + return ih; + + if (!ih) { + if (!idle_hint) { + if (k.monotonic < ts.monotonic) + ts = k; + } else { + idle_hint = false; + ts = k; + } + } else if (idle_hint) { + + if (k.monotonic > ts.monotonic) + ts = k; + } + } + + if (t) + *t = ts; + + return idle_hint; +} + +int seat_check_gc(Seat *s, bool drop_not_started) { + assert(s); + + if (drop_not_started && !s->started) + return 0; + + if (seat_is_vtconsole(s)) + return 1; + + return !!s->devices; +} + +void seat_add_to_gc_queue(Seat *s) { + assert(s); + + if (s->in_gc_queue) + return; + + LIST_PREPEND(Seat, gc_queue, s->manager->seat_gc_queue, s); + s->in_gc_queue = true; +} + +static bool seat_name_valid_char(char c) { + return + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '-' || + c == '_'; +} + +bool seat_name_is_valid(const char *name) { + const char *p; + + assert(name); + + if (!startswith(name, "seat")) + return false; + + if (!name[4]) + return false; + + for (p = name; *p; p++) + if (!seat_name_valid_char(*p)) + return false; + + if (strlen(name) > 255) + return false; + + return true; +} diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h new file mode 100644 index 0000000..3b2c7f0 --- /dev/null +++ b/src/login/logind-seat.h @@ -0,0 +1,83 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foologindseathfoo +#define foologindseathfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct Seat Seat; + +#include "list.h" +#include "util.h" +#include "logind.h" +#include "logind-device.h" +#include "logind-session.h" + +struct Seat { + Manager *manager; + char *id; + + char *state_file; + + LIST_HEAD(Device, devices); + + Session *active; + LIST_HEAD(Session, sessions); + + bool in_gc_queue:1; + bool started:1; + + LIST_FIELDS(Seat, gc_queue); +}; + +Seat *seat_new(Manager *m, const char *id); +void seat_free(Seat *s); + +int seat_save(Seat *s); +int seat_load(Seat *s); + +int seat_apply_acls(Seat *s, Session *old_active); +int seat_set_active(Seat *s, Session *session); +int seat_active_vt_changed(Seat *s, int vtnr); +int seat_read_active_vt(Seat *s); +int seat_preallocate_vts(Seat *s); + +int seat_attach_session(Seat *s, Session *session); + +bool seat_is_vtconsole(Seat *s); +bool seat_can_multi_session(Seat *s); +int seat_get_idle_hint(Seat *s, dual_timestamp *t); + +int seat_start(Seat *s); +int seat_stop(Seat *s); +int seat_stop_sessions(Seat *s); + +int seat_check_gc(Seat *s, bool drop_not_started); +void seat_add_to_gc_queue(Seat *s); + +bool seat_name_is_valid(const char *name); +char *seat_bus_path(Seat *s); + +extern const DBusObjectPathVTable bus_seat_vtable; + +int seat_send_signal(Seat *s, bool new_seat); +int seat_send_changed(Seat *s, const char *properties); + +#endif diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c new file mode 100644 index 0000000..102f8ac --- /dev/null +++ b/src/login/logind-session-dbus.c @@ -0,0 +1,528 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "logind.h" +#include "logind-session.h" +#include "dbus-common.h" +#include "util.h" + +#define BUS_SESSION_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_SESSION_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.login1.Session\0" + +static int bus_session_append_seat(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub; + Session *s = data; + const char *id, *path; + char *p = NULL; + + assert(i); + assert(property); + assert(s); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) + return -ENOMEM; + + if (s->seat) { + id = s->seat->id; + path = p = seat_bus_path(s->seat); + + if (!p) + return -ENOMEM; + } else { + id = ""; + path = "/"; + } + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &path)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_session_append_user(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub; + User *u = data; + char *p = NULL; + + assert(i); + assert(property); + assert(u); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) + return -ENOMEM; + + p = user_bus_path(u); + if (!p) + return -ENOMEM; + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_UINT32, &u->uid) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_session_append_active(DBusMessageIter *i, const char *property, void *data) { + Session *s = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(s); + + b = session_is_active(s); + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_session_append_idle_hint(DBusMessageIter *i, const char *property, void *data) { + Session *s = data; + int b; + + assert(i); + assert(property); + assert(s); + + b = session_get_idle_hint(s, NULL) > 0; + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_session_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) { + Session *s = data; + dual_timestamp t; + uint64_t u; + + assert(i); + assert(property); + assert(s); + + session_get_idle_hint(s, &t); + u = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u)) + return -ENOMEM; + + return 0; +} + +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_type, session_type, SessionType); +static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_class, session_class, SessionClass); + +static int get_session_for_path(Manager *m, const char *path, Session **_s) { + Session *s; + char *id; + + assert(m); + assert(path); + assert(_s); + + if (!startswith(path, "/org/freedesktop/login1/session/")) + return -EINVAL; + + id = bus_path_unescape(path + 32); + if (!id) + return -ENOMEM; + + s = hashmap_get(m->sessions, id); + free(id); + + if (!s) + return -ENOENT; + + *_s = s; + return 0; +} + +static const BusProperty bus_login_session_properties[] = { + { "Id", bus_property_append_string, "s", offsetof(Session, id), true }, + { "Timestamp", bus_property_append_usec, "t", offsetof(Session, timestamp.realtime) }, + { "TimestampMonotonic", bus_property_append_usec, "t", offsetof(Session, timestamp.monotonic) }, + { "ControlGroupPath", bus_property_append_string, "s", offsetof(Session, cgroup_path), true }, + { "VTNr", bus_property_append_uint32, "u", offsetof(Session, vtnr) }, + { "Seat", bus_session_append_seat, "(so)", 0 }, + { "TTY", bus_property_append_string, "s", offsetof(Session, tty), true }, + { "Display", bus_property_append_string, "s", offsetof(Session, display), true }, + { "Remote", bus_property_append_bool, "b", offsetof(Session, remote) }, + { "RemoteUser", bus_property_append_string, "s", offsetof(Session, remote_user), true }, + { "RemoteHost", bus_property_append_string, "s", offsetof(Session, remote_host), true }, + { "Service", bus_property_append_string, "s", offsetof(Session, service), true }, + { "Leader", bus_property_append_pid, "u", offsetof(Session, leader) }, + { "Audit", bus_property_append_uint32, "u", offsetof(Session, audit_id) }, + { "Type", bus_session_append_type, "s", offsetof(Session, type) }, + { "Class", bus_session_append_class, "s", offsetof(Session, class) }, + { "Active", bus_session_append_active, "b", 0 }, + { "Controllers", bus_property_append_strv, "as", offsetof(Session, controllers), true }, + { "ResetControllers", bus_property_append_strv, "as", offsetof(Session, reset_controllers), true }, + { "KillProcesses", bus_property_append_bool, "b", offsetof(Session, kill_processes) }, + { "IdleHint", bus_session_append_idle_hint, "b", 0 }, + { "IdleSinceHint", bus_session_append_idle_hint_since, "t", 0 }, + { "IdleSinceHintMonotonic", bus_session_append_idle_hint_since, "t", 0 }, + { NULL, } +}; + +static const BusProperty bus_login_session_user_properties[] = { + { "User", bus_session_append_user, "(uo)", 0 }, + { "Name", bus_property_append_string, "s", offsetof(User, name), true }, + { NULL, } +}; + +static DBusHandlerResult session_message_dispatch( + Session *s, + DBusConnection *connection, + DBusMessage *message) { + + DBusError error; + DBusMessage *reply = NULL; + int r; + + assert(s); + assert(connection); + assert(message); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Terminate")) { + + r = session_stop(s); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Activate")) { + + r = session_activate(s); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Lock") || + dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Unlock")) { + + if (session_send_lock(s, streq(dbus_message_get_member(message), "Lock")) < 0) + goto oom; + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "SetIdleHint")) { + dbus_bool_t b; + unsigned long ul; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), &error); + if (ul == (unsigned long) -1) + return bus_send_error_reply(connection, message, &error, -EIO); + + if (ul != 0 && ul != s->user->uid) + return bus_send_error_reply(connection, message, NULL, -EPERM); + + session_set_idle_hint(s, b); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Kill")) { + const char *swho; + int32_t signo; + KillWho who; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &swho, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (isempty(swho)) + who = KILL_ALL; + else { + who = kill_who_from_string(swho); + if (who < 0) + return bus_send_error_reply(connection, message, &error, -EINVAL); + } + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = session_kill(s, who, signo); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.login1.Session", bus_login_session_properties, s }, + { "org.freedesktop.login1.Session", bus_login_session_user_properties, s->user }, + { NULL, } + }; + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + } + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult session_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *m = userdata; + Session *s; + int r; + + r = get_session_for_path(m, dbus_message_get_path(message), &s); + if (r < 0) { + + if (r == -ENOMEM) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (r == -ENOENT) { + DBusError e; + + dbus_error_init(&e); + dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown session"); + return bus_send_error_reply(connection, message, &e, r); + } + + return bus_send_error_reply(connection, message, NULL, r); + } + + return session_message_dispatch(s, connection, message); +} + +const DBusObjectPathVTable bus_session_vtable = { + .message_function = session_message_handler +}; + +char *session_bus_path(Session *s) { + char *t, *r; + + assert(s); + + t = bus_path_escape(s->id); + if (!t) + return NULL; + + r = strappend("/org/freedesktop/login1/session/", t); + free(t); + + return r; +} + +int session_send_signal(Session *s, bool new_session) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(s); + + m = dbus_message_new_signal("/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + new_session ? "SessionNew" : "SessionRemoved"); + + if (!m) + return -ENOMEM; + + p = session_bus_path(s); + if (!p) + goto finish; + + if (!dbus_message_append_args( + m, + DBUS_TYPE_STRING, &s->id, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + goto finish; + + if (!dbus_connection_send(s->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + dbus_message_unref(m); + free(p); + + return r; +} + +int session_send_changed(Session *s, const char *properties) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(s); + + if (!s->started) + return 0; + + p = session_bus_path(s); + if (!p) + return -ENOMEM; + + m = bus_properties_changed_new(p, "org.freedesktop.login1.Session", properties); + if (!m) + goto finish; + + if (!dbus_connection_send(s->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + free(p); + + return r; +} + +int session_send_lock(Session *s, bool lock) { + DBusMessage *m; + bool b; + char *p; + + assert(s); + + p = session_bus_path(s); + if (!p) + return -ENOMEM; + + m = dbus_message_new_signal(p, "org.freedesktop.login1.Session", lock ? "Lock" : "Unlock"); + free(p); + + if (!m) + return -ENOMEM; + + b = dbus_connection_send(s->manager->bus, m, NULL); + dbus_message_unref(m); + + if (!b) + return -ENOMEM; + + return 0; +} diff --git a/src/login/logind-session.c b/src/login/logind-session.c new file mode 100644 index 0000000..af9c12d --- /dev/null +++ b/src/login/logind-session.c @@ -0,0 +1,978 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "logind-session.h" +#include "strv.h" +#include "util.h" +#include "cgroup-util.h" + +#define IDLE_THRESHOLD_USEC (5*USEC_PER_MINUTE) + +Session* session_new(Manager *m, User *u, const char *id) { + Session *s; + + assert(m); + assert(id); + + s = new0(Session, 1); + if (!s) + return NULL; + + s->state_file = strappend("/run/systemd/sessions/", id); + if (!s->state_file) { + free(s); + return NULL; + } + + s->id = file_name_from_path(s->state_file); + + if (hashmap_put(m->sessions, s->id, s) < 0) { + free(s->id); + free(s); + return NULL; + } + + s->manager = m; + s->fifo_fd = -1; + s->user = u; + + LIST_PREPEND(Session, sessions_by_user, u->sessions, s); + + return s; +} + +void session_free(Session *s) { + assert(s); + + if (s->in_gc_queue) + LIST_REMOVE(Session, gc_queue, s->manager->session_gc_queue, s); + + if (s->user) { + LIST_REMOVE(Session, sessions_by_user, s->user->sessions, s); + + if (s->user->display == s) + s->user->display = NULL; + } + + if (s->seat) { + if (s->seat->active == s) + s->seat->active = NULL; + + LIST_REMOVE(Session, sessions_by_seat, s->seat->sessions, s); + } + + if (s->cgroup_path) + hashmap_remove(s->manager->cgroups, s->cgroup_path); + + free(s->cgroup_path); + strv_free(s->controllers); + + free(s->tty); + free(s->display); + free(s->remote_host); + free(s->remote_user); + free(s->service); + + hashmap_remove(s->manager->sessions, s->id); + + session_remove_fifo(s); + + free(s->state_file); + free(s); +} + +int session_save(Session *s) { + FILE *f; + int r = 0; + char *temp_path; + + assert(s); + + if (!s->started) + return 0; + + r = safe_mkdir("/run/systemd/sessions", 0755, 0, 0); + if (r < 0) + goto finish; + + r = fopen_temporary(s->state_file, &f, &temp_path); + if (r < 0) + goto finish; + + assert(s->user); + + fchmod(fileno(f), 0644); + + fprintf(f, + "# This is private data. Do not parse.\n" + "UID=%lu\n" + "USER=%s\n" + "ACTIVE=%i\n" + "REMOTE=%i\n" + "KILL_PROCESSES=%i\n", + (unsigned long) s->user->uid, + s->user->name, + session_is_active(s), + s->remote, + s->kill_processes); + + if (s->type >= 0) + fprintf(f, + "TYPE=%s\n", + session_type_to_string(s->type)); + + if (s->class >= 0) + fprintf(f, + "CLASS=%s\n", + session_class_to_string(s->class)); + + if (s->cgroup_path) + fprintf(f, + "CGROUP=%s\n", + s->cgroup_path); + + if (s->fifo_path) + fprintf(f, + "FIFO=%s\n", + s->fifo_path); + + if (s->seat) + fprintf(f, + "SEAT=%s\n", + s->seat->id); + + if (s->tty) + fprintf(f, + "TTY=%s\n", + s->tty); + + if (s->display) + fprintf(f, + "DISPLAY=%s\n", + s->display); + + if (s->remote_host) + fprintf(f, + "REMOTE_HOST=%s\n", + s->remote_host); + + if (s->remote_user) + fprintf(f, + "REMOTE_USER=%s\n", + s->remote_user); + + if (s->service) + fprintf(f, + "SERVICE=%s\n", + s->service); + + if (s->seat && seat_can_multi_session(s->seat)) + fprintf(f, + "VTNR=%i\n", + s->vtnr); + + if (s->leader > 0) + fprintf(f, + "LEADER=%lu\n", + (unsigned long) s->leader); + + if (s->audit_id > 0) + fprintf(f, + "AUDIT=%llu\n", + (unsigned long long) s->audit_id); + + fflush(f); + + if (ferror(f) || rename(temp_path, s->state_file) < 0) { + r = -errno; + unlink(s->state_file); + unlink(temp_path); + } + + fclose(f); + free(temp_path); + +finish: + if (r < 0) + log_error("Failed to save session data for %s: %s", s->id, strerror(-r)); + + return r; +} + +int session_load(Session *s) { + char *remote = NULL, + *kill_processes = NULL, + *seat = NULL, + *vtnr = NULL, + *leader = NULL, + *audit_id = NULL, + *type = NULL, + *class = NULL; + + int k, r; + + assert(s); + + r = parse_env_file(s->state_file, NEWLINE, + "REMOTE", &remote, + "KILL_PROCESSES", &kill_processes, + "CGROUP", &s->cgroup_path, + "FIFO", &s->fifo_path, + "SEAT", &seat, + "TTY", &s->tty, + "DISPLAY", &s->display, + "REMOTE_HOST", &s->remote_host, + "REMOTE_USER", &s->remote_user, + "SERVICE", &s->service, + "VTNR", &vtnr, + "LEADER", &leader, + "TYPE", &type, + "CLASS", &class, + NULL); + + if (r < 0) + goto finish; + + if (remote) { + k = parse_boolean(remote); + if (k >= 0) + s->remote = k; + } + + if (kill_processes) { + k = parse_boolean(kill_processes); + if (k >= 0) + s->kill_processes = k; + } + + if (seat && !s->seat) { + Seat *o; + + o = hashmap_get(s->manager->seats, seat); + if (o) + seat_attach_session(o, s); + } + + if (vtnr && s->seat && seat_can_multi_session(s->seat)) { + int v; + + k = safe_atoi(vtnr, &v); + if (k >= 0 && v >= 1) + s->vtnr = v; + } + + if (leader) { + pid_t pid; + + k = parse_pid(leader, &pid); + if (k >= 0 && pid >= 1) { + s->leader = pid; + + audit_session_from_pid(pid, &s->audit_id); + } + } + + if (type) { + SessionType t; + + t = session_type_from_string(type); + if (t >= 0) + s->type = t; + } + + if (class) { + SessionClass c; + + c = session_class_from_string(class); + if (c >= 0) + s->class = c; + } + + if (s->fifo_path) { + int fd; + + /* If we open an unopened pipe for reading we will not + get an EOF. to trigger an EOF we hence open it for + reading, but close it right-away which then will + trigger the EOF. */ + + fd = session_create_fifo(s); + if (fd >= 0) + close_nointr_nofail(fd); + } + + +finish: + free(remote); + free(kill_processes); + free(seat); + free(vtnr); + free(leader); + free(audit_id); + + return r; +} + +int session_activate(Session *s) { + int r; + + assert(s); + + if (s->vtnr < 0) + return -ENOTSUP; + + if (!s->seat) + return -ENOTSUP; + + if (s->seat->active == s) + return 0; + + assert(seat_is_vtconsole(s->seat)); + + r = chvt(s->vtnr); + if (r < 0) + return r; + + return seat_set_active(s->seat, s); +} + +static int session_link_x11_socket(Session *s) { + char *t, *f, *c; + size_t k; + + assert(s); + assert(s->user); + assert(s->user->runtime_path); + + if (s->user->display) + return 0; + + if (!s->display || !display_is_local(s->display)) + return 0; + + k = strspn(s->display+1, "0123456789"); + f = new(char, sizeof("/tmp/.X11-unix/X") + k); + if (!f) { + log_error("Out of memory"); + return -ENOMEM; + } + + c = stpcpy(f, "/tmp/.X11-unix/X"); + memcpy(c, s->display+1, k); + c[k] = 0; + + if (access(f, F_OK) < 0) { + log_warning("Session %s has display %s with nonexisting socket %s.", s->id, s->display, f); + free(f); + return -ENOENT; + } + + t = strappend(s->user->runtime_path, "/X11-display"); + if (!t) { + log_error("Out of memory"); + free(f); + return -ENOMEM; + } + + if (link(f, t) < 0) { + if (errno == EEXIST) { + unlink(t); + + if (link(f, t) >= 0) + goto done; + } + + if (symlink(f, t) < 0) { + + if (errno == EEXIST) { + unlink(t); + + if (symlink(f, t) >= 0) + goto done; + } + + log_error("Failed to link %s to %s: %m", f, t); + free(f); + free(t); + return -errno; + } + } + +done: + log_info("Linked %s to %s.", f, t); + free(f); + free(t); + + s->user->display = s; + + return 0; +} + +static int session_create_one_group(Session *s, const char *controller, const char *path) { + int r; + + assert(s); + assert(controller); + assert(path); + + if (s->leader > 0) { + r = cg_create_and_attach(controller, path, s->leader); + if (r < 0) + r = cg_create(controller, path); + } else + r = cg_create(controller, path); + + if (r < 0) + return r; + + r = cg_set_task_access(controller, path, 0644, s->user->uid, s->user->gid, -1); + if (r >= 0) + r = cg_set_group_access(controller, path, 0755, s->user->uid, s->user->gid); + + return r; +} + +static int session_create_cgroup(Session *s) { + char **k; + char *p; + int r; + + assert(s); + assert(s->user); + assert(s->user->cgroup_path); + + if (!s->cgroup_path) { + if (asprintf(&p, "%s/%s", s->user->cgroup_path, s->id) < 0) { + log_error("Out of memory"); + return -ENOMEM; + } + } else + p = s->cgroup_path; + + r = session_create_one_group(s, SYSTEMD_CGROUP_CONTROLLER, p); + if (r < 0) { + log_error("Failed to create "SYSTEMD_CGROUP_CONTROLLER":%s: %s", p, strerror(-r)); + free(p); + s->cgroup_path = NULL; + return r; + } + + s->cgroup_path = p; + + STRV_FOREACH(k, s->controllers) { + + if (strv_contains(s->reset_controllers, *k)) + continue; + + r = session_create_one_group(s, *k, p); + if (r < 0) + log_warning("Failed to create %s:%s: %s", *k, p, strerror(-r)); + } + + STRV_FOREACH(k, s->manager->controllers) { + + if (strv_contains(s->reset_controllers, *k) || + strv_contains(s->manager->reset_controllers, *k) || + strv_contains(s->controllers, *k)) + continue; + + r = session_create_one_group(s, *k, p); + if (r < 0) + log_warning("Failed to create %s:%s: %s", *k, p, strerror(-r)); + } + + if (s->leader > 0) { + + STRV_FOREACH(k, s->reset_controllers) { + r = cg_attach(*k, "/", s->leader); + if (r < 0) + log_warning("Failed to reset controller %s: %s", *k, strerror(-r)); + + } + + STRV_FOREACH(k, s->manager->reset_controllers) { + + if (strv_contains(s->reset_controllers, *k) || + strv_contains(s->controllers, *k)) + continue; + + r = cg_attach(*k, "/", s->leader); + if (r < 0) + log_warning("Failed to reset controller %s: %s", *k, strerror(-r)); + + } + } + + hashmap_put(s->manager->cgroups, s->cgroup_path, s); + + return 0; +} + +int session_start(Session *s) { + int r; + + assert(s); + assert(s->user); + + if (s->started) + return 0; + + r = user_start(s->user); + if (r < 0) + return r; + + log_full(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG, + "New session %s of user %s.", s->id, s->user->name); + + /* Create cgroup */ + r = session_create_cgroup(s); + if (r < 0) + return r; + + /* Create X11 symlink */ + session_link_x11_socket(s); + + dual_timestamp_get(&s->timestamp); + + if (s->seat) + seat_read_active_vt(s->seat); + + s->started = true; + + /* Save session data */ + session_save(s); + user_save(s->user); + + session_send_signal(s, true); + + if (s->seat) { + seat_save(s->seat); + + if (s->seat->active == s) + seat_send_changed(s->seat, "Sessions\0ActiveSession\0"); + else + seat_send_changed(s->seat, "Sessions\0"); + } + + user_send_changed(s->user, "Sessions\0"); + + return 0; +} + +static bool session_shall_kill(Session *s) { + assert(s); + + if (!s->kill_processes) + return false; + + if (strv_contains(s->manager->kill_exclude_users, s->user->name)) + return false; + + if (strv_isempty(s->manager->kill_only_users)) + return true; + + return strv_contains(s->manager->kill_only_users, s->user->name); +} + +static int session_terminate_cgroup(Session *s) { + int r; + char **k; + + assert(s); + + if (!s->cgroup_path) + return 0; + + cg_trim(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, false); + + if (session_shall_kill(s)) { + + r = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, true); + if (r < 0) + log_error("Failed to kill session cgroup: %s", strerror(-r)); + + } else { + if (s->leader > 0) { + Session *t; + + /* We still send a HUP to the leader process, + * even if we are not supposed to kill the + * whole cgroup. But let's first check the + * leader still exists and belongs to our + * session... */ + + r = manager_get_session_by_pid(s->manager, s->leader, &t); + if (r > 0 && t == s) { + kill(s->leader, SIGTERM); /* for normal processes */ + kill(s->leader, SIGHUP); /* for shells */ + kill(s->leader, SIGCONT); /* in case they are stopped */ + } + } + + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, true); + if (r < 0) + log_error("Failed to check session cgroup: %s", strerror(-r)); + else if (r > 0) { + r = cg_delete(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path); + if (r < 0) + log_error("Failed to delete session cgroup: %s", strerror(-r)); + } + } + + STRV_FOREACH(k, s->user->manager->controllers) + cg_trim(*k, s->cgroup_path, true); + + hashmap_remove(s->manager->cgroups, s->cgroup_path); + + free(s->cgroup_path); + s->cgroup_path = NULL; + + return 0; +} + +static int session_unlink_x11_socket(Session *s) { + char *t; + int r; + + assert(s); + assert(s->user); + + if (s->user->display != s) + return 0; + + s->user->display = NULL; + + t = strappend(s->user->runtime_path, "/X11-display"); + if (!t) { + log_error("Out of memory"); + return -ENOMEM; + } + + r = unlink(t); + free(t); + + return r < 0 ? -errno : 0; +} + +int session_stop(Session *s) { + int r = 0, k; + + assert(s); + + if (s->started) + log_full(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG, + "Removed session %s.", s->id); + + /* Kill cgroup */ + k = session_terminate_cgroup(s); + if (k < 0) + r = k; + + /* Remove X11 symlink */ + session_unlink_x11_socket(s); + + unlink(s->state_file); + session_add_to_gc_queue(s); + user_add_to_gc_queue(s->user); + + if (s->started) + session_send_signal(s, false); + + if (s->seat) { + if (s->seat->active == s) + seat_set_active(s->seat, NULL); + + seat_send_changed(s->seat, "Sessions\0"); + } + + user_send_changed(s->user, "Sessions\0"); + + s->started = false; + + return r; +} + +bool session_is_active(Session *s) { + assert(s); + + if (!s->seat) + return true; + + return s->seat->active == s; +} + +int session_get_idle_hint(Session *s, dual_timestamp *t) { + char *p; + struct stat st; + usec_t u, n; + bool b; + int k; + + assert(s); + + if (s->idle_hint) { + if (t) + *t = s->idle_hint_timestamp; + + return s->idle_hint; + } + + if (isempty(s->tty)) + goto dont_know; + + if (s->tty[0] != '/') { + p = strappend("/dev/", s->tty); + if (!p) + return -ENOMEM; + } else + p = NULL; + + if (!startswith(p ? p : s->tty, "/dev/")) { + free(p); + goto dont_know; + } + + k = lstat(p ? p : s->tty, &st); + free(p); + + if (k < 0) + goto dont_know; + + u = timespec_load(&st.st_atim); + n = now(CLOCK_REALTIME); + b = u + IDLE_THRESHOLD_USEC < n; + + if (t) + dual_timestamp_from_realtime(t, u + b ? IDLE_THRESHOLD_USEC : 0); + + return b; + +dont_know: + if (t) + *t = s->idle_hint_timestamp; + + return 0; +} + +void session_set_idle_hint(Session *s, bool b) { + assert(s); + + if (s->idle_hint == b) + return; + + s->idle_hint = b; + dual_timestamp_get(&s->idle_hint_timestamp); + + session_send_changed(s, + "IdleHint\0" + "IdleSinceHint\0" + "IdleSinceHintMonotonic\0"); + + if (s->seat) + seat_send_changed(s->seat, + "IdleHint\0" + "IdleSinceHint\0" + "IdleSinceHintMonotonic\0"); + + user_send_changed(s->user, + "IdleHint\0" + "IdleSinceHint\0" + "IdleSinceHintMonotonic\0"); + + manager_send_changed(s->manager, + "IdleHint\0" + "IdleSinceHint\0" + "IdleSinceHintMonotonic\0"); +} + +int session_create_fifo(Session *s) { + int r; + + assert(s); + + /* Create FIFO */ + if (!s->fifo_path) { + r = safe_mkdir("/run/systemd/sessions", 0755, 0, 0); + if (r < 0) + return r; + + if (asprintf(&s->fifo_path, "/run/systemd/sessions/%s.ref", s->id) < 0) + return -ENOMEM; + + if (mkfifo(s->fifo_path, 0600) < 0 && errno != EEXIST) + return -errno; + } + + /* Open reading side */ + if (s->fifo_fd < 0) { + struct epoll_event ev; + + s->fifo_fd = open(s->fifo_path, O_RDONLY|O_CLOEXEC|O_NDELAY); + if (s->fifo_fd < 0) + return -errno; + + r = hashmap_put(s->manager->fifo_fds, INT_TO_PTR(s->fifo_fd + 1), s); + if (r < 0) + return r; + + zero(ev); + ev.events = 0; + ev.data.u32 = FD_FIFO_BASE + s->fifo_fd; + + if (epoll_ctl(s->manager->epoll_fd, EPOLL_CTL_ADD, s->fifo_fd, &ev) < 0) + return -errno; + } + + /* Open writing side */ + r = open(s->fifo_path, O_WRONLY|O_CLOEXEC|O_NDELAY); + if (r < 0) + return -errno; + + return r; +} + +void session_remove_fifo(Session *s) { + assert(s); + + if (s->fifo_fd >= 0) { + assert_se(hashmap_remove(s->manager->fifo_fds, INT_TO_PTR(s->fifo_fd + 1)) == s); + assert_se(epoll_ctl(s->manager->epoll_fd, EPOLL_CTL_DEL, s->fifo_fd, NULL) == 0); + close_nointr_nofail(s->fifo_fd); + s->fifo_fd = -1; + } + + if (s->fifo_path) { + unlink(s->fifo_path); + free(s->fifo_path); + s->fifo_path = NULL; + } +} + +int session_check_gc(Session *s, bool drop_not_started) { + int r; + + assert(s); + + if (drop_not_started && !s->started) + return 0; + + if (s->fifo_fd >= 0) { + + r = pipe_eof(s->fifo_fd); + if (r < 0) + return r; + + if (r == 0) + return 1; + } + + if (s->cgroup_path) { + + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, false); + if (r < 0) + return r; + + if (r <= 0) + return 1; + } + + return 0; +} + +void session_add_to_gc_queue(Session *s) { + assert(s); + + if (s->in_gc_queue) + return; + + LIST_PREPEND(Session, gc_queue, s->manager->session_gc_queue, s); + s->in_gc_queue = true; +} + +int session_kill(Session *s, KillWho who, int signo) { + int r = 0; + Set *pid_set = NULL; + + assert(s); + + if (!s->cgroup_path) + return -ESRCH; + + if (s->leader <= 0 && who == KILL_LEADER) + return -ESRCH; + + if (s->leader > 0) + if (kill(s->leader, signo) < 0) + r = -errno; + + if (who == KILL_ALL) { + int q; + + pid_set = set_new(trivial_hash_func, trivial_compare_func); + if (!pid_set) + return -ENOMEM; + + if (s->leader > 0) { + q = set_put(pid_set, LONG_TO_PTR(s->leader)); + if (q < 0) + r = q; + } + + q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, signo, false, true, false, pid_set); + if (q < 0) + if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) + r = q; + } + + if (pid_set) + set_free(pid_set); + + return r; +} + +static const char* const session_type_table[_SESSION_TYPE_MAX] = { + [SESSION_TTY] = "tty", + [SESSION_X11] = "x11", + [SESSION_UNSPECIFIED] = "unspecified" +}; + +DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType); + +static const char* const session_class_table[_SESSION_CLASS_MAX] = { + [SESSION_USER] = "user", + [SESSION_GREETER] = "greeter", + [SESSION_LOCK_SCREEN] = "lock-screen" +}; + +DEFINE_STRING_TABLE_LOOKUP(session_class, SessionClass); + +static const char* const kill_who_table[_KILL_WHO_MAX] = { + [KILL_LEADER] = "leader", + [KILL_ALL] = "all" +}; + +DEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho); diff --git a/src/login/logind-session.h b/src/login/logind-session.h new file mode 100644 index 0000000..d0b8c87 --- /dev/null +++ b/src/login/logind-session.h @@ -0,0 +1,136 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foologindsessionhfoo +#define foologindsessionhfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct Session Session; + +#include "list.h" +#include "util.h" +#include "logind.h" +#include "logind-seat.h" +#include "logind-user.h" + +typedef enum SessionType { + SESSION_UNSPECIFIED, + SESSION_TTY, + SESSION_X11, + _SESSION_TYPE_MAX, + _SESSION_TYPE_INVALID = -1 +} SessionType; + +typedef enum SessionClass { + SESSION_USER, + SESSION_GREETER, + SESSION_LOCK_SCREEN, + _SESSION_CLASS_MAX, + _SESSION_CLASS_INVALID = -1 +} SessionClass; + +typedef enum KillWho { + KILL_LEADER, + KILL_ALL, + _KILL_WHO_MAX, + _KILL_WHO_INVALID = -1 +} KillWho; + +struct Session { + Manager *manager; + + char *id; + SessionType type; + SessionClass class; + + char *state_file; + + User *user; + + dual_timestamp timestamp; + + char *tty; + char *display; + + bool remote; + char *remote_user; + char *remote_host; + + char *service; + + int vtnr; + Seat *seat; + + pid_t leader; + uint32_t audit_id; + + int fifo_fd; + char *fifo_path; + + char *cgroup_path; + char **controllers, **reset_controllers; + + bool idle_hint; + dual_timestamp idle_hint_timestamp; + + bool kill_processes; + bool in_gc_queue:1; + bool started:1; + + LIST_FIELDS(Session, sessions_by_user); + LIST_FIELDS(Session, sessions_by_seat); + + LIST_FIELDS(Session, gc_queue); +}; + +Session *session_new(Manager *m, User *u, const char *id); +void session_free(Session *s); +int session_check_gc(Session *s, bool drop_not_started); +void session_add_to_gc_queue(Session *s); +int session_activate(Session *s); +bool session_is_active(Session *s); +int session_get_idle_hint(Session *s, dual_timestamp *t); +void session_set_idle_hint(Session *s, bool b); +int session_create_fifo(Session *s); +void session_remove_fifo(Session *s); +int session_start(Session *s); +int session_stop(Session *s); +int session_save(Session *s); +int session_load(Session *s); +int session_kill(Session *s, KillWho who, int signo); + +char *session_bus_path(Session *s); + +extern const DBusObjectPathVTable bus_session_vtable; + +int session_send_signal(Session *s, bool new_session); +int session_send_changed(Session *s, const char *properties); +int session_send_lock(Session *s, bool lock); + +const char* session_type_to_string(SessionType t); +SessionType session_type_from_string(const char *s); + +const char* session_class_to_string(SessionClass t); +SessionClass session_class_from_string(const char *s); + +const char *kill_who_to_string(KillWho k); +KillWho kill_who_from_string(const char *s); + +#endif diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c new file mode 100644 index 0000000..a9d680f --- /dev/null +++ b/src/login/logind-user-dbus.c @@ -0,0 +1,417 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "logind.h" +#include "logind-user.h" +#include "dbus-common.h" + +#define BUS_USER_INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + BUS_USER_INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_PEER_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.login1.User\0" + +static int bus_user_append_display(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub; + User *u = data; + const char *id, *path; + char *p = NULL; + + assert(i); + assert(property); + assert(u); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub)) + return -ENOMEM; + + if (u->display) { + id = u->display->id; + path = p = session_bus_path(u->display); + + if (!p) + return -ENOMEM; + } else { + id = ""; + path = "/"; + } + + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &id) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_OBJECT_PATH, &path)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_user_append_state(DBusMessageIter *i, const char *property, void *data) { + User *u = data; + const char *state; + + assert(i); + assert(property); + assert(u); + + state = user_state_to_string(user_get_state(u)); + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state)) + return -ENOMEM; + + return 0; +} + +static int bus_user_append_sessions(DBusMessageIter *i, const char *property, void *data) { + DBusMessageIter sub, sub2; + User *u = data; + Session *session; + + assert(i); + assert(property); + assert(u); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(so)", &sub)) + return -ENOMEM; + + LIST_FOREACH(sessions_by_user, session, u->sessions) { + char *p; + + if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2)) + return -ENOMEM; + + p = session_bus_path(session); + if (!p) + return -ENOMEM; + + if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &session->id) || + !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) { + free(p); + return -ENOMEM; + } + + free(p); + + if (!dbus_message_iter_close_container(&sub, &sub2)) + return -ENOMEM; + } + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_user_append_idle_hint(DBusMessageIter *i, const char *property, void *data) { + User *u = data; + dbus_bool_t b; + + assert(i); + assert(property); + assert(u); + + b = user_get_idle_hint(u, NULL) > 0; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b)) + return -ENOMEM; + + return 0; +} + +static int bus_user_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) { + User *u = data; + dual_timestamp t; + uint64_t k; + + assert(i); + assert(property); + assert(u); + + user_get_idle_hint(u, &t); + k = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &k)) + return -ENOMEM; + + return 0; +} + +static int get_user_for_path(Manager *m, const char *path, User **_u) { + User *u; + unsigned long lu; + int r; + + assert(m); + assert(path); + assert(_u); + + if (!startswith(path, "/org/freedesktop/login1/user/")) + return -EINVAL; + + r = safe_atolu(path + 29, &lu); + if (r < 0) + return r; + + u = hashmap_get(m->users, ULONG_TO_PTR(lu)); + if (!u) + return -ENOENT; + + *_u = u; + return 0; +} + +static const BusProperty bus_login_user_properties[] = { + { "UID", bus_property_append_uid, "u", offsetof(User, uid) }, + { "GID", bus_property_append_gid, "u", offsetof(User, gid) }, + { "Name", bus_property_append_string, "s", offsetof(User, name), true }, + { "Timestamp", bus_property_append_usec, "t", offsetof(User, timestamp.realtime) }, + { "TimestampMonotonic", bus_property_append_usec, "t", offsetof(User, timestamp.monotonic) }, + { "RuntimePath", bus_property_append_string, "s", offsetof(User, runtime_path), true }, + { "ControlGroupPath", bus_property_append_string, "s", offsetof(User, cgroup_path), true }, + { "Service", bus_property_append_string, "s", offsetof(User, service), true }, + { "Display", bus_user_append_display, "(so)", 0 }, + { "State", bus_user_append_state, "s", 0 }, + { "Sessions", bus_user_append_sessions, "a(so)", 0 }, + { "IdleHint", bus_user_append_idle_hint, "b", 0 }, + { "IdleSinceHint", bus_user_append_idle_hint_since, "t", 0 }, + { "IdleSinceHintMonotonic", bus_user_append_idle_hint_since, "t", 0 }, + { NULL, } +}; + +static DBusHandlerResult user_message_dispatch( + User *u, + DBusConnection *connection, + DBusMessage *message) { + + DBusError error; + DBusMessage *reply = NULL; + int r; + + assert(u); + assert(connection); + assert(message); + + if (dbus_message_is_method_call(message, "org.freedesktop.login1.User", "Terminate")) { + + r = user_stop(u); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + } else if (dbus_message_is_method_call(message, "org.freedesktop.login1.User", "Kill")) { + int32_t signo; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_INT32, &signo, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (signo <= 0 || signo >= _NSIG) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + r = user_kill(u, signo); + if (r < 0) + return bus_send_error_reply(connection, message, NULL, r); + + reply = dbus_message_new_method_return(message); + if (!reply) + goto oom; + + } else { + const BusBoundProperties bps[] = { + { "org.freedesktop.login1.User", bus_login_user_properties, u }, + { NULL, } + }; + + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + } + + if (reply) { + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult user_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + Manager *m = userdata; + User *u; + int r; + + r = get_user_for_path(m, dbus_message_get_path(message), &u); + if (r < 0) { + + if (r == -ENOMEM) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (r == -ENOENT) { + DBusError e; + + dbus_error_init(&e); + dbus_set_error_const(&e, DBUS_ERROR_UNKNOWN_OBJECT, "Unknown user"); + return bus_send_error_reply(connection, message, &e, r); + } + + return bus_send_error_reply(connection, message, NULL, r); + } + + return user_message_dispatch(u, connection, message); +} + +const DBusObjectPathVTable bus_user_vtable = { + .message_function = user_message_handler +}; + +char *user_bus_path(User *u) { + char *s; + + assert(u); + + if (asprintf(&s, "/org/freedesktop/login1/user/%llu", (unsigned long long) u->uid) < 0) + return NULL; + + return s; +} + +int user_send_signal(User *u, bool new_user) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + uint32_t uid; + + assert(u); + + m = dbus_message_new_signal("/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + new_user ? "UserNew" : "UserRemoved"); + + if (!m) + return -ENOMEM; + + p = user_bus_path(u); + if (!p) + goto finish; + + uid = u->uid; + + if (!dbus_message_append_args( + m, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_OBJECT_PATH, &p, + DBUS_TYPE_INVALID)) + goto finish; + + if (!dbus_connection_send(u->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + dbus_message_unref(m); + free(p); + + return r; +} + +int user_send_changed(User *u, const char *properties) { + DBusMessage *m; + int r = -ENOMEM; + char *p = NULL; + + assert(u); + + if (!u->started) + return 0; + + p = user_bus_path(u); + if (!p) + return -ENOMEM; + + m = bus_properties_changed_new(p, "org.freedesktop.login1.User", properties); + if (!m) + goto finish; + + if (!dbus_connection_send(u->manager->bus, m, NULL)) + goto finish; + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + free(p); + + return r; +} diff --git a/src/login/logind-user.c b/src/login/logind-user.c new file mode 100644 index 0000000..717f0e2 --- /dev/null +++ b/src/login/logind-user.c @@ -0,0 +1,589 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "logind-user.h" +#include "util.h" +#include "cgroup-util.h" +#include "hashmap.h" +#include "strv.h" + +User* user_new(Manager *m, uid_t uid, gid_t gid, const char *name) { + User *u; + + assert(m); + assert(name); + + u = new0(User, 1); + if (!u) + return NULL; + + u->name = strdup(name); + if (!u->name) { + free(u); + return NULL; + } + + if (asprintf(&u->state_file, "/run/systemd/users/%lu", (unsigned long) uid) < 0) { + free(u->name); + free(u); + return NULL; + } + + if (hashmap_put(m->users, ULONG_TO_PTR((unsigned long) uid), u) < 0) { + free(u->state_file); + free(u->name); + free(u); + return NULL; + } + + u->manager = m; + u->uid = uid; + u->gid = gid; + + return u; +} + +void user_free(User *u) { + assert(u); + + if (u->in_gc_queue) + LIST_REMOVE(User, gc_queue, u->manager->user_gc_queue, u); + + while (u->sessions) + session_free(u->sessions); + + free(u->cgroup_path); + + free(u->service); + free(u->runtime_path); + + hashmap_remove(u->manager->users, ULONG_TO_PTR((unsigned long) u->uid)); + + free(u->name); + free(u->state_file); + free(u); +} + +int user_save(User *u) { + FILE *f; + int r; + char *temp_path; + + assert(u); + assert(u->state_file); + + if (!u->started) + return 0; + + r = safe_mkdir("/run/systemd/users", 0755, 0, 0); + if (r < 0) + goto finish; + + r = fopen_temporary(u->state_file, &f, &temp_path); + if (r < 0) + goto finish; + + fchmod(fileno(f), 0644); + + fprintf(f, + "# This is private data. Do not parse.\n" + "NAME=%s\n" + "STATE=%s\n", + u->name, + user_state_to_string(user_get_state(u))); + + if (u->cgroup_path) + fprintf(f, + "CGROUP=%s\n", + u->cgroup_path); + + if (u->runtime_path) + fprintf(f, + "RUNTIME=%s\n", + u->runtime_path); + + if (u->service) + fprintf(f, + "SERVICE=%s\n", + u->service); + + if (u->display) + fprintf(f, + "DISPLAY=%s\n", + u->display->id); + + if (u->sessions) { + Session *i; + + fputs("SESSIONS=", f); + LIST_FOREACH(sessions_by_user, i, u->sessions) { + fprintf(f, + "%s%c", + i->id, + i->sessions_by_user_next ? ' ' : '\n'); + } + + fputs("SEATS=", f); + LIST_FOREACH(sessions_by_user, i, u->sessions) { + if (i->seat) + fprintf(f, + "%s%c", + i->seat->id, + i->sessions_by_user_next ? ' ' : '\n'); + } + + fputs("ACTIVE_SESSIONS=", f); + LIST_FOREACH(sessions_by_user, i, u->sessions) + if (session_is_active(i)) + fprintf(f, + "%lu%c", + (unsigned long) i->user->uid, + i->sessions_by_user_next ? ' ' : '\n'); + + fputs("ACTIVE_SEATS=", f); + LIST_FOREACH(sessions_by_user, i, u->sessions) { + if (session_is_active(i) && i->seat) + fprintf(f, + "%s%c", + i->seat->id, + i->sessions_by_user_next ? ' ' : '\n'); + } + } + + fflush(f); + + if (ferror(f) || rename(temp_path, u->state_file) < 0) { + r = -errno; + unlink(u->state_file); + unlink(temp_path); + } + + fclose(f); + free(temp_path); + +finish: + if (r < 0) + log_error("Failed to save user data for %s: %s", u->name, strerror(-r)); + + return r; +} + +int user_load(User *u) { + int r; + char *display = NULL; + Session *s = NULL; + + assert(u); + + r = parse_env_file(u->state_file, NEWLINE, + "CGROUP", &u->cgroup_path, + "RUNTIME", &u->runtime_path, + "SERVICE", &u->service, + "DISPLAY", &display, + NULL); + if (r < 0) { + free(display); + + if (r == -ENOENT) + return 0; + + log_error("Failed to read %s: %s", u->state_file, strerror(-r)); + return r; + } + + if (display) { + s = hashmap_get(u->manager->sessions, display); + free(display); + } + + if (s && s->display && display_is_local(s->display)) + u->display = s; + + return r; +} + +static int user_mkdir_runtime_path(User *u) { + char *p; + int r; + + assert(u); + + r = safe_mkdir("/run/user", 0755, 0, 0); + if (r < 0) { + log_error("Failed to create /run/user: %s", strerror(-r)); + return r; + } + + if (!u->runtime_path) { + p = strappend("/run/user/", u->name); + + if (!p) { + log_error("Out of memory"); + return -ENOMEM; + } + } else + p = u->runtime_path; + + r = safe_mkdir(p, 0700, u->uid, u->gid); + if (r < 0) { + log_error("Failed to create runtime directory %s: %s", p, strerror(-r)); + free(p); + u->runtime_path = NULL; + return r; + } + + u->runtime_path = p; + return 0; +} + +static int user_create_cgroup(User *u) { + char **k; + char *p; + int r; + + assert(u); + + if (!u->cgroup_path) { + if (asprintf(&p, "%s/%s", u->manager->cgroup_path, u->name) < 0) { + log_error("Out of memory"); + return -ENOMEM; + } + } else + p = u->cgroup_path; + + r = cg_create(SYSTEMD_CGROUP_CONTROLLER, p); + if (r < 0) { + log_error("Failed to create cgroup "SYSTEMD_CGROUP_CONTROLLER":%s: %s", p, strerror(-r)); + free(p); + u->cgroup_path = NULL; + return r; + } + + u->cgroup_path = p; + + STRV_FOREACH(k, u->manager->controllers) { + + if (strv_contains(u->manager->reset_controllers, *k)) + continue; + + r = cg_create(*k, p); + if (r < 0) + log_warning("Failed to create cgroup %s:%s: %s", *k, p, strerror(-r)); + } + + return 0; +} + +static int user_start_service(User *u) { + assert(u); + + /* FIXME: Fill me in later ... */ + + return 0; +} + +int user_start(User *u) { + int r; + + assert(u); + + if (u->started) + return 0; + + log_debug("New user %s logged in.", u->name); + + /* Make XDG_RUNTIME_DIR */ + r = user_mkdir_runtime_path(u); + if (r < 0) + return r; + + /* Create cgroup */ + r = user_create_cgroup(u); + if (r < 0) + return r; + + /* Spawn user systemd */ + r = user_start_service(u); + if (r < 0) + return r; + + dual_timestamp_get(&u->timestamp); + + u->started = true; + + /* Save new user data */ + user_save(u); + + user_send_signal(u, true); + + return 0; +} + +static int user_stop_service(User *u) { + assert(u); + + if (!u->service) + return 0; + + return 0; +} + +static int user_shall_kill(User *u) { + assert(u); + + if (!u->manager->kill_user_processes) + return false; + + if (strv_contains(u->manager->kill_exclude_users, u->name)) + return false; + + if (strv_isempty(u->manager->kill_only_users)) + return true; + + return strv_contains(u->manager->kill_only_users, u->name); +} + +static int user_terminate_cgroup(User *u) { + int r; + char **k; + + assert(u); + + if (!u->cgroup_path) + return 0; + + cg_trim(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, false); + + if (user_shall_kill(u)) { + + r = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true); + if (r < 0) + log_error("Failed to kill user cgroup: %s", strerror(-r)); + } else { + + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true); + if (r < 0) + log_error("Failed to check user cgroup: %s", strerror(-r)); + else if (r > 0) { + r = cg_delete(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path); + if (r < 0) + log_error("Failed to delete user cgroup: %s", strerror(-r)); + } else + r = -EBUSY; + } + + STRV_FOREACH(k, u->manager->controllers) + cg_trim(*k, u->cgroup_path, true); + + free(u->cgroup_path); + u->cgroup_path = NULL; + + return r; +} + +static int user_remove_runtime_path(User *u) { + int r; + + assert(u); + + if (!u->runtime_path) + return 0; + + r = rm_rf(u->runtime_path, false, true, false); + if (r < 0) + log_error("Failed to remove runtime directory %s: %s", u->runtime_path, strerror(-r)); + + free(u->runtime_path); + u->runtime_path = NULL; + + return r; +} + +int user_stop(User *u) { + Session *s; + int r = 0, k; + assert(u); + + if (u->started) + log_debug("User %s logged out.", u->name); + + LIST_FOREACH(sessions_by_user, s, u->sessions) { + k = session_stop(s); + if (k < 0) + r = k; + } + + /* Kill systemd */ + k = user_stop_service(u); + if (k < 0) + r = k; + + /* Kill cgroup */ + k = user_terminate_cgroup(u); + if (k < 0) + r = k; + + /* Kill XDG_RUNTIME_DIR */ + k = user_remove_runtime_path(u); + if (k < 0) + r = k; + + unlink(u->state_file); + user_add_to_gc_queue(u); + + if (u->started) + user_send_signal(u, false); + + u->started = false; + + return r; +} + +int user_get_idle_hint(User *u, dual_timestamp *t) { + Session *s; + bool idle_hint = true; + dual_timestamp ts = { 0, 0 }; + + assert(u); + + LIST_FOREACH(sessions_by_user, s, u->sessions) { + dual_timestamp k; + int ih; + + ih = session_get_idle_hint(s, &k); + if (ih < 0) + return ih; + + if (!ih) { + if (!idle_hint) { + if (k.monotonic < ts.monotonic) + ts = k; + } else { + idle_hint = false; + ts = k; + } + } else if (idle_hint) { + + if (k.monotonic > ts.monotonic) + ts = k; + } + } + + if (t) + *t = ts; + + return idle_hint; +} + +int user_check_gc(User *u, bool drop_not_started) { + int r; + char *p; + + assert(u); + + if (drop_not_started && !u->started) + return 0; + + if (u->sessions) + return 1; + + if (asprintf(&p, "/var/lib/systemd/linger/%s", u->name) < 0) + return -ENOMEM; + + r = access(p, F_OK) >= 0; + free(p); + + if (r > 0) + return 1; + + if (u->cgroup_path) { + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, false); + if (r < 0) + return r; + + if (r <= 0) + return 1; + } + + return 0; +} + +void user_add_to_gc_queue(User *u) { + assert(u); + + if (u->in_gc_queue) + return; + + LIST_PREPEND(User, gc_queue, u->manager->user_gc_queue, u); + u->in_gc_queue = true; +} + +UserState user_get_state(User *u) { + Session *i; + + assert(u); + + if (!u->sessions) + return USER_LINGERING; + + LIST_FOREACH(sessions_by_user, i, u->sessions) + if (session_is_active(i)) + return USER_ACTIVE; + + return USER_ONLINE; +} + +int user_kill(User *u, int signo) { + int r = 0, q; + Set *pid_set = NULL; + + assert(u); + + if (!u->cgroup_path) + return -ESRCH; + + pid_set = set_new(trivial_hash_func, trivial_compare_func); + if (!pid_set) + return -ENOMEM; + + q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set); + if (q < 0) + if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) + r = q; + + if (pid_set) + set_free(pid_set); + + return r; +} + +static const char* const user_state_table[_USER_STATE_MAX] = { + [USER_OFFLINE] = "offline", + [USER_LINGERING] = "lingering", + [USER_ONLINE] = "online", + [USER_ACTIVE] = "active" +}; + +DEFINE_STRING_TABLE_LOOKUP(user_state, UserState); diff --git a/src/login/logind-user.h b/src/login/logind-user.h new file mode 100644 index 0000000..db9a5f6 --- /dev/null +++ b/src/login/logind-user.h @@ -0,0 +1,86 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foologinduserhfoo +#define foologinduserhfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct User User; + +#include "list.h" +#include "util.h" +#include "logind.h" +#include "logind-session.h" + +typedef enum UserState { + USER_OFFLINE, + USER_LINGERING, + USER_ONLINE, + USER_ACTIVE, + _USER_STATE_MAX, + _USER_STATE_INVALID = -1 +} UserState; + +struct User { + Manager *manager; + + uid_t uid; + gid_t gid; + char *name; + + char *state_file; + char *runtime_path; + char *service; + char *cgroup_path; + + Session *display; + + dual_timestamp timestamp; + + bool in_gc_queue:1; + bool started:1; + + LIST_HEAD(Session, sessions); + LIST_FIELDS(User, gc_queue); +}; + +User* user_new(Manager *m, uid_t uid, gid_t gid, const char *name); +void user_free(User *u); +int user_check_gc(User *u, bool drop_not_started); +void user_add_to_gc_queue(User *u); +int user_start(User *u); +int user_stop(User *u); +UserState user_get_state(User *u); +int user_get_idle_hint(User *u, dual_timestamp *t); +int user_save(User *u); +int user_load(User *u); +int user_kill(User *u, int signo); + +char *user_bus_path(User *s); + +extern const DBusObjectPathVTable bus_user_vtable; + +int user_send_signal(User *u, bool new_user); +int user_send_changed(User *u, const char *properties); + +const char* user_state_to_string(UserState s); +UserState user_state_from_string(const char *s); + +#endif diff --git a/src/login/logind.c b/src/login/logind.c new file mode 100644 index 0000000..7fd6515 --- /dev/null +++ b/src/login/logind.c @@ -0,0 +1,1287 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "logind.h" +#include "dbus-common.h" +#include "dbus-loop.h" +#include "strv.h" +#include "conf-parser.h" + +Manager *manager_new(void) { + Manager *m; + + m = new0(Manager, 1); + if (!m) + return NULL; + + m->console_active_fd = -1; + m->bus_fd = -1; + m->udev_seat_fd = -1; + m->udev_vcsa_fd = -1; + m->epoll_fd = -1; + m->n_autovts = 6; + + m->devices = hashmap_new(string_hash_func, string_compare_func); + m->seats = hashmap_new(string_hash_func, string_compare_func); + m->sessions = hashmap_new(string_hash_func, string_compare_func); + m->users = hashmap_new(trivial_hash_func, trivial_compare_func); + m->cgroups = hashmap_new(string_hash_func, string_compare_func); + m->fifo_fds = hashmap_new(trivial_hash_func, trivial_compare_func); + + if (!m->devices || !m->seats || !m->sessions || !m->users || !m->cgroups || !m->fifo_fds) { + manager_free(m); + return NULL; + } + + m->reset_controllers = strv_new("cpu", NULL); + m->kill_exclude_users = strv_new("root", NULL); + if (!m->reset_controllers || !m->kill_exclude_users) { + manager_free(m); + return NULL; + } + + m->udev = udev_new(); + if (!m->udev) { + manager_free(m); + return NULL; + } + + if (cg_get_user_path(&m->cgroup_path) < 0) { + manager_free(m); + return NULL; + } + + return m; +} + +void manager_free(Manager *m) { + Session *session; + User *u; + Device *d; + Seat *s; + + assert(m); + + while ((session = hashmap_first(m->sessions))) + session_free(session); + + while ((u = hashmap_first(m->users))) + user_free(u); + + while ((d = hashmap_first(m->devices))) + device_free(d); + + while ((s = hashmap_first(m->seats))) + seat_free(s); + + hashmap_free(m->sessions); + hashmap_free(m->users); + hashmap_free(m->devices); + hashmap_free(m->seats); + hashmap_free(m->cgroups); + hashmap_free(m->fifo_fds); + + if (m->console_active_fd >= 0) + close_nointr_nofail(m->console_active_fd); + + if (m->udev_seat_monitor) + udev_monitor_unref(m->udev_seat_monitor); + + if (m->udev_vcsa_monitor) + udev_monitor_unref(m->udev_vcsa_monitor); + + if (m->udev) + udev_unref(m->udev); + + if (m->bus) { + dbus_connection_flush(m->bus); + dbus_connection_close(m->bus); + dbus_connection_unref(m->bus); + } + + if (m->bus_fd >= 0) + close_nointr_nofail(m->bus_fd); + + if (m->epoll_fd >= 0) + close_nointr_nofail(m->epoll_fd); + + strv_free(m->controllers); + strv_free(m->reset_controllers); + strv_free(m->kill_only_users); + strv_free(m->kill_exclude_users); + + free(m->cgroup_path); + free(m); +} + +int manager_add_device(Manager *m, const char *sysfs, Device **_device) { + Device *d; + + assert(m); + assert(sysfs); + + d = hashmap_get(m->devices, sysfs); + if (d) { + if (_device) + *_device = d; + + return 0; + } + + d = device_new(m, sysfs); + if (!d) + return -ENOMEM; + + if (_device) + *_device = d; + + return 0; +} + +int manager_add_seat(Manager *m, const char *id, Seat **_seat) { + Seat *s; + + assert(m); + assert(id); + + s = hashmap_get(m->seats, id); + if (s) { + if (_seat) + *_seat = s; + + return 0; + } + + s = seat_new(m, id); + if (!s) + return -ENOMEM; + + if (_seat) + *_seat = s; + + return 0; +} + +int manager_add_session(Manager *m, User *u, const char *id, Session **_session) { + Session *s; + + assert(m); + assert(id); + + s = hashmap_get(m->sessions, id); + if (s) { + if (_session) + *_session = s; + + return 0; + } + + s = session_new(m, u, id); + if (!s) + return -ENOMEM; + + if (_session) + *_session = s; + + return 0; +} + +int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) { + User *u; + + assert(m); + assert(name); + + u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid)); + if (u) { + if (_user) + *_user = u; + + return 0; + } + + u = user_new(m, uid, gid, name); + if (!u) + return -ENOMEM; + + if (_user) + *_user = u; + + return 0; +} + +int manager_add_user_by_name(Manager *m, const char *name, User **_user) { + uid_t uid; + gid_t gid; + int r; + + assert(m); + assert(name); + + r = get_user_creds(&name, &uid, &gid, NULL); + if (r < 0) + return r; + + return manager_add_user(m, uid, gid, name, _user); +} + +int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) { + struct passwd *p; + + assert(m); + + errno = 0; + p = getpwuid(uid); + if (!p) + return errno ? -errno : -ENOENT; + + return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user); +} + +int manager_process_seat_device(Manager *m, struct udev_device *d) { + Device *device; + int r; + + assert(m); + + if (streq_ptr(udev_device_get_action(d), "remove")) { + + device = hashmap_get(m->devices, udev_device_get_syspath(d)); + if (!device) + return 0; + + seat_add_to_gc_queue(device->seat); + device_free(device); + + } else { + const char *sn; + Seat *seat; + + sn = udev_device_get_property_value(d, "ID_SEAT"); + if (isempty(sn)) + sn = "seat0"; + + if (!seat_name_is_valid(sn)) { + log_warning("Device with invalid seat name %s found, ignoring.", sn); + return 0; + } + + r = manager_add_device(m, udev_device_get_syspath(d), &device); + if (r < 0) + return r; + + r = manager_add_seat(m, sn, &seat); + if (r < 0) { + if (!device->seat) + device_free(device); + + return r; + } + + device_attach(device, seat); + seat_start(seat); + } + + return 0; +} + +int manager_enumerate_devices(Manager *m) { + struct udev_list_entry *item = NULL, *first = NULL; + struct udev_enumerate *e; + int r; + + assert(m); + + /* Loads devices from udev and creates seats for them as + * necessary */ + + e = udev_enumerate_new(m->udev); + if (!e) { + r = -ENOMEM; + goto finish; + } + + r = udev_enumerate_add_match_subsystem(e, "graphics"); + if (r < 0) + goto finish; + + r = udev_enumerate_add_match_tag(e, "seat"); + if (r < 0) + goto finish; + + r = udev_enumerate_scan_devices(e); + if (r < 0) + goto finish; + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + struct udev_device *d; + int k; + + d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item)); + if (!d) { + r = -ENOMEM; + goto finish; + } + + k = manager_process_seat_device(m, d); + udev_device_unref(d); + + if (k < 0) + r = k; + } + +finish: + if (e) + udev_enumerate_unref(e); + + return r; +} + +int manager_enumerate_seats(Manager *m) { + DIR *d; + struct dirent *de; + int r = 0; + + assert(m); + + /* This loads data about seats stored on disk, but does not + * actually create any seats. Removes data of seats that no + * longer exist. */ + + d = opendir("/run/systemd/seats"); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open /run/systemd/seats: %m"); + return -errno; + } + + while ((de = readdir(d))) { + Seat *s; + int k; + + if (!dirent_is_file(de)) + continue; + + s = hashmap_get(m->seats, de->d_name); + if (!s) { + unlinkat(dirfd(d), de->d_name, 0); + continue; + } + + k = seat_load(s); + if (k < 0) + r = k; + } + + closedir(d); + + return r; +} + +static int manager_enumerate_users_from_cgroup(Manager *m) { + int r = 0; + char *name; + DIR *d; + int k; + + r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, &d); + if (r < 0) { + if (r == -ENOENT) + return 0; + + log_error("Failed to open %s: %s", m->cgroup_path, strerror(-r)); + return r; + } + + while ((k = cg_read_subgroup(d, &name)) > 0) { + User *user; + + k = manager_add_user_by_name(m, name, &user); + if (k < 0) { + free(name); + r = k; + continue; + } + + user_add_to_gc_queue(user); + + if (!user->cgroup_path) + if (asprintf(&user->cgroup_path, "%s/%s", m->cgroup_path, name) < 0) { + r = -ENOMEM; + free(name); + break; + } + + free(name); + } + + if (r >= 0 && k < 0) + r = k; + + closedir(d); + + return r; +} + +static int manager_enumerate_linger_users(Manager *m) { + DIR *d; + struct dirent *de; + int r = 0; + + d = opendir("/var/lib/systemd/linger"); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open /var/lib/systemd/linger/: %m"); + return -errno; + } + + while ((de = readdir(d))) { + int k; + + if (!dirent_is_file(de)) + continue; + + k = manager_add_user_by_name(m, de->d_name, NULL); + if (k < 0) { + log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k)); + r = k; + } + } + + closedir(d); + + return r; +} + +int manager_enumerate_users(Manager *m) { + DIR *d; + struct dirent *de; + int r, k; + + assert(m); + + /* First, enumerate user cgroups */ + r = manager_enumerate_users_from_cgroup(m); + + /* Second, add lingering users on top */ + k = manager_enumerate_linger_users(m); + if (k < 0) + r = k; + + /* Third, read in user data stored on disk */ + d = opendir("/run/systemd/users"); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open /run/systemd/users: %m"); + return -errno; + } + + while ((de = readdir(d))) { + uid_t uid; + User *u; + + if (!dirent_is_file(de)) + continue; + + k = parse_uid(de->d_name, &uid); + if (k < 0) { + log_error("Failed to parse file name %s: %s", de->d_name, strerror(-k)); + continue; + } + + u = hashmap_get(m->users, ULONG_TO_PTR(uid)); + if (!u) { + unlinkat(dirfd(d), de->d_name, 0); + continue; + } + + k = user_load(u); + if (k < 0) + r = k; + } + + closedir(d); + + return r; +} + +static int manager_enumerate_sessions_from_cgroup(Manager *m) { + User *u; + Iterator i; + int r = 0; + + HASHMAP_FOREACH(u, m->users, i) { + DIR *d; + char *name; + int k; + + if (!u->cgroup_path) + continue; + + k = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &d); + if (k < 0) { + if (k == -ENOENT) + continue; + + log_error("Failed to open %s: %s", u->cgroup_path, strerror(-k)); + r = k; + continue; + } + + while ((k = cg_read_subgroup(d, &name)) > 0) { + Session *session; + + if (streq(name, "shared")) + continue; + + k = manager_add_session(m, u, name, &session); + if (k < 0) { + free(name); + break; + } + + session_add_to_gc_queue(session); + + if (!session->cgroup_path) + if (asprintf(&session->cgroup_path, "%s/%s", u->cgroup_path, name) < 0) { + k = -ENOMEM; + free(name); + break; + } + + free(name); + } + + closedir(d); + + if (k < 0) + r = k; + } + + return r; +} + +int manager_enumerate_sessions(Manager *m) { + DIR *d; + struct dirent *de; + int r = 0; + + assert(m); + + /* First enumerate session cgroups */ + r = manager_enumerate_sessions_from_cgroup(m); + + /* Second, read in session data stored on disk */ + d = opendir("/run/systemd/sessions"); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open /run/systemd/sessions: %m"); + return -errno; + } + + while ((de = readdir(d))) { + struct Session *s; + int k; + + if (!dirent_is_file(de)) + continue; + + s = hashmap_get(m->sessions, de->d_name); + if (!s) { + unlinkat(dirfd(d), de->d_name, 0); + continue; + } + + k = session_load(s); + if (k < 0) + r = k; + } + + closedir(d); + + return r; +} + +int manager_dispatch_seat_udev(Manager *m) { + struct udev_device *d; + int r; + + assert(m); + + d = udev_monitor_receive_device(m->udev_seat_monitor); + if (!d) + return -ENOMEM; + + r = manager_process_seat_device(m, d); + udev_device_unref(d); + + return r; +} + +int manager_dispatch_vcsa_udev(Manager *m) { + struct udev_device *d; + int r = 0; + const char *name; + + assert(m); + + d = udev_monitor_receive_device(m->udev_vcsa_monitor); + if (!d) + return -ENOMEM; + + name = udev_device_get_sysname(d); + + /* Whenever a VCSA device is removed try to reallocate our + * VTs, to make sure our auto VTs never go away. */ + + if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove")) + r = seat_preallocate_vts(m->vtconsole); + + udev_device_unref(d); + + return r; +} + +int manager_dispatch_console(Manager *m) { + assert(m); + + if (m->vtconsole) + seat_read_active_vt(m->vtconsole); + + return 0; +} + +static int vt_is_busy(int vtnr) { + struct vt_stat vt_stat; + int r = 0, fd; + + assert(vtnr >= 1); + + /* We explicitly open /dev/tty1 here instead of /dev/tty0. If + * we'd open the latter we'd open the foreground tty which + * hence would be unconditionally busy. By opening /dev/tty1 + * we avoid this. Since tty1 is special and needs to be an + * explicitly loaded getty or DM this is safe. */ + + fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return -errno; + + if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0) + r = -errno; + else + r = !!(vt_stat.v_state & (1 << vtnr)); + + close_nointr_nofail(fd); + + return r; +} + +int manager_spawn_autovt(Manager *m, int vtnr) { + int r; + DBusMessage *message = NULL, *reply = NULL; + char *name = NULL; + const char *mode = "fail"; + DBusError error; + + assert(m); + assert(vtnr >= 1); + + dbus_error_init(&error); + + if ((unsigned) vtnr > m->n_autovts) + return 0; + + r = vt_is_busy(vtnr); + if (r < 0) + return r; + else if (r > 0) + return -EBUSY; + + message = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit"); + if (!message) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) { + log_error("Could not allocate service name."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(message, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)) { + log_error("Could not attach target and flag information to message."); + r = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(m->bus, message, -1, &error); + if (!reply) { + log_error("Failed to start unit: %s", bus_error_message(&error)); + goto finish; + } + + r = 0; + +finish: + free(name); + + if (message) + dbus_message_unref(message); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session) { + Session *s; + char *p; + + assert(m); + assert(cgroup); + assert(session); + + s = hashmap_get(m->cgroups, cgroup); + if (s) { + *session = s; + return 1; + } + + p = strdup(cgroup); + if (!p) { + log_error("Out of memory."); + return -ENOMEM; + } + + for (;;) { + char *e; + + e = strrchr(p, '/'); + if (!e || e == p) { + free(p); + *session = NULL; + return 0; + } + + *e = 0; + + s = hashmap_get(m->cgroups, p); + if (s) { + free(p); + *session = s; + return 1; + } + } +} + +int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) { + char *p; + int r; + + assert(m); + assert(pid >= 1); + assert(session); + + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &p); + if (r < 0) + return r; + + r = manager_get_session_by_cgroup(m, p, session); + free(p); + + return r; +} + +void manager_cgroup_notify_empty(Manager *m, const char *cgroup) { + Session *s; + int r; + + r = manager_get_session_by_cgroup(m, cgroup, &s); + if (r <= 0) + return; + + session_add_to_gc_queue(s); +} + +static void manager_pipe_notify_eof(Manager *m, int fd) { + Session *s; + + assert_se(m); + assert_se(fd >= 0); + + assert_se(s = hashmap_get(m->fifo_fds, INT_TO_PTR(fd + 1))); + assert(s->fifo_fd == fd); + session_remove_fifo(s); + + session_stop(s); +} + +static int manager_connect_bus(Manager *m) { + DBusError error; + int r; + struct epoll_event ev; + + assert(m); + assert(!m->bus); + assert(m->bus_fd < 0); + + dbus_error_init(&error); + + m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!m->bus) { + log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error)); + r = -ECONNREFUSED; + goto fail; + } + + if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) || + !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) || + !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) || + !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) || + !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) { + log_error("Not enough memory"); + r = -ENOMEM; + goto fail; + } + + dbus_bus_add_match(m->bus, + "type='signal'," + "interface='org.freedesktop.systemd1.Agent'," + "member='Released'," + "path='/org/freedesktop/systemd1/agent'", + &error); + + if (dbus_error_is_set(&error)) { + log_error("Failed to register match: %s", bus_error_message(&error)); + r = -EIO; + goto fail; + } + + r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to register name on bus: %s", bus_error_message(&error)); + r = -EIO; + goto fail; + } + + if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + log_error("Failed to acquire name."); + r = -EEXIST; + goto fail; + } + + m->bus_fd = bus_loop_open(m->bus); + if (m->bus_fd < 0) { + r = m->bus_fd; + goto fail; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.u32 = FD_BUS; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0) + goto fail; + + return 0; + +fail: + dbus_error_free(&error); + + return r; +} + +static int manager_connect_console(Manager *m) { + struct epoll_event ev; + + assert(m); + assert(m->console_active_fd < 0); + + m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC); + if (m->console_active_fd < 0) { + + /* On certain architectures (S390 and Xen), /dev/tty0 + does not exist, so don't fail if we can't open it.*/ + if (errno == ENOENT) + return 0; + + log_error("Failed to open /sys/class/tty/tty0/active: %m"); + return -errno; + } + + zero(ev); + ev.events = 0; + ev.data.u32 = FD_CONSOLE; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0) + return -errno; + + return 0; +} + +static int manager_connect_udev(Manager *m) { + struct epoll_event ev; + int r; + + assert(m); + assert(!m->udev_seat_monitor); + assert(!m->udev_vcsa_monitor); + + m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev"); + if (!m->udev_seat_monitor) + return -ENOMEM; + + r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "seat"); + if (r < 0) + return r; + + r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_seat_monitor, "graphics", NULL); + if (r < 0) + return r; + + r = udev_monitor_enable_receiving(m->udev_seat_monitor); + if (r < 0) + return r; + + m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor); + + zero(ev); + ev.events = EPOLLIN; + ev.data.u32 = FD_SEAT_UDEV; + + /* Don't bother watching VCSA devices, if nobody cares */ + if (m->n_autovts <= 0 || m->console_active_fd < 0) + return 0; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0) + return -errno; + + m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev"); + if (!m->udev_vcsa_monitor) + return -ENOMEM; + + r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL); + if (r < 0) + return r; + + r = udev_monitor_enable_receiving(m->udev_vcsa_monitor); + if (r < 0) + return r; + + m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor); + + zero(ev); + ev.events = EPOLLIN; + ev.data.u32 = FD_VCSA_UDEV; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0) + return -errno; + + return 0; +} + +void manager_gc(Manager *m, bool drop_not_started) { + Seat *seat; + Session *session; + User *user; + + assert(m); + + while ((seat = m->seat_gc_queue)) { + LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat); + seat->in_gc_queue = false; + + if (seat_check_gc(seat, drop_not_started) == 0) { + seat_stop(seat); + seat_free(seat); + } + } + + while ((session = m->session_gc_queue)) { + LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session); + session->in_gc_queue = false; + + if (session_check_gc(session, drop_not_started) == 0) { + session_stop(session); + session_free(session); + } + } + + while ((user = m->user_gc_queue)) { + LIST_REMOVE(User, gc_queue, m->user_gc_queue, user); + user->in_gc_queue = false; + + if (user_check_gc(user, drop_not_started) == 0) { + user_stop(user); + user_free(user); + } + } +} + +int manager_get_idle_hint(Manager *m, dual_timestamp *t) { + Session *s; + bool idle_hint = true; + dual_timestamp ts = { 0, 0 }; + Iterator i; + + assert(m); + + HASHMAP_FOREACH(s, m->sessions, i) { + dual_timestamp k; + int ih; + + ih = session_get_idle_hint(s, &k); + if (ih < 0) + return ih; + + if (!ih) { + if (!idle_hint) { + if (k.monotonic < ts.monotonic) + ts = k; + } else { + idle_hint = false; + ts = k; + } + } else if (idle_hint) { + + if (k.monotonic > ts.monotonic) + ts = k; + } + } + + if (t) + *t = ts; + + return idle_hint; +} + +int manager_startup(Manager *m) { + int r; + Seat *seat; + Session *session; + User *user; + Iterator i; + + assert(m); + assert(m->epoll_fd <= 0); + + m->epoll_fd = epoll_create1(EPOLL_CLOEXEC); + if (m->epoll_fd < 0) + return -errno; + + /* Connect to console */ + r = manager_connect_console(m); + if (r < 0) + return r; + + /* Connect to udev */ + r = manager_connect_udev(m); + if (r < 0) + return r; + + /* Connect to the bus */ + r = manager_connect_bus(m); + if (r < 0) + return r; + + /* Instantiate magic seat 0 */ + r = manager_add_seat(m, "seat0", &m->vtconsole); + if (r < 0) + return r; + + /* Deserialize state */ + manager_enumerate_devices(m); + manager_enumerate_seats(m); + manager_enumerate_users(m); + manager_enumerate_sessions(m); + + /* Remove stale objects before we start them */ + manager_gc(m, false); + + /* And start everything */ + HASHMAP_FOREACH(seat, m->seats, i) + seat_start(seat); + + HASHMAP_FOREACH(user, m->users, i) + user_start(user); + + HASHMAP_FOREACH(session, m->sessions, i) + session_start(session); + + return 0; +} + +int manager_run(Manager *m) { + assert(m); + + for (;;) { + struct epoll_event event; + int n; + + manager_gc(m, true); + + if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE) + continue; + + manager_gc(m, true); + + n = epoll_wait(m->epoll_fd, &event, 1, -1); + if (n < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + + log_error("epoll() failed: %m"); + return -errno; + } + + switch (event.data.u32) { + + case FD_SEAT_UDEV: + manager_dispatch_seat_udev(m); + break; + + case FD_VCSA_UDEV: + manager_dispatch_vcsa_udev(m); + break; + + case FD_CONSOLE: + manager_dispatch_console(m); + break; + + case FD_BUS: + bus_loop_dispatch(m->bus_fd); + break; + + default: + if (event.data.u32 >= FD_FIFO_BASE) + manager_pipe_notify_eof(m, event.data.u32 - FD_FIFO_BASE); + } + } + + return 0; +} + +static int manager_parse_config_file(Manager *m) { + FILE *f; + const char *fn; + int r; + + assert(m); + + fn = "/etc/systemd/systemd-logind.conf"; + f = fopen(fn, "re"); + if (!f) { + if (errno == ENOENT) + return 0; + + log_warning("Failed to open configuration file %s: %m", fn); + return -errno; + } + + r = config_parse(fn, f, "Login\0", config_item_perf_lookup, (void*) logind_gperf_lookup, false, m); + if (r < 0) + log_warning("Failed to parse configuration file: %s", strerror(-r)); + + fclose(f); + + return r; +} + +int main(int argc, char *argv[]) { + Manager *m = NULL; + int r; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc != 1) { + log_error("This program takes no arguments."); + r = -EINVAL; + goto finish; + } + + m = manager_new(); + if (!m) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + manager_parse_config_file(m); + + r = manager_startup(m); + if (r < 0) { + log_error("Failed to fully start up daemon: %s", strerror(-r)); + goto finish; + } + + log_debug("systemd-logind running as pid %lu", (unsigned long) getpid()); + + sd_notify(false, + "READY=1\n" + "STATUS=Processing requests..."); + + r = manager_run(m); + + log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid()); + +finish: + sd_notify(false, + "STATUS=Shutting down..."); + + if (m) + manager_free(m); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/login/logind.h b/src/login/logind.h new file mode 100644 index 0000000..a4b4602 --- /dev/null +++ b/src/login/logind.h @@ -0,0 +1,131 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foologindhfoo +#define foologindhfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "list.h" +#include "hashmap.h" +#include "cgroup-util.h" + +typedef struct Manager Manager; + +#include "logind-device.h" +#include "logind-seat.h" +#include "logind-session.h" +#include "logind-user.h" + +struct Manager { + DBusConnection *bus; + + Hashmap *devices; + Hashmap *seats; + Hashmap *sessions; + Hashmap *users; + + LIST_HEAD(Seat, seat_gc_queue); + LIST_HEAD(Session, session_gc_queue); + LIST_HEAD(User, user_gc_queue); + + struct udev *udev; + struct udev_monitor *udev_seat_monitor, *udev_vcsa_monitor; + + int udev_seat_fd; + int udev_vcsa_fd; + + int console_active_fd; + int bus_fd; + int epoll_fd; + + unsigned n_autovts; + + Seat *vtconsole; + + char *cgroup_path; + char **controllers, **reset_controllers; + + char **kill_only_users, **kill_exclude_users; + + bool kill_user_processes; + + unsigned long session_counter; + + Hashmap *cgroups; + Hashmap *fifo_fds; +}; + +enum { + FD_SEAT_UDEV, + FD_VCSA_UDEV, + FD_CONSOLE, + FD_BUS, + FD_FIFO_BASE +}; + +Manager *manager_new(void); +void manager_free(Manager *m); + +int manager_add_device(Manager *m, const char *sysfs, Device **_device); +int manager_add_seat(Manager *m, const char *id, Seat **_seat); +int manager_add_session(Manager *m, User *u, const char *id, Session **_session); +int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user); +int manager_add_user_by_name(Manager *m, const char *name, User **_user); +int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user); + +int manager_process_seat_device(Manager *m, struct udev_device *d); +int manager_dispatch_seat_udev(Manager *m); +int manager_dispatch_vcsa_udev(Manager *m); +int manager_dispatch_console(Manager *m); + +int manager_enumerate_devices(Manager *m); +int manager_enumerate_seats(Manager *m); +int manager_enumerate_sessions(Manager *m); +int manager_enumerate_users(Manager *m); + +int manager_startup(Manager *m); +int manager_run(Manager *m); +int manager_spawn_autovt(Manager *m, int vtnr); + +void manager_cgroup_notify_empty(Manager *m, const char *cgroup); + +void manager_gc(Manager *m, bool drop_not_started); + +int manager_get_idle_hint(Manager *m, dual_timestamp *t); + +int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session); +int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session); + +extern const DBusObjectPathVTable bus_manager_vtable; + +DBusHandlerResult bus_message_filter(DBusConnection *c, DBusMessage *message, void *userdata); + +int manager_send_changed(Manager *manager, const char *properties); + +/* gperf lookup function */ +const struct ConfigPerfItem* logind_gperf_lookup(const char *key, unsigned length); + +#endif diff --git a/src/login/multi-seat-x.c b/src/login/multi-seat-x.c new file mode 100644 index 0000000..7133e02 --- /dev/null +++ b/src/login/multi-seat-x.c @@ -0,0 +1,195 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include + +#include "util.h" + +int main(int argc, char *argv[]) { + + struct udev *udev = NULL; + struct udev_enumerate *enumerator = NULL; + struct udev_list_entry *first, *item; + int i; + const char *seat = NULL; + char **new_argv; + char *path = NULL, *device_node = NULL; + int r; + FILE *f = NULL; + + /* This binary will go away as soon as X natively supports + * display enumeration with udev in a way that covers both PCI + * and USB. */ + + /* This will simply determine the fb device id of the graphics + * device assigned to a seat and write a configuration file + * from it and then spawn the real X server. */ + + /* If this file is removed, don't forget to remove the code + * that invokes this in gdm and other display managers. */ + + for (i = 1; i < argc; i++) + if (streq(argv[i], "-seat")) + seat = argv[i+1]; + + if (isempty(seat) || streq(seat, "seat0")) { + argv[0] = (char*) X_SERVER; + execv(X_SERVER, argv); + log_error("Failed to execute real X server: %m"); + goto fail; + } + + udev = udev_new(); + if (!udev) { + log_error("Failed to allocate udev environment."); + goto fail; + } + + enumerator = udev_enumerate_new(udev); + if (!enumerator) { + log_error("Failed to allocate udev enumerator."); + goto fail; + } + + udev_enumerate_add_match_subsystem(enumerator, "graphics"); + udev_enumerate_add_match_tag(enumerator, seat); + + r = udev_enumerate_scan_devices(enumerator); + if (r < 0) { + log_error("Failed to enumerate devices."); + goto fail; + } + + first = udev_enumerate_get_list_entry(enumerator); + udev_list_entry_foreach(item, first) { + struct udev_device *d; + const char *dn; + + d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); + if (!d) + continue; + + dn = udev_device_get_devnode(d); + + if (dn) { + device_node = strdup(dn); + if (!device_node) { + udev_device_unref(d); + log_error("Out of memory."); + goto fail; + } + } + + udev_device_unref(d); + + if (device_node) + break; + } + + if (!device_node) { + log_error("Failed to find device node for seat %s.", seat); + goto fail; + } + + r = safe_mkdir("/run/systemd/multi-session-x", 0755, 0, 0); + if (r < 0) { + log_error("Failed to create directory: %s", strerror(-r)); + goto fail; + } + + path = strappend("/run/systemd/multi-session-x/", seat); + if (!path) { + log_error("Out of memory"); + goto fail; + } + + f = fopen(path, "we"); + if (!f) { + log_error("Failed to write configuration file: %m"); + goto fail; + } + + fprintf(f, + "Section \"Device\"\n" + " Identifier \"udev\"\n" + " Driver \"fbdev\"\n" + " Option \"fbdev\" \"%s\"\n" + "EndSection\n" + "Section \"ServerFlags\"\n" + " Option \"AutoAddDevices\" \"True\"\n" + " Option \"AllowEmptyInput\" \"True\"\n" + " Option \"DontVTSwitch\" \"True\"\n" + "EndSection\n" + "Section \"InputClass\"\n" + " Identifier \"Force Input Devices to Seat\"\n" + " Option \"GrabDevice\" \"True\"\n" + "EndSection\n", + device_node); + + fflush(f); + + if (ferror(f)) { + log_error("Failed to write configuration file: %m"); + goto fail; + } + + fclose(f); + f = NULL; + + new_argv = alloca(sizeof(char*) * (argc + 3 + 1)); + memcpy(new_argv, argv, sizeof(char*) * (argc + 2 + 1)); + + new_argv[0] = (char*) X_SERVER; + new_argv[argc+0] = (char*) "-config"; + new_argv[argc+1] = path; + new_argv[argc+2] = (char*) "-sharevts"; + new_argv[argc+3] = NULL; + + udev_enumerate_unref(enumerator); + enumerator = NULL; + + udev_unref(udev); + udev = NULL; + + free(device_node); + device_node = NULL; + + execv(X_SERVER, new_argv); + log_error("Failed to execute real X server: %m"); + +fail: + if (enumerator) + udev_enumerate_unref(enumerator); + + if (udev) + udev_unref(udev); + + free(path); + free(device_node); + + if (f) + fclose(f); + + return EXIT_FAILURE; +} diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf new file mode 100644 index 0000000..9ef852b --- /dev/null +++ b/src/login/org.freedesktop.login1.conf @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/login/org.freedesktop.login1.policy.in b/src/login/org.freedesktop.login1.policy.in new file mode 100644 index 0000000..adc9048 --- /dev/null +++ b/src/login/org.freedesktop.login1.policy.in @@ -0,0 +1,89 @@ + + + + + + + + The systemd Project + http://www.freedesktop.org/wiki/Software/systemd + + + <_description>Allow non-logged-in users to run programs + <_message>Authentication is required to allow a non-logged-in user to run programs + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Allow attaching devices to seats + <_message>Authentication is required to allow attaching a device to a seat + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Flush device to seat attachments + <_message>Authentication is required to allow resetting how devices are attached to seats + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Power off the system + <_message>Authentication is required to allow powering off the system + + auth_admin_keep + auth_admin_keep + yes + + + + + <_description>Power off the system when other users are logged in + <_message>Authentication is required to allow powering off the system while other users are logged in + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Reboot the system + <_message>Authentication is required to allow rebooting the system + + auth_admin_keep + auth_admin_keep + yes + + + + + <_description>Reboot the system when other users are logged in + <_message>Authentication is required to allow rebooting the system while other users are logged in + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + diff --git a/src/login/org.freedesktop.login1.service b/src/login/org.freedesktop.login1.service new file mode 100644 index 0000000..4a64177 --- /dev/null +++ b/src/login/org.freedesktop.login1.service @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# systemd 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. + +[D-BUS Service] +Name=org.freedesktop.login1 +Exec=/bin/false +User=root +SystemdService=dbus-org.freedesktop.login1.service diff --git a/src/login/pam-module.c b/src/login/pam-module.c new file mode 100644 index 0000000..8544413 --- /dev/null +++ b/src/login/pam-module.c @@ -0,0 +1,630 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "util.h" +#include "macro.h" +#include "strv.h" +#include "dbus-common.h" +#include "def.h" +#include "socket-util.h" + +static int parse_argv(pam_handle_t *handle, + int argc, const char **argv, + char ***controllers, + char ***reset_controllers, + bool *kill_processes, + char ***kill_only_users, + char ***kill_exclude_users, + bool *debug) { + + unsigned i; + + assert(argc >= 0); + assert(argc == 0 || argv); + + for (i = 0; i < (unsigned) argc; i++) { + int k; + + if (startswith(argv[i], "kill-session-processes=")) { + if ((k = parse_boolean(argv[i] + 23)) < 0) { + pam_syslog(handle, LOG_ERR, "Failed to parse kill-session-processes= argument."); + return k; + } + + if (kill_processes) + *kill_processes = k; + + } else if (startswith(argv[i], "kill-session=")) { + /* As compatibility for old versions */ + + if ((k = parse_boolean(argv[i] + 13)) < 0) { + pam_syslog(handle, LOG_ERR, "Failed to parse kill-session= argument."); + return k; + } + + if (kill_processes) + *kill_processes = k; + + } else if (startswith(argv[i], "controllers=")) { + + if (controllers) { + char **l; + + if (!(l = strv_split(argv[i] + 12, ","))) { + pam_syslog(handle, LOG_ERR, "Out of memory."); + return -ENOMEM; + } + + strv_free(*controllers); + *controllers = l; + } + + } else if (startswith(argv[i], "reset-controllers=")) { + + if (reset_controllers) { + char **l; + + if (!(l = strv_split(argv[i] + 18, ","))) { + pam_syslog(handle, LOG_ERR, "Out of memory."); + return -ENOMEM; + } + + strv_free(*reset_controllers); + *reset_controllers = l; + } + + } else if (startswith(argv[i], "kill-only-users=")) { + + if (kill_only_users) { + char **l; + + if (!(l = strv_split(argv[i] + 16, ","))) { + pam_syslog(handle, LOG_ERR, "Out of memory."); + return -ENOMEM; + } + + strv_free(*kill_only_users); + *kill_only_users = l; + } + + } else if (startswith(argv[i], "kill-exclude-users=")) { + + if (kill_exclude_users) { + char **l; + + if (!(l = strv_split(argv[i] + 19, ","))) { + pam_syslog(handle, LOG_ERR, "Out of memory."); + return -ENOMEM; + } + + strv_free(*kill_exclude_users); + *kill_exclude_users = l; + } + + } else if (startswith(argv[i], "debug=")) { + if ((k = parse_boolean(argv[i] + 6)) < 0) { + pam_syslog(handle, LOG_ERR, "Failed to parse debug= argument."); + return k; + } + + if (debug) + *debug = k; + + } else if (startswith(argv[i], "create-session=") || + startswith(argv[i], "kill-user=")) { + + pam_syslog(handle, LOG_WARNING, "Option %s not supported anymore, ignoring.", argv[i]); + + } else { + pam_syslog(handle, LOG_ERR, "Unknown parameter '%s'.", argv[i]); + return -EINVAL; + } + } + + return 0; +} + +static int get_user_data( + pam_handle_t *handle, + const char **ret_username, + struct passwd **ret_pw) { + + const char *username = NULL; + struct passwd *pw = NULL; + uid_t uid; + int r; + + assert(handle); + assert(ret_username); + assert(ret_pw); + + r = audit_loginuid_from_pid(0, &uid); + if (r >= 0) + pw = pam_modutil_getpwuid(handle, uid); + else { + r = pam_get_user(handle, &username, NULL); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to get user name."); + return r; + } + + if (isempty(username)) { + pam_syslog(handle, LOG_ERR, "User name not valid."); + return PAM_AUTH_ERR; + } + + pw = pam_modutil_getpwnam(handle, username); + } + + if (!pw) { + pam_syslog(handle, LOG_ERR, "Failed to get user data."); + return PAM_USER_UNKNOWN; + } + + *ret_pw = pw; + *ret_username = username ? username : pw->pw_name; + + return PAM_SUCCESS; +} + +static bool check_user_lists( + pam_handle_t *handle, + uid_t uid, + char **kill_only_users, + char **kill_exclude_users) { + + const char *name = NULL; + char **l; + + assert(handle); + + if (uid == 0) + name = "root"; /* Avoid obvious NSS requests, to suppress network traffic */ + else { + struct passwd *pw; + + pw = pam_modutil_getpwuid(handle, uid); + if (pw) + name = pw->pw_name; + } + + STRV_FOREACH(l, kill_exclude_users) { + uid_t u; + + if (parse_uid(*l, &u) >= 0) + if (u == uid) + return false; + + if (name && streq(name, *l)) + return false; + } + + if (strv_isempty(kill_only_users)) + return true; + + STRV_FOREACH(l, kill_only_users) { + uid_t u; + + if (parse_uid(*l, &u) >= 0) + if (u == uid) + return true; + + if (name && streq(name, *l)) + return true; + } + + return false; +} + +static int get_seat_from_display(const char *display, const char **seat, uint32_t *vtnr) { + char *p = NULL; + int r; + int fd; + union sockaddr_union sa; + struct ucred ucred; + socklen_t l; + char *tty; + int v; + + assert(display); + assert(vtnr); + + /* We deduce the X11 socket from the display name, then use + * SO_PEERCRED to determine the X11 server process, ask for + * the controlling tty of that and if it's a VC then we know + * the seat and the virtual terminal. Sounds ugly, is only + * semi-ugly. */ + + r = socket_from_display(display, &p); + if (r < 0) + return r; + + fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); + if (fd < 0) { + free(p); + return -errno; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, p, sizeof(sa.un.sun_path)-1); + free(p); + + if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) { + close_nointr_nofail(fd); + return -errno; + } + + l = sizeof(ucred); + r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l); + close_nointr_nofail(fd); + + if (r < 0) + return -errno; + + r = get_ctty(ucred.pid, NULL, &tty); + if (r < 0) + return r; + + v = vtnr_from_tty(tty); + free(tty); + + if (v < 0) + return v; + else if (v == 0) + return -ENOENT; + + if (seat) + *seat = "seat0"; + *vtnr = (uint32_t) v; + + return 0; +} + +_public_ PAM_EXTERN int pam_sm_open_session( + pam_handle_t *handle, + int flags, + int argc, const char **argv) { + + struct passwd *pw; + bool kill_processes = false, debug = false; + const char *username, *id, *object_path, *runtime_path, *service = NULL, *tty = NULL, *display = NULL, *remote_user = NULL, *remote_host = NULL, *seat = NULL, *type, *class, *cvtnr = NULL; + char **controllers = NULL, **reset_controllers = NULL, **kill_only_users = NULL, **kill_exclude_users = NULL; + DBusError error; + uint32_t uid, pid; + DBusMessageIter iter; + dbus_bool_t kp; + int session_fd = -1; + DBusConnection *bus = NULL; + DBusMessage *m = NULL, *reply = NULL; + dbus_bool_t remote; + int r; + uint32_t vtnr = 0; + + assert(handle); + + dbus_error_init(&error); + + /* pam_syslog(handle, LOG_INFO, "pam-systemd initializing"); */ + + /* Make this a NOP on non-systemd systems */ + if (sd_booted() <= 0) + return PAM_SUCCESS; + + if (parse_argv(handle, + argc, argv, + &controllers, &reset_controllers, + &kill_processes, &kill_only_users, &kill_exclude_users, + &debug) < 0) { + r = PAM_SESSION_ERR; + goto finish; + } + + r = get_user_data(handle, &username, &pw); + if (r != PAM_SUCCESS) + goto finish; + + /* Make sure we don't enter a loop by talking to + * systemd-logind when it is actually waiting for the + * background to finish start-up. If the service is + * "systemd-shared" we simply set XDG_RUNTIME_DIR and + * leave. */ + + pam_get_item(handle, PAM_SERVICE, (const void**) &service); + if (streq_ptr(service, "systemd-shared")) { + char *p, *rt = NULL; + + if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) pw->pw_uid) < 0) { + r = PAM_BUF_ERR; + goto finish; + } + + r = parse_env_file(p, NEWLINE, + "RUNTIME", &rt, + NULL); + free(p); + + if (r < 0 && r != -ENOENT) { + r = PAM_SESSION_ERR; + free(rt); + goto finish; + } + + if (rt) { + r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", rt, 0); + free(rt); + + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to set runtime dir."); + goto finish; + } + } + + r = PAM_SUCCESS; + goto finish; + } + + if (kill_processes) + kill_processes = check_user_lists(handle, pw->pw_uid, kill_only_users, kill_exclude_users); + + dbus_connection_set_change_sigpipe(FALSE); + + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!bus) { + pam_syslog(handle, LOG_ERR, "Failed to connect to system bus: %s", bus_error_message(&error)); + r = PAM_SESSION_ERR; + goto finish; + } + + m = dbus_message_new_method_call( + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "CreateSession"); + + if (!m) { + pam_syslog(handle, LOG_ERR, "Could not allocate create session message."); + r = PAM_BUF_ERR; + goto finish; + } + + uid = pw->pw_uid; + pid = getpid(); + + pam_get_item(handle, PAM_XDISPLAY, (const void**) &display); + pam_get_item(handle, PAM_TTY, (const void**) &tty); + pam_get_item(handle, PAM_RUSER, (const void**) &remote_user); + pam_get_item(handle, PAM_RHOST, (const void**) &remote_host); + seat = pam_getenv(handle, "XDG_SEAT"); + cvtnr = pam_getenv(handle, "XDG_VTNR"); + + service = strempty(service); + tty = strempty(tty); + display = strempty(display); + remote_user = strempty(remote_user); + remote_host = strempty(remote_host); + seat = strempty(seat); + + if (strchr(tty, ':')) { + /* A tty with a colon is usually an X11 display, place + * there to show up in utmp. We rearrange things and + * don't pretend that an X display was a tty */ + + if (isempty(display)) + display = tty; + tty = ""; + } else if (streq(tty, "cron")) { + /* cron has been setting PAM_TTY to "cron" for a very long time + * and it cannot stop doing that for compatibility reasons. */ + tty = ""; + } + + if (!isempty(cvtnr)) + safe_atou32(cvtnr, &vtnr); + + if (!isempty(display) && vtnr <= 0) { + if (isempty(seat)) + get_seat_from_display(display, &seat, &vtnr); + else if (streq(seat, "seat0")) + get_seat_from_display(display, NULL, &vtnr); + } + + type = !isempty(display) ? "x11" : + !isempty(tty) ? "tty" : "unspecified"; + + class = pam_getenv(handle, "XDG_SESSION_CLASS"); + if (isempty(class)) + class = "user"; + + remote = !isempty(remote_host) && + !streq(remote_host, "localhost") && + !streq(remote_host, "localhost.localdomain"); + + if (!dbus_message_append_args(m, + DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_UINT32, &pid, + DBUS_TYPE_STRING, &service, + DBUS_TYPE_STRING, &type, + DBUS_TYPE_STRING, &class, + DBUS_TYPE_STRING, &seat, + DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_STRING, &tty, + DBUS_TYPE_STRING, &display, + DBUS_TYPE_BOOLEAN, &remote, + DBUS_TYPE_STRING, &remote_user, + DBUS_TYPE_STRING, &remote_host, + DBUS_TYPE_INVALID)) { + pam_syslog(handle, LOG_ERR, "Could not attach parameters to message."); + r = PAM_BUF_ERR; + goto finish; + } + + dbus_message_iter_init_append(m, &iter); + + r = bus_append_strv_iter(&iter, controllers); + if (r < 0) { + pam_syslog(handle, LOG_ERR, "Could not attach parameter to message."); + r = PAM_BUF_ERR; + goto finish; + } + + r = bus_append_strv_iter(&iter, reset_controllers); + if (r < 0) { + pam_syslog(handle, LOG_ERR, "Could not attach parameter to message."); + r = PAM_BUF_ERR; + goto finish; + } + + kp = kill_processes; + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &kp)) { + pam_syslog(handle, LOG_ERR, "Could not attach parameter to message."); + r = PAM_BUF_ERR; + goto finish; + } + + if (debug) + pam_syslog(handle, LOG_DEBUG, "Asking logind to create session: " + "uid=%u pid=%u service=%s type=%s seat=%s vtnr=%u tty=%s display=%s remote=%s remote_user=%s remote_host=%s", + uid, pid, service, type, seat, vtnr, tty, display, yes_no(remote), remote_user, remote_host); + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + pam_syslog(handle, LOG_ERR, "Failed to create session: %s", bus_error_message(&error)); + r = PAM_SESSION_ERR; + goto finish; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_STRING, &id, + DBUS_TYPE_OBJECT_PATH, &object_path, + DBUS_TYPE_STRING, &runtime_path, + DBUS_TYPE_UNIX_FD, &session_fd, + DBUS_TYPE_STRING, &seat, + DBUS_TYPE_UINT32, &vtnr, + DBUS_TYPE_INVALID)) { + pam_syslog(handle, LOG_ERR, "Failed to parse message: %s", bus_error_message(&error)); + r = PAM_SESSION_ERR; + goto finish; + } + + if (debug) + pam_syslog(handle, LOG_DEBUG, "Reply from logind: " + "id=%s object_path=%s runtime_path=%s session_fd=%d seat=%s vtnr=%u", + id, object_path, runtime_path, session_fd, seat, vtnr); + + r = pam_misc_setenv(handle, "XDG_SESSION_ID", id, 0); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to set session id."); + goto finish; + } + + r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", runtime_path, 0); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to set runtime dir."); + goto finish; + } + + if (!isempty(seat)) { + r = pam_misc_setenv(handle, "XDG_SEAT", seat, 0); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to set seat."); + goto finish; + } + } + + if (vtnr > 0) { + char buf[11]; + snprintf(buf, sizeof(buf), "%u", vtnr); + char_array_0(buf); + + r = pam_misc_setenv(handle, "XDG_VTNR", buf, 0); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to set virtual terminal number."); + goto finish; + } + } + + if (session_fd >= 0) { + r = pam_set_data(handle, "systemd.session-fd", INT_TO_PTR(session_fd+1), NULL); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to install session fd."); + return r; + } + } + + session_fd = -1; + + r = PAM_SUCCESS; + +finish: + strv_free(controllers); + strv_free(reset_controllers); + strv_free(kill_only_users); + strv_free(kill_exclude_users); + + dbus_error_free(&error); + + if (bus) { + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + if (session_fd >= 0) + close_nointr_nofail(session_fd); + + return r; +} + +_public_ PAM_EXTERN int pam_sm_close_session( + pam_handle_t *handle, + int flags, + int argc, const char **argv) { + + const void *p = NULL; + + pam_get_data(handle, "systemd.session-fd", &p); + + if (p) + close_nointr(PTR_TO_INT(p) - 1); + + return PAM_SUCCESS; +} diff --git a/src/login/sd-login.c b/src/login/sd-login.c new file mode 100644 index 0000000..887c421 --- /dev/null +++ b/src/login/sd-login.c @@ -0,0 +1,835 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "cgroup-util.h" +#include "macro.h" +#include "sd-login.h" +#include "strv.h" + +static int pid_get_cgroup(pid_t pid, char **root, char **cgroup) { + char *cg_process, *cg_init, *p; + int r; + + if (pid == 0) + pid = getpid(); + + if (pid <= 0) + return -EINVAL; + + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &cg_process); + if (r < 0) + return r; + + r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &cg_init); + if (r < 0) { + free(cg_process); + return r; + } + + if (endswith(cg_init, "/system")) + cg_init[strlen(cg_init)-7] = 0; + else if (streq(cg_init, "/")) + cg_init[0] = 0; + + if (startswith(cg_process, cg_init)) + p = cg_process + strlen(cg_init); + else + p = cg_process; + + free(cg_init); + + if (cgroup) { + char* c; + + c = strdup(p); + if (!c) { + free(cg_process); + return -ENOMEM; + } + + *cgroup = c; + } + + if (root) { + cg_process[p-cg_process] = 0; + *root = cg_process; + } else + free(cg_process); + + return 0; +} + +_public_ int sd_pid_get_session(pid_t pid, char **session) { + int r; + char *cgroup, *p; + + if (!session) + return -EINVAL; + + r = pid_get_cgroup(pid, NULL, &cgroup); + if (r < 0) + return r; + + if (!startswith(cgroup, "/user/")) { + free(cgroup); + return -ENOENT; + } + + p = strchr(cgroup + 6, '/'); + if (!p) { + free(cgroup); + return -ENOENT; + } + + p++; + if (startswith(p, "shared/") || streq(p, "shared")) { + free(cgroup); + return -ENOENT; + } + + p = strndup(p, strcspn(p, "/")); + free(cgroup); + + if (!p) + return -ENOMEM; + + *session = p; + return 0; +} + +_public_ int sd_pid_get_unit(pid_t pid, char **unit) { + int r; + char *cgroup, *p, *at, *b; + size_t k; + + if (!unit) + return -EINVAL; + + r = pid_get_cgroup(pid, NULL, &cgroup); + if (r < 0) + return r; + + if (!startswith(cgroup, "/system/")) { + free(cgroup); + return -ENOENT; + } + + p = cgroup + 8; + k = strcspn(p, "/"); + + at = memchr(p, '@', k); + if (at && at[1] == '.') { + size_t j; + + /* This is a templated service */ + if (p[k] != '/') { + free(cgroup); + return -EIO; + } + + j = strcspn(p+k+1, "/"); + + b = malloc(k + j + 1); + + if (b) { + memcpy(b, p, at - p + 1); + memcpy(b + (at - p) + 1, p + k + 1, j); + memcpy(b + (at - p) + 1 + j, at + 1, k - (at - p) - 1); + b[k+j] = 0; + } + } else + b = strndup(p, k); + + free(cgroup); + + if (!b) + return -ENOMEM; + + *unit = b; + return 0; +} + +_public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) { + int r; + char *root, *cgroup, *p, *cc; + struct stat st; + + if (!uid) + return -EINVAL; + + r = pid_get_cgroup(pid, &root, &cgroup); + if (r < 0) + return r; + + if (!startswith(cgroup, "/user/")) { + free(cgroup); + free(root); + return -ENOENT; + } + + p = strchr(cgroup + 6, '/'); + if (!p) { + free(cgroup); + return -ENOENT; + } + + p++; + p += strcspn(p, "/"); + *p = 0; + + r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, root, cgroup, &cc); + free(root); + free(cgroup); + + if (r < 0) + return -ENOMEM; + + r = lstat(cc, &st); + free(cc); + + if (r < 0) + return -errno; + + if (!S_ISDIR(st.st_mode)) + return -ENOTDIR; + + *uid = st.st_uid; + return 0; +} + +_public_ int sd_uid_get_state(uid_t uid, char**state) { + char *p, *s = NULL; + int r; + + if (!state) + return -EINVAL; + + if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) uid) < 0) + return -ENOMEM; + + r = parse_env_file(p, NEWLINE, "STATE", &s, NULL); + free(p); + + if (r == -ENOENT) { + free(s); + s = strdup("offline"); + if (!s) + return -ENOMEM; + + *state = s; + return 0; + } else if (r < 0) { + free(s); + return r; + } else if (!s) + return -EIO; + + *state = s; + return 0; +} + +_public_ int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) { + char *p, *w, *t, *state, *s = NULL; + size_t l; + int r; + const char *variable; + + if (!seat) + return -EINVAL; + + variable = require_active ? "ACTIVE_UID" : "UIDS"; + + p = strappend("/run/systemd/seats/", seat); + if (!p) + return -ENOMEM; + + r = parse_env_file(p, NEWLINE, variable, &s, NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } + + if (!s) + return -EIO; + + if (asprintf(&t, "%lu", (unsigned long) uid) < 0) { + free(s); + return -ENOMEM; + } + + FOREACH_WORD(w, l, s, state) { + if (strncmp(t, w, l) == 0) { + free(s); + free(t); + + return 1; + } + } + + free(s); + free(t); + + return 0; +} + +static int uid_get_array(uid_t uid, const char *variable, char ***array) { + char *p, *s = NULL; + char **a; + int r; + + if (asprintf(&p, "/run/systemd/users/%lu", (unsigned long) uid) < 0) + return -ENOMEM; + + r = parse_env_file(p, NEWLINE, + variable, &s, + NULL); + free(p); + + if (r < 0) { + free(s); + + if (r == -ENOENT) { + if (array) + *array = NULL; + return 0; + } + + return r; + } + + if (!s) { + if (array) + *array = NULL; + return 0; + } + + a = strv_split(s, " "); + free(s); + + if (!a) + return -ENOMEM; + + strv_uniq(a); + r = strv_length(a); + + if (array) + *array = a; + else + strv_free(a); + + return r; +} + +_public_ int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions) { + return uid_get_array(uid, require_active ? "ACTIVE_SESSIONS" : "SESSIONS", sessions); +} + +_public_ int sd_uid_get_seats(uid_t uid, int require_active, char ***seats) { + return uid_get_array(uid, require_active ? "ACTIVE_SEATS" : "SEATS", seats); +} + +static int file_of_session(const char *session, char **_p) { + char *p; + int r; + + assert(_p); + + if (session) + p = strappend("/run/systemd/sessions/", session); + else { + char *buf; + + r = sd_pid_get_session(0, &buf); + if (r < 0) + return r; + + p = strappend("/run/systemd/sessions/", buf); + free(buf); + } + + if (!p) + return -ENOMEM; + + *_p = p; + return 0; +} + +_public_ int sd_session_is_active(const char *session) { + int r; + char *p, *s = NULL; + + r = file_of_session(session, &p); + if (r < 0) + return r; + + r = parse_env_file(p, NEWLINE, "ACTIVE", &s, NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } + + if (!s) + return -EIO; + + r = parse_boolean(s); + free(s); + + return r; +} + +_public_ int sd_session_get_uid(const char *session, uid_t *uid) { + int r; + char *p, *s = NULL; + + if (!uid) + return -EINVAL; + + r = file_of_session(session, &p); + if (r < 0) + return r; + + r = parse_env_file(p, NEWLINE, "UID", &s, NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } + + if (!s) + return -EIO; + + r = parse_uid(s, uid); + free(s); + + return r; +} + +static int session_get_string(const char *session, const char *field, char **value) { + char *p, *s = NULL; + int r; + + if (!value) + return -EINVAL; + + r = file_of_session(session, &p); + if (r < 0) + return r; + + r = parse_env_file(p, NEWLINE, field, &s, NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } + + if (isempty(s)) + return -ENOENT; + + *value = s; + return 0; +} + +_public_ int sd_session_get_seat(const char *session, char **seat) { + return session_get_string(session, "SEAT", seat); +} + +_public_ int sd_session_get_service(const char *session, char **service) { + return session_get_string(session, "SERVICE", service); +} + +_public_ int sd_session_get_type(const char *session, char **type) { + return session_get_string(session, "TYPE", type); +} + +_public_ int sd_session_get_class(const char *session, char **class) { + return session_get_string(session, "CLASS", class); +} + +_public_ int sd_session_get_display(const char *session, char **display) { + return session_get_string(session, "DISPLAY", display); +} + +static int file_of_seat(const char *seat, char **_p) { + char *p; + int r; + + assert(_p); + + if (seat) + p = strappend("/run/systemd/seats/", seat); + else { + char *buf; + + r = sd_session_get_seat(NULL, &buf); + if (r < 0) + return r; + + p = strappend("/run/systemd/seats/", buf); + free(buf); + } + + if (!p) + return -ENOMEM; + + *_p = p; + return 0; +} + +_public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) { + char *p, *s = NULL, *t = NULL; + int r; + + if (!session && !uid) + return -EINVAL; + + r = file_of_seat(seat, &p); + if (r < 0) + return r; + + r = parse_env_file(p, NEWLINE, + "ACTIVE", &s, + "ACTIVE_UID", &t, + NULL); + free(p); + + if (r < 0) { + free(s); + free(t); + return r; + } + + if (session && !s) { + free(t); + return -ENOENT; + } + + if (uid && !t) { + free(s); + return -ENOENT; + } + + if (uid && t) { + r = parse_uid(t, uid); + if (r < 0) { + free(t); + free(s); + return r; + } + } + + free(t); + + if (session && s) + *session = s; + else + free(s); + + return 0; +} + +_public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uids, unsigned *n_uids) { + char *p, *s = NULL, *t = NULL, **a = NULL; + uid_t *b = NULL; + unsigned n = 0; + int r; + + r = file_of_seat(seat, &p); + if (r < 0) + return r; + + r = parse_env_file(p, NEWLINE, + "SESSIONS", &s, + "ACTIVE_SESSIONS", &t, + NULL); + free(p); + + if (r < 0) { + free(s); + free(t); + return r; + } + + if (s) { + a = strv_split(s, " "); + if (!a) { + free(s); + free(t); + return -ENOMEM; + } + } + + free(s); + + if (uids && t) { + char *w, *state; + size_t l; + + FOREACH_WORD(w, l, t, state) + n++; + + if (n == 0) + b = NULL; + else { + unsigned i = 0; + + b = new(uid_t, n); + if (!b) { + strv_free(a); + return -ENOMEM; + } + + FOREACH_WORD(w, l, t, state) { + char *k; + + k = strndup(w, l); + if (!k) { + free(t); + free(b); + strv_free(a); + return -ENOMEM; + } + + r = parse_uid(k, b + i); + free(k); + if (r < 0) + continue; + + i++; + } + } + } + + free(t); + + r = strv_length(a); + + if (sessions) + *sessions = a; + else + strv_free(a); + + if (uids) + *uids = b; + + if (n_uids) + *n_uids = n; + + return r; +} + +_public_ int sd_seat_can_multi_session(const char *seat) { + char *p, *s = NULL; + int r; + + r = file_of_seat(seat, &p); + if (r < 0) + return r; + + r = parse_env_file(p, NEWLINE, + "CAN_MULTI_SESSION", &s, + NULL); + free(p); + + if (r < 0) { + free(s); + return r; + } + + if (s) { + r = parse_boolean(s); + free(s); + } else + r = 0; + + return r; +} + +_public_ int sd_get_seats(char ***seats) { + return get_files_in_directory("/run/systemd/seats/", seats); +} + +_public_ int sd_get_sessions(char ***sessions) { + return get_files_in_directory("/run/systemd/sessions/", sessions); +} + +_public_ int sd_get_uids(uid_t **users) { + DIR *d; + int r = 0; + unsigned n = 0; + uid_t *l = NULL; + + d = opendir("/run/systemd/users/"); + if (!d) + return -errno; + + for (;;) { + struct dirent buffer, *de; + int k; + uid_t uid; + + k = readdir_r(d, &buffer, &de); + if (k != 0) { + r = -k; + goto finish; + } + + if (!de) + break; + + dirent_ensure_type(d, de); + + if (!dirent_is_file(de)) + continue; + + k = parse_uid(de->d_name, &uid); + if (k < 0) + continue; + + if (users) { + if ((unsigned) r >= n) { + uid_t *t; + + n = MAX(16, 2*r); + t = realloc(l, sizeof(uid_t) * n); + if (!t) { + r = -ENOMEM; + goto finish; + } + + l = t; + } + + assert((unsigned) r < n); + l[r++] = uid; + } else + r++; + } + +finish: + if (d) + closedir(d); + + if (r >= 0) { + if (users) + *users = l; + } else + free(l); + + return r; +} + +static inline int MONITOR_TO_FD(sd_login_monitor *m) { + return (int) (unsigned long) m - 1; +} + +static inline sd_login_monitor* FD_TO_MONITOR(int fd) { + return (sd_login_monitor*) (unsigned long) (fd + 1); +} + +_public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) { + int fd, k; + bool good = false; + + if (!m) + return -EINVAL; + + fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); + if (fd < 0) + return errno; + + if (!category || streq(category, "seat")) { + k = inotify_add_watch(fd, "/run/systemd/seats/", IN_MOVED_TO|IN_DELETE); + if (k < 0) { + close_nointr_nofail(fd); + return -errno; + } + + good = true; + } + + if (!category || streq(category, "session")) { + k = inotify_add_watch(fd, "/run/systemd/sessions/", IN_MOVED_TO|IN_DELETE); + if (k < 0) { + close_nointr_nofail(fd); + return -errno; + } + + good = true; + } + + if (!category || streq(category, "uid")) { + k = inotify_add_watch(fd, "/run/systemd/users/", IN_MOVED_TO|IN_DELETE); + if (k < 0) { + close_nointr_nofail(fd); + return -errno; + } + + good = true; + } + + if (!good) { + close_nointr(fd); + return -EINVAL; + } + + *m = FD_TO_MONITOR(fd); + return 0; +} + +_public_ sd_login_monitor* sd_login_monitor_unref(sd_login_monitor *m) { + int fd; + + if (!m) + return NULL; + + fd = MONITOR_TO_FD(m); + close_nointr(fd); + + return NULL; +} + +_public_ int sd_login_monitor_flush(sd_login_monitor *m) { + + if (!m) + return -EINVAL; + + return flush_fd(MONITOR_TO_FD(m)); +} + +_public_ int sd_login_monitor_get_fd(sd_login_monitor *m) { + + if (!m) + return -EINVAL; + + return MONITOR_TO_FD(m); +} diff --git a/src/login/sysfs-show.c b/src/login/sysfs-show.c new file mode 100644 index 0000000..b8b356d --- /dev/null +++ b/src/login/sysfs-show.c @@ -0,0 +1,187 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "util.h" +#include "sysfs-show.h" + +static int show_sysfs_one( + struct udev *udev, + const char *seat, + struct udev_list_entry **item, + const char *sub, + const char *prefix, + unsigned n_columns) { + + assert(udev); + assert(seat); + assert(item); + assert(prefix); + + while (*item) { + struct udev_list_entry *next, *lookahead; + struct udev_device *d; + const char *sn, *name, *sysfs, *subsystem, *sysname; + char *l, *k; + + sysfs = udev_list_entry_get_name(*item); + if (!path_startswith(sysfs, sub)) + return 0; + + d = udev_device_new_from_syspath(udev, sysfs); + if (!d) { + *item = udev_list_entry_get_next(*item); + continue; + } + + sn = udev_device_get_property_value(d, "ID_SEAT"); + if (isempty(sn)) + sn = "seat0"; + + /* fixme, also check for tag 'seat' here */ + if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) { + udev_device_unref(d); + *item = udev_list_entry_get_next(*item); + continue; + } + + name = udev_device_get_sysattr_value(d, "name"); + if (!name) + name = udev_device_get_sysattr_value(d, "id"); + subsystem = udev_device_get_subsystem(d); + sysname = udev_device_get_sysname(d); + + /* Look if there's more coming after this */ + lookahead = next = udev_list_entry_get_next(*item); + while (lookahead) { + const char *lookahead_sysfs; + + lookahead_sysfs = udev_list_entry_get_name(lookahead); + + if (path_startswith(lookahead_sysfs, sub) && + !path_startswith(lookahead_sysfs, sysfs)) { + struct udev_device *lookahead_d; + + lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs); + if (lookahead_d) { + const char *lookahead_sn; + bool found; + + lookahead_sn = udev_device_get_property_value(d, "ID_SEAT"); + if (isempty(lookahead_sn)) + lookahead_sn = "seat0"; + + found = streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat"); + udev_device_unref(lookahead_d); + + if (found) + break; + } + } + + lookahead = udev_list_entry_get_next(lookahead); + } + + k = ellipsize(sysfs, n_columns, 20); + printf("%s%s %s\n", prefix, lookahead ? "\342\224\234" : "\342\224\224", k ? k : sysfs); + free(k); + + if (asprintf(&l, + "(%s:%s)%s%s%s", + subsystem, sysname, + name ? " \"" : "", name ? name : "", name ? "\"" : "") < 0) { + udev_device_unref(d); + return -ENOMEM; + } + + k = ellipsize(l, n_columns, 70); + printf("%s%s %s\n", prefix, lookahead ? "\342\224\202" : " ", k ? k : l); + free(k); + free(l); + + *item = next; + if (*item) { + char *p; + + p = strappend(prefix, lookahead ? "\342\224\202 " : " "); + show_sysfs_one(udev, seat, item, sysfs, p ? p : prefix, n_columns - 2); + free(p); + } + + udev_device_unref(d); + } + + return 0; +} + +int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) { + struct udev *udev; + struct udev_list_entry *first = NULL; + struct udev_enumerate *e; + int r; + + if (n_columns <= 0) + n_columns = columns(); + + if (!prefix) + prefix = ""; + + if (isempty(seat)) + seat = "seat0"; + + udev = udev_new(); + if (!udev) + return -ENOMEM; + + e = udev_enumerate_new(udev); + if (!e) { + r = -ENOMEM; + goto finish; + } + + if (!streq(seat, "seat0")) + r = udev_enumerate_add_match_tag(e, seat); + else + r = udev_enumerate_add_match_tag(e, "seat"); + + if (r < 0) + goto finish; + + r = udev_enumerate_scan_devices(e); + if (r < 0) + goto finish; + + first = udev_enumerate_get_list_entry(e); + if (first) + show_sysfs_one(udev, seat, &first, "/", prefix, n_columns); + +finish: + if (e) + udev_enumerate_unref(e); + + if (udev) + udev_unref(udev); + + return r; +} diff --git a/src/login/systemd-logind.conf b/src/login/systemd-logind.conf new file mode 100644 index 0000000..9909804 --- /dev/null +++ b/src/login/systemd-logind.conf @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd 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. +# +# See system-logind.conf(5) for details + +[Login] +#NAutoVTs=6 +#KillUserProcesses=no +#KillOnlyUsers= +#KillExcludeUsers=root +#Controllers= +#ResetControllers=cpu diff --git a/src/login/test-login.c b/src/login/test-login.c new file mode 100644 index 0000000..dd84042 --- /dev/null +++ b/src/login/test-login.c @@ -0,0 +1,188 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include + +#include "util.h" +#include "strv.h" + +int main(int argc, char* argv[]) { + int r, k; + uid_t u, u2; + char *seat, *type, *class, *display; + char *session; + char *state; + char *session2; + char *t; + char **seats, **sessions; + uid_t *uids; + unsigned n; + struct pollfd pollfd; + sd_login_monitor *m; + + assert_se(sd_pid_get_session(0, &session) == 0); + printf("session = %s\n", session); + + assert_se(sd_pid_get_owner_uid(0, &u2) == 0); + printf("user = %lu\n", (unsigned long) u2); + + r = sd_uid_get_sessions(u2, false, &sessions); + assert_se(r >= 0); + assert_se(r == (int) strv_length(sessions)); + assert_se(t = strv_join(sessions, ", ")); + strv_free(sessions); + printf("sessions = %s\n", t); + free(t); + + assert_se(r == sd_uid_get_sessions(u2, false, NULL)); + + r = sd_uid_get_seats(u2, false, &seats); + assert_se(r >= 0); + assert_se(r == (int) strv_length(seats)); + assert_se(t = strv_join(seats, ", ")); + strv_free(seats); + printf("seats = %s\n", t); + free(t); + + assert_se(r == sd_uid_get_seats(u2, false, NULL)); + + r = sd_session_is_active(session); + assert_se(r >= 0); + printf("active = %s\n", yes_no(r)); + + assert_se(sd_session_get_uid(session, &u) >= 0); + printf("uid = %lu\n", (unsigned long) u); + assert_se(u == u2); + + assert_se(sd_session_get_type(session, &type) >= 0); + printf("type = %s\n", type); + free(type); + + assert_se(sd_session_get_class(session, &class) >= 0); + printf("class = %s\n", class); + free(class); + + assert_se(sd_session_get_display(session, &display) >= 0); + printf("display = %s\n", display); + free(display); + + assert_se(sd_session_get_seat(session, &seat) >= 0); + printf("seat = %s\n", seat); + + r = sd_seat_can_multi_session(seat); + assert_se(r >= 0); + printf("can do multi session = %s\n", yes_no(r)); + + assert_se(sd_uid_get_state(u, &state) >= 0); + printf("state = %s\n", state); + + assert_se(sd_uid_is_on_seat(u, 0, seat) > 0); + + k = sd_uid_is_on_seat(u, 1, seat); + assert_se(k >= 0); + assert_se(!!r == !!r); + + assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0); + printf("session2 = %s\n", session2); + printf("uid2 = %lu\n", (unsigned long) u2); + + r = sd_seat_get_sessions(seat, &sessions, &uids, &n); + assert_se(r >= 0); + printf("n_sessions = %i\n", r); + assert_se(r == (int) strv_length(sessions)); + assert_se(t = strv_join(sessions, ", ")); + strv_free(sessions); + printf("sessions = %s\n", t); + free(t); + printf("uids ="); + for (k = 0; k < (int) n; k++) + printf(" %lu", (unsigned long) uids[k]); + printf("\n"); + free(uids); + + assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r); + + free(session); + free(state); + free(session2); + free(seat); + + r = sd_get_seats(&seats); + assert_se(r >= 0); + assert_se(r == (int) strv_length(seats)); + assert_se(t = strv_join(seats, ", ")); + strv_free(seats); + printf("n_seats = %i\n", r); + printf("seats = %s\n", t); + free(t); + + assert_se(sd_get_seats(NULL) == r); + + r = sd_seat_get_active(NULL, &t, NULL); + assert_se(r >= 0); + printf("active session on current seat = %s\n", t); + free(t); + + r = sd_get_sessions(&sessions); + assert_se(r >= 0); + assert_se(r == (int) strv_length(sessions)); + assert_se(t = strv_join(sessions, ", ")); + strv_free(sessions); + printf("n_sessions = %i\n", r); + printf("sessions = %s\n", t); + free(t); + + assert_se(sd_get_sessions(NULL) == r); + + r = sd_get_uids(&uids); + assert_se(r >= 0); + + printf("uids ="); + for (k = 0; k < r; k++) + printf(" %lu", (unsigned long) uids[k]); + printf("\n"); + free(uids); + + printf("n_uids = %i\n", r); + assert_se(sd_get_uids(NULL) == r); + + r = sd_login_monitor_new("session", &m); + assert_se(r >= 0); + + zero(pollfd); + pollfd.fd = sd_login_monitor_get_fd(m); + pollfd.events = POLLIN; + + for (n = 0; n < 5; n++) { + r = poll(&pollfd, 1, -1); + assert_se(r >= 0); + + sd_login_monitor_flush(m); + printf("Wake!\n"); + } + + sd_login_monitor_unref(m); + + return 0; +} diff --git a/src/login/uaccess.c b/src/login/uaccess.c new file mode 100644 index 0000000..e1af5bf --- /dev/null +++ b/src/login/uaccess.c @@ -0,0 +1,91 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include +#include + +#include "logind-acl.h" +#include "util.h" +#include "log.h" + +int main(int argc, char *argv[]) { + int r; + const char *path = NULL, *seat; + bool changed_acl = false; + uid_t uid; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc < 2 || argc > 3) { + log_error("This program expects one or two arguments."); + r = -EINVAL; + goto finish; + } + + /* Make sure we don't muck around with ACLs the system is not + * running systemd. */ + if (!sd_booted()) + return 0; + + path = argv[1]; + seat = argc < 3 || isempty(argv[2]) ? "seat0" : argv[2]; + + r = sd_seat_get_active(seat, NULL, &uid); + if (r == -ENOENT) { + /* No active session on this seat */ + r = 0; + goto finish; + } else if (r < 0) { + log_error("Failed to determine active user on seat %s.", seat); + goto finish; + } + + r = devnode_acl(path, true, false, 0, true, uid); + if (r < 0) { + log_error("Failed to apply ACL on %s: %s", path, strerror(-r)); + goto finish; + } + + changed_acl = true; + r = 0; + +finish: + if (path && !changed_acl) { + int k; + /* Better be safe that sorry and reset ACL */ + + k = devnode_acl(path, true, false, 0, false, 0); + if (k < 0) { + log_error("Failed to apply ACL on %s: %s", path, strerror(-k)); + if (r >= 0) + r = k; + } + } + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/login/user-sessions.c b/src/login/user-sessions.c new file mode 100644 index 0000000..64aa3bb --- /dev/null +++ b/src/login/user-sessions.c @@ -0,0 +1,100 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "cgroup-util.h" + +int main(int argc, char*argv[]) { + int ret = EXIT_FAILURE; + + if (argc != 2) { + log_error("This program requires one argument."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (streq(argv[1], "start")) { + int q = 0, r = 0; + + if (unlink("/run/nologin") < 0 && errno != ENOENT) { + log_error("Failed to remove /run/nologin file: %m"); + r = -errno; + } + + if (unlink("/etc/nologin") < 0 && errno != ENOENT) { + + /* If the file doesn't exist and /etc simply + * was read-only (in which case unlink() + * returns EROFS even if the file doesn't + * exist), don't complain */ + + if (errno != EROFS || access("/etc/nologin", F_OK) >= 0) { + log_error("Failed to remove /etc/nologin file: %m"); + q = -errno; + } + } + + if (r < 0 || q < 0) + goto finish; + + } else if (streq(argv[1], "stop")) { + int r, q; + char *cgroup_user_tree = NULL; + + if ((r = write_one_line_file_atomic("/run/nologin", "System is going down.")) < 0) + log_error("Failed to create /run/nologin: %s", strerror(-r)); + + if ((q = cg_get_user_path(&cgroup_user_tree)) < 0) { + log_error("Failed to determine use path: %s", strerror(-q)); + goto finish; + } + + q = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, cgroup_user_tree, true); + free(cgroup_user_tree); + + if (q < 0) { + log_error("Failed to kill sessions: %s", strerror(-q)); + goto finish; + } + + if (r < 0) + goto finish; + + } else { + log_error("Unknown verb %s.", argv[1]); + goto finish; + } + + ret = EXIT_SUCCESS; + +finish: + return ret; +} diff --git a/src/logs-show.c b/src/logs-show.c new file mode 100644 index 0000000..f023f0a --- /dev/null +++ b/src/logs-show.c @@ -0,0 +1,668 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2012 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "logs-show.h" +#include "log.h" +#include "util.h" + +#define PRINT_THRESHOLD 128 + +static bool contains_unprintable(const void *p, size_t l) { + const char *j; + + for (j = p; j < (const char *) p + l; j++) + if (*j < ' ' || *j >= 127) + return true; + + return false; +} + +static int parse_field(const void *data, size_t length, const char *field, char **target, size_t *target_size) { + size_t fl, nl; + void *buf; + + assert(data); + assert(field); + assert(target); + assert(target_size); + + fl = strlen(field); + if (length < fl) + return 0; + + if (memcmp(data, field, fl)) + return 0; + + nl = length - fl; + buf = malloc(nl+1); + memcpy(buf, (const char*) data + fl, nl); + ((char*)buf)[nl] = 0; + if (!buf) { + log_error("Out of memory"); + return -ENOMEM; + } + + free(*target); + *target = buf; + *target_size = nl; + + return 1; +} + +static bool shall_print(bool show_all, char *p, size_t l) { + if (show_all) + return true; + + if (l > PRINT_THRESHOLD) + return false; + + if (contains_unprintable(p, l)) + return false; + + return true; +} + +static int output_short(sd_journal *j, unsigned line, bool show_all, bool monotonic_mode) { + int r; + const void *data; + size_t length; + size_t n = 0; + char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = NULL; + size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0; + + assert(j); + + SD_JOURNAL_FOREACH_DATA(j, data, length) { + + r = parse_field(data, length, "_HOSTNAME=", &hostname, &hostname_len); + if (r < 0) + goto finish; + else if (r > 0) + continue; + + r = parse_field(data, length, "SYSLOG_IDENTIFIER=", &identifier, &identifier_len); + if (r < 0) + goto finish; + else if (r > 0) + continue; + + r = parse_field(data, length, "_COMM=", &comm, &comm_len); + if (r < 0) + goto finish; + else if (r > 0) + continue; + + r = parse_field(data, length, "_PID=", &pid, &pid_len); + if (r < 0) + goto finish; + else if (r > 0) + continue; + + r = parse_field(data, length, "SYSLOG_PID=", &fake_pid, &fake_pid_len); + if (r < 0) + goto finish; + else if (r > 0) + continue; + + r = parse_field(data, length, "_SOURCE_REALTIME_TIMESTAMP=", &realtime, &realtime_len); + if (r < 0) + goto finish; + else if (r > 0) + continue; + + r = parse_field(data, length, "_SOURCE_MONOTONIC_TIMESTAMP=", &monotonic, &monotonic_len); + if (r < 0) + goto finish; + else if (r > 0) + continue; + + r = parse_field(data, length, "MESSAGE=", &message, &message_len); + if (r < 0) + goto finish; + } + + if (!message) { + r = 0; + goto finish; + } + + if (monotonic_mode) { + uint64_t t; + sd_id128_t boot_id; + + r = -ENOENT; + + if (monotonic) + r = safe_atou64(monotonic, &t); + + if (r < 0) + r = sd_journal_get_monotonic_usec(j, &t, &boot_id); + + if (r < 0) { + log_error("Failed to get monotonic: %s", strerror(-r)); + goto finish; + } + + printf("[%5llu.%06llu]", + (unsigned long long) (t / USEC_PER_SEC), + (unsigned long long) (t % USEC_PER_SEC)); + + n += 1 + 5 + 1 + 6 + 1; + + } else { + char buf[64]; + uint64_t x; + time_t t; + struct tm tm; + + r = -ENOENT; + + if (realtime) + r = safe_atou64(realtime, &x); + + if (r < 0) + r = sd_journal_get_realtime_usec(j, &x); + + if (r < 0) { + log_error("Failed to get realtime: %s", strerror(-r)); + goto finish; + } + + t = (time_t) (x / USEC_PER_SEC); + if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S", localtime_r(&t, &tm)) <= 0) { + log_error("Failed to format time."); + goto finish; + } + + fputs(buf, stdout); + n += strlen(buf); + } + + if (hostname && shall_print(show_all, hostname, hostname_len)) { + printf(" %.*s", (int) hostname_len, hostname); + n += hostname_len + 1; + } + + if (identifier && shall_print(show_all, identifier, identifier_len)) { + printf(" %.*s", (int) identifier_len, identifier); + n += identifier_len + 1; + } else if (comm && shall_print(show_all, comm, comm_len)) { + printf(" %.*s", (int) comm_len, comm); + n += comm_len + 1; + } + + if (pid && shall_print(show_all, pid, pid_len)) { + printf("[%.*s]", (int) pid_len, pid); + n += pid_len + 2; + } else if (fake_pid && shall_print(show_all, fake_pid, fake_pid_len)) { + printf("[%.*s]", (int) fake_pid_len, fake_pid); + n += fake_pid_len + 2; + } + + if (show_all) + printf(": %.*s\n", (int) message_len, message); + else if (contains_unprintable(message, message_len)) { + char bytes[FORMAT_BYTES_MAX]; + printf(": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len)); + } else if (message_len + n < columns()) + printf(": %.*s\n", (int) message_len, message); + else if (n < columns()) { + char *e; + + e = ellipsize_mem(message, message_len, columns() - n - 2, 90); + + if (!e) + printf(": %.*s\n", (int) message_len, message); + else + printf(": %s\n", e); + + free(e); + } else + fputs("\n", stdout); + + r = 0; + +finish: + free(hostname); + free(identifier); + free(comm); + free(pid); + free(fake_pid); + free(message); + free(monotonic); + free(realtime); + + return r; +} + +static int output_short_realtime(sd_journal *j, unsigned line, bool show_all) { + return output_short(j, line, show_all, false); +} + +static int output_short_monotonic(sd_journal *j, unsigned line, bool show_all) { + return output_short(j, line, show_all, true); +} + +static int output_verbose(sd_journal *j, unsigned line, bool show_all) { + const void *data; + size_t length; + char *cursor; + uint64_t realtime; + char ts[FORMAT_TIMESTAMP_MAX]; + int r; + + assert(j); + + r = sd_journal_get_realtime_usec(j, &realtime); + if (r < 0) { + log_error("Failed to get realtime timestamp: %s", strerror(-r)); + return r; + } + + r = sd_journal_get_cursor(j, &cursor); + if (r < 0) { + log_error("Failed to get cursor: %s", strerror(-r)); + return r; + } + + printf("%s [%s]\n", + format_timestamp(ts, sizeof(ts), realtime), + cursor); + + free(cursor); + + SD_JOURNAL_FOREACH_DATA(j, data, length) { + if (!show_all && (length > PRINT_THRESHOLD || + contains_unprintable(data, length))) { + const char *c; + char bytes[FORMAT_BYTES_MAX]; + + c = memchr(data, '=', length); + if (!c) { + log_error("Invalid field."); + return -EINVAL; + } + + printf("\t%.*s=[%s blob data]\n", + (int) (c - (const char*) data), + (const char*) data, + format_bytes(bytes, sizeof(bytes), length - (c - (const char *) data) - 1)); + } else + printf("\t%.*s\n", (int) length, (const char*) data); + } + + return 0; +} + +static int output_export(sd_journal *j, unsigned line, bool show_all) { + sd_id128_t boot_id; + char sid[33]; + int r; + usec_t realtime, monotonic; + char *cursor; + const void *data; + size_t length; + + assert(j); + + r = sd_journal_get_realtime_usec(j, &realtime); + if (r < 0) { + log_error("Failed to get realtime timestamp: %s", strerror(-r)); + return r; + } + + r = sd_journal_get_monotonic_usec(j, &monotonic, &boot_id); + if (r < 0) { + log_error("Failed to get monotonic timestamp: %s", strerror(-r)); + return r; + } + + r = sd_journal_get_cursor(j, &cursor); + if (r < 0) { + log_error("Failed to get cursor: %s", strerror(-r)); + return r; + } + + printf(".cursor=%s\n" + ".realtime=%llu\n" + ".monotonic=%llu\n" + ".boot_id=%s\n", + cursor, + (unsigned long long) realtime, + (unsigned long long) monotonic, + sd_id128_to_string(boot_id, sid)); + + free(cursor); + + SD_JOURNAL_FOREACH_DATA(j, data, length) { + + if (contains_unprintable(data, length)) { + const char *c; + uint64_t le64; + + c = memchr(data, '=', length); + if (!c) { + log_error("Invalid field."); + return -EINVAL; + } + + fwrite(data, c - (const char*) data, 1, stdout); + fputc('\n', stdout); + le64 = htole64(length - (c - (const char*) data) - 1); + fwrite(&le64, sizeof(le64), 1, stdout); + fwrite(c + 1, length - (c - (const char*) data) - 1, 1, stdout); + } else + fwrite(data, length, 1, stdout); + + fputc('\n', stdout); + } + + fputc('\n', stdout); + + return 0; +} + +static void json_escape(const char* p, size_t l) { + + if (contains_unprintable(p, l)) { + bool not_first = false; + + fputs("[ ", stdout); + + while (l > 0) { + if (not_first) + printf(", %u", (uint8_t) *p); + else { + not_first = true; + printf("%u", (uint8_t) *p); + } + + p++; + l--; + } + + fputs(" ]", stdout); + } else { + fputc('\"', stdout); + + while (l > 0) { + if (*p == '"' || *p == '\\') { + fputc('\\', stdout); + fputc(*p, stdout); + } else + fputc(*p, stdout); + + p++; + l--; + } + + fputc('\"', stdout); + } +} + +static int output_json(sd_journal *j, unsigned line, bool show_all) { + uint64_t realtime, monotonic; + char *cursor; + const void *data; + size_t length; + sd_id128_t boot_id; + char sid[33]; + int r; + + assert(j); + + r = sd_journal_get_realtime_usec(j, &realtime); + if (r < 0) { + log_error("Failed to get realtime timestamp: %s", strerror(-r)); + return r; + } + + r = sd_journal_get_monotonic_usec(j, &monotonic, &boot_id); + if (r < 0) { + log_error("Failed to get monotonic timestamp: %s", strerror(-r)); + return r; + } + + r = sd_journal_get_cursor(j, &cursor); + if (r < 0) { + log_error("Failed to get cursor: %s", strerror(-r)); + return r; + } + + if (line == 1) + fputc('\n', stdout); + else + fputs(",\n", stdout); + + printf("{\n" + "\t\".cursor\" : \"%s\",\n" + "\t\".realtime\" : %llu,\n" + "\t\".monotonic\" : %llu,\n" + "\t\".boot_id\" : \"%s\"", + cursor, + (unsigned long long) realtime, + (unsigned long long) monotonic, + sd_id128_to_string(boot_id, sid)); + + free(cursor); + + SD_JOURNAL_FOREACH_DATA(j, data, length) { + const char *c; + + c = memchr(data, '=', length); + if (!c) { + log_error("Invalid field."); + return -EINVAL; + } + + fputs(",\n\t", stdout); + json_escape(data, c - (const char*) data); + fputs(" : ", stdout); + json_escape(c + 1, length - (c - (const char*) data) - 1); + } + + fputs("\n}", stdout); + fflush(stdout); + + return 0; +} + +static int output_cat(sd_journal *j, unsigned line, bool show_all) { + const void *data; + size_t l; + int r; + + assert(j); + + r = sd_journal_get_data(j, "MESSAGE", &data, &l); + if (r < 0) { + log_error("Failed to get data: %s", strerror(-r)); + return r; + } + + assert(l >= 8); + + fwrite((const char*) data + 8, 1, l - 8, stdout); + putchar('\n'); + + return 0; +} + +static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, unsigned line, bool show_all) = { + [OUTPUT_SHORT] = output_short_realtime, + [OUTPUT_SHORT_MONOTONIC] = output_short_monotonic, + [OUTPUT_VERBOSE] = output_verbose, + [OUTPUT_EXPORT] = output_export, + [OUTPUT_JSON] = output_json, + [OUTPUT_CAT] = output_cat +}; + +int output_journal(sd_journal *j, OutputMode mode, unsigned line, bool show_all) { + assert(mode >= 0); + assert(mode < _OUTPUT_MODE_MAX); + + return output_funcs[mode](j, line, show_all); +} + +int show_journal_by_unit( + const char *unit, + OutputMode mode, + const char *prefix, + unsigned n_columns, + usec_t not_before, + unsigned how_many, + bool show_all, + bool follow) { + + char *m = NULL; + sd_journal *j; + int r; + int fd; + unsigned line = 0; + bool need_seek = false; + + assert(mode >= 0); + assert(mode < _OUTPUT_MODE_MAX); + assert(unit); + + if (!endswith(unit, ".service") && + !endswith(unit, ".socket") && + !endswith(unit, ".mount") && + !endswith(unit, ".swap")) + return 0; + + if (how_many <= 0) + return 0; + + if (n_columns <= 0) + n_columns = columns(); + + if (!prefix) + prefix = ""; + + if (asprintf(&m, "_SYSTEMD_UNIT=%s", unit) < 0) { + r = -ENOMEM; + goto finish; + } + + r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM_ONLY); + if (r < 0) + goto finish; + + fd = sd_journal_get_fd(j); + if (fd < 0) + goto finish; + + r = sd_journal_add_match(j, m, strlen(m)); + if (r < 0) + goto finish; + + r = sd_journal_seek_tail(j); + if (r < 0) + goto finish; + + r = sd_journal_previous_skip(j, how_many); + if (r < 0) + goto finish; + + if (mode == OUTPUT_JSON) { + fputc('[', stdout); + fflush(stdout); + } + + for (;;) { + for (;;) { + usec_t usec; + + if (need_seek) { + r = sd_journal_next(j); + if (r < 0) + goto finish; + } + + if (r == 0) + break; + + need_seek = true; + + if (not_before > 0) { + r = sd_journal_get_monotonic_usec(j, &usec, NULL); + + /* -ESTALE is returned if the + timestamp is not from this boot */ + if (r == -ESTALE) + continue; + else if (r < 0) + goto finish; + + if (usec < not_before) + continue; + } + + line ++; + + r = output_journal(j, mode, line, show_all); + if (r < 0) + goto finish; + } + + if (!follow) + break; + + r = fd_wait_for_event(fd, POLLIN, (usec_t) -1); + if (r < 0) + goto finish; + + r = sd_journal_process(j); + if (r < 0) + goto finish; + + } + + if (mode == OUTPUT_JSON) + fputs("\n]\n", stdout); + +finish: + if (m) + free(m); + + if (j) + sd_journal_close(j); + + return r; +} + +static const char *const output_mode_table[_OUTPUT_MODE_MAX] = { + [OUTPUT_SHORT] = "short", + [OUTPUT_SHORT_MONOTONIC] = "short-monotonic", + [OUTPUT_VERBOSE] = "verbose", + [OUTPUT_EXPORT] = "export", + [OUTPUT_JSON] = "json", + [OUTPUT_CAT] = "cat" +}; + +DEFINE_STRING_TABLE_LOOKUP(output_mode, OutputMode); diff --git a/src/logs-show.h b/src/logs-show.h new file mode 100644 index 0000000..abb82c8 --- /dev/null +++ b/src/logs-show.h @@ -0,0 +1,57 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foologsshowhfoo +#define foologsshowhfoo + +/*** + This file is part of systemd. + + Copyright 2012 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include + +#include "util.h" + +typedef enum OutputMode { + OUTPUT_SHORT, + OUTPUT_SHORT_MONOTONIC, + OUTPUT_VERBOSE, + OUTPUT_EXPORT, + OUTPUT_JSON, + OUTPUT_CAT, + _OUTPUT_MODE_MAX, + _OUTPUT_MODE_INVALID = -1 +} OutputMode; + +int output_journal(sd_journal *j, OutputMode mode, unsigned line, bool show_all); + +int show_journal_by_unit( + const char *unit, + OutputMode mode, + const char *prefix, + unsigned n_columns, + usec_t not_before, + unsigned how_many, + bool show_all, + bool follow); + +const char* output_mode_to_string(OutputMode m); +OutputMode output_mode_from_string(const char *s); + +#endif diff --git a/src/loopback-setup.c b/src/loopback-setup.c new file mode 100644 index 0000000..b6359de --- /dev/null +++ b/src/loopback-setup.c @@ -0,0 +1,274 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "macro.h" +#include "loopback-setup.h" +#include "socket-util.h" + +#define NLMSG_TAIL(nmsg) \ + ((struct rtattr *) (((uint8_t*) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) + +static int add_rtattr(struct nlmsghdr *n, size_t max_length, int type, const void *data, size_t data_length) { + size_t length; + struct rtattr *rta; + + length = RTA_LENGTH(data_length); + + if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length) > max_length) + return -E2BIG; + + rta = NLMSG_TAIL(n); + rta->rta_type = type; + rta->rta_len = length; + memcpy(RTA_DATA(rta), data, data_length); + n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(length); + + return 0; +} + +static ssize_t sendto_loop(int fd, const void *buf, size_t buf_len, int flags, const struct sockaddr *sa, socklen_t sa_len) { + + for (;;) { + ssize_t l; + + if ((l = sendto(fd, buf, buf_len, flags, sa, sa_len)) >= 0) + return l; + + if (errno != EINTR) + return -errno; + } +} + +static ssize_t recvfrom_loop(int fd, void *buf, size_t buf_len, int flags, struct sockaddr *sa, socklen_t *sa_len) { + + for (;;) { + ssize_t l; + + if ((l = recvfrom(fd, buf, buf_len, flags, sa, sa_len)) >= 0) + return l; + + if (errno != EINTR) + return -errno; + } +} + +static int add_adresses(int fd, int if_loopback, unsigned *requests) { + union { + struct sockaddr sa; + struct sockaddr_nl nl; + } sa; + union { + struct nlmsghdr header; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct ifaddrmsg)) + + RTA_LENGTH(sizeof(struct in6_addr))]; + } request; + + struct ifaddrmsg *ifaddrmsg; + uint32_t ipv4_address = htonl(INADDR_LOOPBACK); + int r; + + zero(request); + + request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); + request.header.nlmsg_type = RTM_NEWADDR; + request.header.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK; + request.header.nlmsg_seq = *requests + 1; + + ifaddrmsg = NLMSG_DATA(&request.header); + ifaddrmsg->ifa_family = AF_INET; + ifaddrmsg->ifa_prefixlen = 8; + ifaddrmsg->ifa_flags = IFA_F_PERMANENT; + ifaddrmsg->ifa_scope = RT_SCOPE_HOST; + ifaddrmsg->ifa_index = if_loopback; + + if ((r = add_rtattr(&request.header, sizeof(request), IFA_LOCAL, &ipv4_address, sizeof(ipv4_address))) < 0) + return r; + + zero(sa); + sa.nl.nl_family = AF_NETLINK; + + if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0) + return -errno; + (*requests)++; + + if (!socket_ipv6_is_supported()) + return 0; + + request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); + request.header.nlmsg_seq = *requests + 1; + + ifaddrmsg->ifa_family = AF_INET6; + ifaddrmsg->ifa_prefixlen = 128; + + if ((r = add_rtattr(&request.header, sizeof(request), IFA_LOCAL, &in6addr_loopback, sizeof(in6addr_loopback))) < 0) + return r; + + if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0) + return -errno; + (*requests)++; + + return 0; +} + +static int start_interface(int fd, int if_loopback, unsigned *requests) { + union { + struct sockaddr sa; + struct sockaddr_nl nl; + } sa; + union { + struct nlmsghdr header; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct ifinfomsg))]; + } request; + + struct ifinfomsg *ifinfomsg; + + zero(request); + + request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + request.header.nlmsg_type = RTM_NEWLINK; + request.header.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK; + request.header.nlmsg_seq = *requests + 1; + + ifinfomsg = NLMSG_DATA(&request.header); + ifinfomsg->ifi_family = AF_UNSPEC; + ifinfomsg->ifi_index = if_loopback; + ifinfomsg->ifi_flags = IFF_UP; + ifinfomsg->ifi_change = IFF_UP; + + zero(sa); + sa.nl.nl_family = AF_NETLINK; + + if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0) + return -errno; + + (*requests)++; + + return 0; +} + +static int read_response(int fd, unsigned requests_max) { + union { + struct sockaddr sa; + struct sockaddr_nl nl; + } sa; + union { + struct nlmsghdr header; + uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct nlmsgerr))]; + } response; + + ssize_t l; + socklen_t sa_len = sizeof(sa); + struct nlmsgerr *nlmsgerr; + + if ((l = recvfrom_loop(fd, &response, sizeof(response), 0, &sa.sa, &sa_len)) < 0) + return -errno; + + if (sa_len != sizeof(sa.nl) || + sa.nl.nl_family != AF_NETLINK) + return -EIO; + + if (sa.nl.nl_pid != 0) + return 0; + + if ((size_t) l < sizeof(struct nlmsghdr)) + return -EIO; + + if (response.header.nlmsg_type != NLMSG_ERROR || + (pid_t) response.header.nlmsg_pid != getpid() || + response.header.nlmsg_seq >= requests_max) + return 0; + + if ((size_t) l < NLMSG_LENGTH(sizeof(struct nlmsgerr)) || + response.header.nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) + return -EIO; + + nlmsgerr = NLMSG_DATA(&response.header); + + if (nlmsgerr->error < 0 && nlmsgerr->error != -EEXIST) { + log_warning("Netlink failure for request %i: %s", response.header.nlmsg_seq, strerror(-nlmsgerr->error)); + return nlmsgerr->error; + } + + return response.header.nlmsg_seq; +} + +int loopback_setup(void) { + int r, if_loopback; + union { + struct sockaddr sa; + struct sockaddr_nl nl; + struct sockaddr_storage storage; + } sa; + unsigned requests = 0, i; + int fd; + + errno = 0; + if ((if_loopback = (int) if_nametoindex("lo")) <= 0) + return errno ? -errno : -ENODEV; + + if ((fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) + return -errno; + + zero(sa); + sa.nl.nl_family = AF_NETLINK; + + if (bind(fd, &sa.sa, sizeof(sa)) < 0) { + r = -errno; + goto finish; + } + + if ((r = add_adresses(fd, if_loopback, &requests)) < 0) + goto finish; + + if ((r = start_interface(fd, if_loopback, &requests)) < 0) + goto finish; + + for (i = 0; i < requests; i++) { + if ((r = read_response(fd, requests)) < 0) + goto finish; + } + + r = 0; + +finish: + if (r < 0) + log_warning("Failed to configure loopback device: %s", strerror(-r)); + + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} diff --git a/src/loopback-setup.h b/src/loopback-setup.h new file mode 100644 index 0000000..81f4529 --- /dev/null +++ b/src/loopback-setup.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooloopbacksetuphfoo +#define fooloopbacksetuphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +int loopback_setup(void); + +#endif diff --git a/src/machine-id-main.c b/src/machine-id-main.c new file mode 100644 index 0000000..03970a2 --- /dev/null +++ b/src/machine-id-main.c @@ -0,0 +1,35 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "machine-id-setup.h" +#include "log.h" + +int main(int argc, char *argv[]) { + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + return machine_id_setup() < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/machine-id-setup.c b/src/machine-id-setup.c new file mode 100644 index 0000000..531f3b2 --- /dev/null +++ b/src/machine-id-setup.c @@ -0,0 +1,175 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "machine-id-setup.h" +#include "macro.h" +#include "util.h" +#include "log.h" + +static int generate(char id[34]) { + int fd, r; + unsigned char *p; + sd_id128_t buf; + char *q; + ssize_t k; + + assert(id); + + /* First, try reading the D-Bus machine id, unless it is a symlink */ + fd = open("/var/lib/dbus/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); + if (fd >= 0) { + + k = loop_read(fd, id, 33, false); + close_nointr_nofail(fd); + + if (k >= 32) { + id[32] = '\n'; + id[33] = 0; + + log_info("Initializing machine ID from D-Bus machine ID."); + return 0; + } + } + + /* If that didn't work, generate a random machine id */ + r = sd_id128_randomize(&buf); + if (r < 0) { + log_error("Failed to open /dev/urandom: %s", strerror(-r)); + return r; + } + + for (p = buf.bytes, q = id; p < buf.bytes + sizeof(buf); p++, q += 2) { + q[0] = hexchar(*p >> 4); + q[1] = hexchar(*p & 15); + } + + id[32] = '\n'; + id[33] = 0; + + log_info("Initializing machine ID from random generator."); + + return 0; +} + +int machine_id_setup(void) { + int fd, r; + bool writable; + struct stat st; + char id[34]; /* 32 + \n + \0 */ + mode_t m; + + m = umask(0000); + + /* We create this 0444, to indicate that this isn't really + * something you should ever modify. Of course, since the file + * will be owned by root it doesn't matter much, but maybe + * people look. */ + + fd = open("/etc/machine-id", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444); + if (fd >= 0) + writable = true; + else { + fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) { + umask(m); + log_error("Cannot open /etc/machine-id: %m"); + return -errno; + } + + writable = false; + } + + umask(m); + + if (fstat(fd, &st) < 0) { + log_error("fstat() failed: %m"); + r = -errno; + goto finish; + } + + if (S_ISREG(st.st_mode)) { + if (loop_read(fd, id, 32, false) >= 32) { + r = 0; + goto finish; + } + } + + /* Hmm, so, the id currently stored is not useful, then let's + * generate one */ + + r = generate(id); + if (r < 0) + goto finish; + + if (S_ISREG(st.st_mode) && writable) { + lseek(fd, 0, SEEK_SET); + + if (loop_write(fd, id, 33, false) == 33) { + r = 0; + goto finish; + } + } + + close_nointr_nofail(fd); + fd = -1; + + /* Hmm, we couldn't write it? So let's write it to + * /run/systemd/machine-id as a replacement */ + + mkdir_p("/run/systemd", 0755); + + m = umask(0022); + r = write_one_line_file("/run/systemd/machine-id", id); + umask(m); + + if (r < 0) { + log_error("Cannot write /run/systemd/machine-id: %s", strerror(-r)); + + unlink("/run/systemd/machine-id"); + goto finish; + } + + /* And now, let's mount it over */ + r = mount("/run/systemd/machine-id", "/etc/machine-id", "bind", MS_BIND|MS_RDONLY, NULL) < 0 ? -errno : 0; + unlink("/run/systemd/machine-id"); + + if (r < 0) + log_error("Failed to mount /etc/machine-id: %s", strerror(-r)); + else + log_info("Installed transient /etc/machine-id file."); + +finish: + + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} diff --git a/src/machine-id-setup.h b/src/machine-id-setup.h new file mode 100644 index 0000000..4d0a9cf --- /dev/null +++ b/src/machine-id-setup.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foomachineidsetuphfoo +#define foomachineidsetuphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +int machine_id_setup(void); + +#endif diff --git a/src/macro.h b/src/macro.h new file mode 100644 index 0000000..58de001 --- /dev/null +++ b/src/macro.h @@ -0,0 +1,180 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foomacrohfoo +#define foomacrohfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#define _printf_attr_(a,b) __attribute__ ((format (printf, a, b))) +#define _sentinel_ __attribute__ ((sentinel)) +#define _noreturn_ __attribute__((noreturn)) +#define _unused_ __attribute__ ((unused)) +#define _destructor_ __attribute__ ((destructor)) +#define _pure_ __attribute__ ((pure)) +#define _const_ __attribute__ ((const)) +#define _deprecated_ __attribute__ ((deprecated)) +#define _packed_ __attribute__ ((packed)) +#define _malloc_ __attribute__ ((malloc)) +#define _weak_ __attribute__ ((weak)) +#define _likely_(x) (__builtin_expect(!!(x),1)) +#define _unlikely_(x) (__builtin_expect(!!(x),0)) +#define _public_ __attribute__ ((visibility("default"))) +#define _hidden_ __attribute__ ((visibility("hidden"))) +#define _weakref_(x) __attribute__((weakref(#x))) +#define _introspect_(x) __attribute__((section("introspect." x))) + +#define XSTRINGIFY(x) #x +#define STRINGIFY(x) XSTRINGIFY(x) + +/* Rounds up */ +#define ALIGN(l) ALIGN_TO((l), sizeof(void*)) +static inline size_t ALIGN_TO(size_t l, size_t ali) { + return ((l + ali - 1) & ~(ali - 1)); +} + +#define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0])) + +#ifndef MAX +#define MAX(a,b) \ + __extension__ ({ \ + typeof(a) _a = (a); \ + typeof(b) _b = (b); \ + _a > _b ? _a : _b; \ + }) +#endif + +#define MAX3(a,b,c) \ + MAX(MAX(a,b),c) + +#ifndef MIN +#define MIN(a,b) \ + __extension__ ({ \ + typeof(a) _a = (a); \ + typeof(b) _b = (b); \ + _a < _b ? _a : _b; \ + }) +#endif + +#define MIN3(a,b,c) \ + MIN(MIN(a,b),c) + +#define CLAMP(x, low, high) \ + __extension__ ({ \ + typeof(x) _x = (x); \ + typeof(low) _low = (low); \ + typeof(high) _high = (high); \ + ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \ + }) + +#define assert_se(expr) \ + do { \ + if (_unlikely_(!(expr))) \ + log_assert_failed(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ + } while (false) \ + +/* We override the glibc assert() here. */ +#undef assert +#ifdef NDEBUG +#define assert(expr) do {} while(false) +#else +#define assert(expr) assert_se(expr) +#endif + +#define assert_not_reached(t) \ + do { \ + log_assert_failed_unreachable(t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ + } while (false) + +#define assert_cc(expr) \ + do { \ + switch (0) { \ + case 0: \ + case !!(expr): \ + ; \ + } \ + } while (false) + +#define PTR_TO_UINT(p) ((unsigned int) ((uintptr_t) (p))) +#define UINT_TO_PTR(u) ((void*) ((uintptr_t) (u))) + +#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p))) +#define UINT32_TO_PTR(u) ((void*) ((uintptr_t) (u))) + +#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p))) +#define ULONG_TO_PTR(u) ((void*) ((uintptr_t) (u))) + +#define PTR_TO_INT(p) ((int) ((intptr_t) (p))) +#define INT_TO_PTR(u) ((void*) ((intptr_t) (u))) + +#define TO_INT32(p) ((int32_t) ((intptr_t) (p))) +#define INT32_TO_PTR(u) ((void*) ((intptr_t) (u))) + +#define PTR_TO_LONG(p) ((long) ((intptr_t) (p))) +#define LONG_TO_PTR(u) ((void*) ((intptr_t) (u))) + +#define memzero(x,l) (memset((x), 0, (l))) +#define zero(x) (memzero(&(x), sizeof(x))) + +#define char_array_0(x) x[sizeof(x)-1] = 0; + +#define IOVEC_SET_STRING(i, s) \ + do { \ + struct iovec *_i = &(i); \ + char *_s = (char *)(s); \ + _i->iov_base = _s; \ + _i->iov_len = strlen(_s); \ + } while(false) + +static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) { + unsigned j; + size_t r = 0; + + for (j = 0; j < n; j++) + r += i[j].iov_len; + + return r; +} + +static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) { + unsigned j; + + for (j = 0; j < n; j++) { + size_t sub; + + if (_unlikely_(k <= 0)) + break; + + sub = MIN(i[j].iov_len, k); + i[j].iov_len -= sub; + i[j].iov_base = (uint8_t*) i[j].iov_base + sub; + k -= sub; + } + + return k; +} + +#include "log.h" + +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..ed317b4 --- /dev/null +++ b/src/main.c @@ -0,0 +1,1628 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "manager.h" +#include "log.h" +#include "mount-setup.h" +#include "hostname-setup.h" +#include "loopback-setup.h" +#include "kmod-setup.h" +#include "locale-setup.h" +#include "selinux-setup.h" +#include "machine-id-setup.h" +#include "load-fragment.h" +#include "fdset.h" +#include "special.h" +#include "conf-parser.h" +#include "bus-errors.h" +#include "missing.h" +#include "label.h" +#include "build.h" +#include "strv.h" +#include "def.h" +#include "virt.h" + +static enum { + ACTION_RUN, + ACTION_HELP, + ACTION_TEST, + ACTION_DUMP_CONFIGURATION_ITEMS, + ACTION_DONE +} arg_action = ACTION_RUN; + +static char *arg_default_unit = NULL; +static ManagerRunningAs arg_running_as = _MANAGER_RUNNING_AS_INVALID; + +static bool arg_dump_core = true; +static bool arg_crash_shell = false; +static int arg_crash_chvt = -1; +static bool arg_confirm_spawn = false; +static bool arg_show_status = true; +#ifdef HAVE_SYSV_COMPAT +static bool arg_sysv_console = true; +#endif +static bool arg_mount_auto = true; +static bool arg_swap_auto = true; +static char **arg_default_controllers = NULL; +static char ***arg_join_controllers = NULL; +static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL; +static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT; + +static FILE* serialization = NULL; + +static void nop_handler(int sig) { +} + +_noreturn_ static void crash(int sig) { + + if (!arg_dump_core) + log_error("Caught <%s>, not dumping core.", signal_to_string(sig)); + else { + struct sigaction sa; + pid_t pid; + + /* We want to wait for the core process, hence let's enable SIGCHLD */ + zero(sa); + sa.sa_handler = nop_handler; + sa.sa_flags = SA_NOCLDSTOP|SA_RESTART; + assert_se(sigaction(SIGCHLD, &sa, NULL) == 0); + + if ((pid = fork()) < 0) + log_error("Caught <%s>, cannot fork for core dump: %s", signal_to_string(sig), strerror(errno)); + + else if (pid == 0) { + struct rlimit rl; + + /* Enable default signal handler for core dump */ + zero(sa); + sa.sa_handler = SIG_DFL; + assert_se(sigaction(sig, &sa, NULL) == 0); + + /* Don't limit the core dump size */ + zero(rl); + rl.rlim_cur = RLIM_INFINITY; + rl.rlim_max = RLIM_INFINITY; + setrlimit(RLIMIT_CORE, &rl); + + /* Just to be sure... */ + assert_se(chdir("/") == 0); + + /* Raise the signal again */ + raise(sig); + + assert_not_reached("We shouldn't be here..."); + _exit(1); + + } else { + siginfo_t status; + int r; + + /* Order things nicely. */ + if ((r = wait_for_terminate(pid, &status)) < 0) + log_error("Caught <%s>, waitpid() failed: %s", signal_to_string(sig), strerror(-r)); + else if (status.si_code != CLD_DUMPED) + log_error("Caught <%s>, core dump failed.", signal_to_string(sig)); + else + log_error("Caught <%s>, dumped core as pid %lu.", signal_to_string(sig), (unsigned long) pid); + } + } + + if (arg_crash_chvt) + chvt(arg_crash_chvt); + + if (arg_crash_shell) { + struct sigaction sa; + pid_t pid; + + log_info("Executing crash shell in 10s..."); + sleep(10); + + /* Let the kernel reap children for us */ + zero(sa); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART; + assert_se(sigaction(SIGCHLD, &sa, NULL) == 0); + + if ((pid = fork()) < 0) + log_error("Failed to fork off crash shell: %s", strerror(errno)); + else if (pid == 0) { + int fd, r; + + if ((fd = acquire_terminal("/dev/console", false, true, true)) < 0) + log_error("Failed to acquire terminal: %s", strerror(-fd)); + else if ((r = make_stdio(fd)) < 0) + log_error("Failed to duplicate terminal fd: %s", strerror(-r)); + + execl("/bin/sh", "/bin/sh", NULL); + + log_error("execl() failed: %s", strerror(errno)); + _exit(1); + } + + log_info("Successfully spawned crash shell as pid %lu.", (unsigned long) pid); + } + + log_info("Freezing execution."); + freeze(); +} + +static void install_crash_handler(void) { + struct sigaction sa; + + zero(sa); + + sa.sa_handler = crash; + sa.sa_flags = SA_NODEFER; + + sigaction_many(&sa, SIGNALS_CRASH_HANDLER, -1); +} + +static int console_setup(bool do_reset) { + int tty_fd, r; + + /* If we are init, we connect stdin/stdout/stderr to /dev/null + * and make sure we don't have a controlling tty. */ + + release_terminal(); + + if (!do_reset) + return 0; + + tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (tty_fd < 0) { + log_error("Failed to open /dev/console: %s", strerror(-tty_fd)); + return -tty_fd; + } + + /* We don't want to force text mode. + * plymouth may be showing pictures already from initrd. */ + r = reset_terminal_fd(tty_fd, false); + if (r < 0) + log_error("Failed to reset /dev/console: %s", strerror(-r)); + + close_nointr_nofail(tty_fd); + return r; +} + +static int set_default_unit(const char *u) { + char *c; + + assert(u); + + if (!(c = strdup(u))) + return -ENOMEM; + + free(arg_default_unit); + arg_default_unit = c; + return 0; +} + +static int parse_proc_cmdline_word(const char *word) { + + static const char * const rlmap[] = { + "emergency", SPECIAL_EMERGENCY_TARGET, + "-b", SPECIAL_EMERGENCY_TARGET, + "single", SPECIAL_RESCUE_TARGET, + "-s", SPECIAL_RESCUE_TARGET, + "s", SPECIAL_RESCUE_TARGET, + "S", SPECIAL_RESCUE_TARGET, + "1", SPECIAL_RESCUE_TARGET, + "2", SPECIAL_RUNLEVEL2_TARGET, + "3", SPECIAL_RUNLEVEL3_TARGET, + "4", SPECIAL_RUNLEVEL4_TARGET, + "5", SPECIAL_RUNLEVEL5_TARGET, + }; + + assert(word); + + if (startswith(word, "systemd.unit=")) + return set_default_unit(word + 13); + + else if (startswith(word, "systemd.log_target=")) { + + if (log_set_target_from_string(word + 19) < 0) + log_warning("Failed to parse log target %s. Ignoring.", word + 19); + + } else if (startswith(word, "systemd.log_level=")) { + + if (log_set_max_level_from_string(word + 18) < 0) + log_warning("Failed to parse log level %s. Ignoring.", word + 18); + + } else if (startswith(word, "systemd.log_color=")) { + + if (log_show_color_from_string(word + 18) < 0) + log_warning("Failed to parse log color setting %s. Ignoring.", word + 18); + + } else if (startswith(word, "systemd.log_location=")) { + + if (log_show_location_from_string(word + 21) < 0) + log_warning("Failed to parse log location setting %s. Ignoring.", word + 21); + + } else if (startswith(word, "systemd.dump_core=")) { + int r; + + if ((r = parse_boolean(word + 18)) < 0) + log_warning("Failed to parse dump core switch %s. Ignoring.", word + 18); + else + arg_dump_core = r; + + } else if (startswith(word, "systemd.crash_shell=")) { + int r; + + if ((r = parse_boolean(word + 20)) < 0) + log_warning("Failed to parse crash shell switch %s. Ignoring.", word + 20); + else + arg_crash_shell = r; + + } else if (startswith(word, "systemd.confirm_spawn=")) { + int r; + + if ((r = parse_boolean(word + 22)) < 0) + log_warning("Failed to parse confirm spawn switch %s. Ignoring.", word + 22); + else + arg_confirm_spawn = r; + + } else if (startswith(word, "systemd.crash_chvt=")) { + int k; + + if (safe_atoi(word + 19, &k) < 0) + log_warning("Failed to parse crash chvt switch %s. Ignoring.", word + 19); + else + arg_crash_chvt = k; + + } else if (startswith(word, "systemd.show_status=")) { + int r; + + if ((r = parse_boolean(word + 20)) < 0) + log_warning("Failed to parse show status switch %s. Ignoring.", word + 20); + else + arg_show_status = r; + } else if (startswith(word, "systemd.default_standard_output=")) { + int r; + + if ((r = exec_output_from_string(word + 32)) < 0) + log_warning("Failed to parse default standard output switch %s. Ignoring.", word + 32); + else + arg_default_std_output = r; + } else if (startswith(word, "systemd.default_standard_error=")) { + int r; + + if ((r = exec_output_from_string(word + 31)) < 0) + log_warning("Failed to parse default standard error switch %s. Ignoring.", word + 31); + else + arg_default_std_error = r; + } else if (startswith(word, "systemd.setenv=")) { + char *cenv, *eq; + int r; + + cenv = strdup(word + 15); + if (!cenv) + return -ENOMEM; + + eq = strchr(cenv, '='); + if (!eq) { + r = unsetenv(cenv); + if (r < 0) + log_warning("unsetenv failed %s. Ignoring.", strerror(errno)); + } else { + *eq = 0; + r = setenv(cenv, eq + 1, 1); + if (r < 0) + log_warning("setenv failed %s. Ignoring.", strerror(errno)); + } + free(cenv); +#ifdef HAVE_SYSV_COMPAT + } else if (startswith(word, "systemd.sysv_console=")) { + int r; + + if ((r = parse_boolean(word + 21)) < 0) + log_warning("Failed to parse SysV console switch %s. Ignoring.", word + 20); + else + arg_sysv_console = r; +#endif + + } else if (startswith(word, "systemd.")) { + + log_warning("Unknown kernel switch %s. Ignoring.", word); + + log_info("Supported kernel switches:\n" + "systemd.unit=UNIT Default unit to start\n" + "systemd.dump_core=0|1 Dump core on crash\n" + "systemd.crash_shell=0|1 Run shell on crash\n" + "systemd.crash_chvt=N Change to VT #N on crash\n" + "systemd.confirm_spawn=0|1 Confirm every process spawn\n" + "systemd.show_status=0|1 Show status updates on the console during bootup\n" +#ifdef HAVE_SYSV_COMPAT + "systemd.sysv_console=0|1 Connect output of SysV scripts to console\n" +#endif + "systemd.log_target=console|kmsg|journal|journal-or-kmsg|syslog|syslog-or-kmsg|null\n" + " Log target\n" + "systemd.log_level=LEVEL Log level\n" + "systemd.log_color=0|1 Highlight important log messages\n" + "systemd.log_location=0|1 Include code location in log messages\n" + "systemd.default_standard_output=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n" + " Set default log output for services\n" + "systemd.default_standard_error=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n" + " Set default log error output for services\n"); + + } else if (streq(word, "quiet")) { + arg_show_status = false; +#ifdef HAVE_SYSV_COMPAT + arg_sysv_console = false; +#endif + } else { + unsigned i; + + /* SysV compatibility */ + for (i = 0; i < ELEMENTSOF(rlmap); i += 2) + if (streq(word, rlmap[i])) + return set_default_unit(rlmap[i+1]); + } + + return 0; +} + +static int config_parse_level2( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + assert(filename); + assert(lvalue); + assert(rvalue); + + log_set_max_level_from_string(rvalue); + return 0; +} + +static int config_parse_target( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + assert(filename); + assert(lvalue); + assert(rvalue); + + log_set_target_from_string(rvalue); + return 0; +} + +static int config_parse_color( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + assert(filename); + assert(lvalue); + assert(rvalue); + + log_show_color_from_string(rvalue); + return 0; +} + +static int config_parse_location( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + assert(filename); + assert(lvalue); + assert(rvalue); + + log_show_location_from_string(rvalue); + return 0; +} + +static int config_parse_cpu_affinity2( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + char *w; + size_t l; + char *state; + cpu_set_t *c = NULL; + unsigned ncpus = 0; + + assert(filename); + assert(lvalue); + assert(rvalue); + + FOREACH_WORD_QUOTED(w, l, rvalue, state) { + char *t; + int r; + unsigned cpu; + + if (!(t = strndup(w, l))) + return -ENOMEM; + + r = safe_atou(t, &cpu); + free(t); + + if (!c) + if (!(c = cpu_set_malloc(&ncpus))) + return -ENOMEM; + + if (r < 0 || cpu >= ncpus) { + log_error("[%s:%u] Failed to parse CPU affinity: %s", filename, line, rvalue); + CPU_FREE(c); + return -EBADMSG; + } + + CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c); + } + + if (c) { + if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0) + log_warning("Failed to set CPU affinity: %m"); + + CPU_FREE(c); + } + + return 0; +} + +static void strv_free_free(char ***l) { + char ***i; + + if (!l) + return; + + for (i = l; *i; i++) + strv_free(*i); + + free(l); +} + +static void free_join_controllers(void) { + if (!arg_join_controllers) + return; + + strv_free_free(arg_join_controllers); + arg_join_controllers = NULL; +} + +static int config_parse_join_controllers( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + unsigned n = 0; + char *state, *w; + size_t length; + + assert(filename); + assert(lvalue); + assert(rvalue); + + free_join_controllers(); + + FOREACH_WORD_QUOTED(w, length, rvalue, state) { + char *s, **l; + + s = strndup(w, length); + if (!s) + return -ENOMEM; + + l = strv_split(s, ","); + free(s); + + strv_uniq(l); + + if (strv_length(l) <= 1) { + strv_free(l); + continue; + } + + if (!arg_join_controllers) { + arg_join_controllers = new(char**, 2); + if (!arg_join_controllers) { + strv_free(l); + return -ENOMEM; + } + + arg_join_controllers[0] = l; + arg_join_controllers[1] = NULL; + + n = 1; + } else { + char ***a; + char ***t; + + t = new0(char**, n+2); + if (!t) { + strv_free(l); + return -ENOMEM; + } + + n = 0; + + for (a = arg_join_controllers; *a; a++) { + + if (strv_overlap(*a, l)) { + char **c; + + c = strv_merge(*a, l); + if (!c) { + strv_free(l); + strv_free_free(t); + return -ENOMEM; + } + + strv_free(l); + l = c; + } else { + char **c; + + c = strv_copy(*a); + if (!c) { + strv_free(l); + strv_free_free(t); + return -ENOMEM; + } + + t[n++] = c; + } + } + + t[n++] = strv_uniq(l); + + strv_free_free(arg_join_controllers); + arg_join_controllers = t; + } + } + + return 0; +} + +static int parse_config_file(void) { + + const ConfigTableItem items[] = { + { "Manager", "LogLevel", config_parse_level2, 0, NULL }, + { "Manager", "LogTarget", config_parse_target, 0, NULL }, + { "Manager", "LogColor", config_parse_color, 0, NULL }, + { "Manager", "LogLocation", config_parse_location, 0, NULL }, + { "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core }, + { "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell }, + { "Manager", "ShowStatus", config_parse_bool, 0, &arg_show_status }, +#ifdef HAVE_SYSV_COMPAT + { "Manager", "SysVConsole", config_parse_bool, 0, &arg_sysv_console }, +#endif + { "Manager", "CrashChVT", config_parse_int, 0, &arg_crash_chvt }, + { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL }, + { "Manager", "MountAuto", config_parse_bool, 0, &arg_mount_auto }, + { "Manager", "SwapAuto", config_parse_bool, 0, &arg_swap_auto }, + { "Manager", "DefaultControllers", config_parse_strv, 0, &arg_default_controllers }, + { "Manager", "DefaultStandardOutput", config_parse_output, 0, &arg_default_std_output }, + { "Manager", "DefaultStandardError", config_parse_output, 0, &arg_default_std_error }, + { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers }, + { NULL, NULL, NULL, 0, NULL } + }; + + FILE *f; + const char *fn; + int r; + + fn = arg_running_as == MANAGER_SYSTEM ? SYSTEM_CONFIG_FILE : USER_CONFIG_FILE; + f = fopen(fn, "re"); + if (!f) { + if (errno == ENOENT) + return 0; + + log_warning("Failed to open configuration file '%s': %m", fn); + return 0; + } + + r = config_parse(fn, f, "Manager\0", config_item_table_lookup, (void*) items, false, NULL); + if (r < 0) + log_warning("Failed to parse configuration file: %s", strerror(-r)); + + fclose(f); + + return 0; +} + +static int parse_proc_cmdline(void) { + char *line, *w, *state; + int r; + size_t l; + + /* Don't read /proc/cmdline if we are in a container, since + * that is only relevant for the host system */ + if (detect_container(NULL) > 0) + return 0; + + if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) { + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return 0; + } + + FOREACH_WORD_QUOTED(w, l, line, state) { + char *word; + + if (!(word = strndup(w, l))) { + r = -ENOMEM; + goto finish; + } + + r = parse_proc_cmdline_word(word); + free(word); + + if (r < 0) + goto finish; + } + + r = 0; + +finish: + free(line); + return r; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_LOG_LEVEL = 0x100, + ARG_LOG_TARGET, + ARG_LOG_COLOR, + ARG_LOG_LOCATION, + ARG_UNIT, + ARG_SYSTEM, + ARG_USER, + ARG_TEST, + ARG_DUMP_CONFIGURATION_ITEMS, + ARG_DUMP_CORE, + ARG_CRASH_SHELL, + ARG_CONFIRM_SPAWN, + ARG_SHOW_STATUS, + ARG_SYSV_CONSOLE, + ARG_DESERIALIZE, + ARG_INTROSPECT, + ARG_DEFAULT_STD_OUTPUT, + ARG_DEFAULT_STD_ERROR + }; + + static const struct option options[] = { + { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, + { "log-target", required_argument, NULL, ARG_LOG_TARGET }, + { "log-color", optional_argument, NULL, ARG_LOG_COLOR }, + { "log-location", optional_argument, NULL, ARG_LOG_LOCATION }, + { "unit", required_argument, NULL, ARG_UNIT }, + { "system", no_argument, NULL, ARG_SYSTEM }, + { "user", no_argument, NULL, ARG_USER }, + { "test", no_argument, NULL, ARG_TEST }, + { "help", no_argument, NULL, 'h' }, + { "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS }, + { "dump-core", no_argument, NULL, ARG_DUMP_CORE }, + { "crash-shell", no_argument, NULL, ARG_CRASH_SHELL }, + { "confirm-spawn", no_argument, NULL, ARG_CONFIRM_SPAWN }, + { "show-status", optional_argument, NULL, ARG_SHOW_STATUS }, +#ifdef HAVE_SYSV_COMPAT + { "sysv-console", optional_argument, NULL, ARG_SYSV_CONSOLE }, +#endif + { "deserialize", required_argument, NULL, ARG_DESERIALIZE }, + { "introspect", optional_argument, NULL, ARG_INTROSPECT }, + { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, }, + { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, }, + { NULL, 0, NULL, 0 } + }; + + int c, r; + + assert(argc >= 1); + assert(argv); + + if (getpid() == 1) + opterr = 0; + + while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0) + + switch (c) { + + case ARG_LOG_LEVEL: + if ((r = log_set_max_level_from_string(optarg)) < 0) { + log_error("Failed to parse log level %s.", optarg); + return r; + } + + break; + + case ARG_LOG_TARGET: + + if ((r = log_set_target_from_string(optarg)) < 0) { + log_error("Failed to parse log target %s.", optarg); + return r; + } + + break; + + case ARG_LOG_COLOR: + + if (optarg) { + if ((r = log_show_color_from_string(optarg)) < 0) { + log_error("Failed to parse log color setting %s.", optarg); + return r; + } + } else + log_show_color(true); + + break; + + case ARG_LOG_LOCATION: + + if (optarg) { + if ((r = log_show_location_from_string(optarg)) < 0) { + log_error("Failed to parse log location setting %s.", optarg); + return r; + } + } else + log_show_location(true); + + break; + + case ARG_DEFAULT_STD_OUTPUT: + + if ((r = exec_output_from_string(optarg)) < 0) { + log_error("Failed to parse default standard output setting %s.", optarg); + return r; + } else + arg_default_std_output = r; + break; + + case ARG_DEFAULT_STD_ERROR: + + if ((r = exec_output_from_string(optarg)) < 0) { + log_error("Failed to parse default standard error output setting %s.", optarg); + return r; + } else + arg_default_std_error = r; + break; + + case ARG_UNIT: + + if ((r = set_default_unit(optarg)) < 0) { + log_error("Failed to set default unit %s: %s", optarg, strerror(-r)); + return r; + } + + break; + + case ARG_SYSTEM: + arg_running_as = MANAGER_SYSTEM; + break; + + case ARG_USER: + arg_running_as = MANAGER_USER; + break; + + case ARG_TEST: + arg_action = ACTION_TEST; + break; + + case ARG_DUMP_CONFIGURATION_ITEMS: + arg_action = ACTION_DUMP_CONFIGURATION_ITEMS; + break; + + case ARG_DUMP_CORE: + arg_dump_core = true; + break; + + case ARG_CRASH_SHELL: + arg_crash_shell = true; + break; + + case ARG_CONFIRM_SPAWN: + arg_confirm_spawn = true; + break; + + case ARG_SHOW_STATUS: + + if (optarg) { + if ((r = parse_boolean(optarg)) < 0) { + log_error("Failed to show status boolean %s.", optarg); + return r; + } + arg_show_status = r; + } else + arg_show_status = true; + break; +#ifdef HAVE_SYSV_COMPAT + case ARG_SYSV_CONSOLE: + + if (optarg) { + if ((r = parse_boolean(optarg)) < 0) { + log_error("Failed to SysV console boolean %s.", optarg); + return r; + } + arg_sysv_console = r; + } else + arg_sysv_console = true; + break; +#endif + + case ARG_DESERIALIZE: { + int fd; + FILE *f; + + if ((r = safe_atoi(optarg, &fd)) < 0 || fd < 0) { + log_error("Failed to parse deserialize option %s.", optarg); + return r; + } + + if (!(f = fdopen(fd, "r"))) { + log_error("Failed to open serialization fd: %m"); + return r; + } + + if (serialization) + fclose(serialization); + + serialization = f; + + break; + } + + case ARG_INTROSPECT: { + const char * const * i = NULL; + + for (i = bus_interface_table; *i; i += 2) + if (!optarg || streq(i[0], optarg)) { + fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + "\n", stdout); + fputs(i[1], stdout); + fputs("\n", stdout); + + if (optarg) + break; + } + + if (!i[0] && optarg) + log_error("Unknown interface %s.", optarg); + + arg_action = ACTION_DONE; + break; + } + + case 'h': + arg_action = ACTION_HELP; + break; + + case 'D': + log_set_max_level(LOG_DEBUG); + break; + + case 'b': + case 's': + case 'z': + /* Just to eat away the sysvinit kernel + * cmdline args without getopt() error + * messages that we'll parse in + * parse_proc_cmdline_word() or ignore. */ + + case '?': + default: + if (getpid() != 1) { + log_error("Unknown option code %c", c); + return -EINVAL; + } + + break; + } + + if (optind < argc && getpid() != 1) { + /* Hmm, when we aren't run as init system + * let's complain about excess arguments */ + + log_error("Excess arguments."); + return -EINVAL; + } + + if (detect_container(NULL) > 0) { + char **a; + + /* All /proc/cmdline arguments the kernel didn't + * understand it passed to us. We're not really + * interested in that usually since /proc/cmdline is + * more interesting and complete. With one exception: + * if we are run in a container /proc/cmdline is not + * relevant for the container, hence we rely on argv[] + * instead. */ + + for (a = argv; a < argv + argc; a++) + if ((r = parse_proc_cmdline_word(*a)) < 0) + return r; + } + + return 0; +} + +static int help(void) { + + printf("%s [OPTIONS...]\n\n" + "Starts up and maintains the system or user services.\n\n" + " -h --help Show this help\n" + " --test Determine startup sequence, dump it and exit\n" + " --dump-configuration-items Dump understood unit configuration items\n" + " --introspect[=INTERFACE] Extract D-Bus interface data\n" + " --unit=UNIT Set default unit\n" + " --system Run a system instance, even if PID != 1\n" + " --user Run a user instance\n" + " --dump-core Dump core on crash\n" + " --crash-shell Run shell on crash\n" + " --confirm-spawn Ask for confirmation when spawning processes\n" + " --show-status[=0|1] Show status updates on the console during bootup\n" +#ifdef HAVE_SYSV_COMPAT + " --sysv-console[=0|1] Connect output of SysV scripts to console\n" +#endif + " --log-target=TARGET Set log target (console, journal, syslog, kmsg, journal-or-kmsg, syslog-or-kmsg, null)\n" + " --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n" + " --log-color[=0|1] Highlight important log messages\n" + " --log-location[=0|1] Include code location in log messages\n" + " --default-standard-output= Set default standard output for services\n" + " --default-standard-error= Set default standard error output for services\n", + program_invocation_short_name); + + return 0; +} + +static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds) { + FILE *f = NULL; + FDSet *fds = NULL; + int r; + + assert(m); + assert(_f); + assert(_fds); + + /* Make sure nothing is really destructed when we shut down */ + m->n_reloading ++; + + if ((r = manager_open_serialization(m, &f)) < 0) { + log_error("Failed to create serialization file: %s", strerror(-r)); + goto fail; + } + + if (!(fds = fdset_new())) { + r = -ENOMEM; + log_error("Failed to allocate fd set: %s", strerror(-r)); + goto fail; + } + + if ((r = manager_serialize(m, f, fds)) < 0) { + log_error("Failed to serialize state: %s", strerror(-r)); + goto fail; + } + + if (fseeko(f, 0, SEEK_SET) < 0) { + log_error("Failed to rewind serialization fd: %m"); + goto fail; + } + + if ((r = fd_cloexec(fileno(f), false)) < 0) { + log_error("Failed to disable O_CLOEXEC for serialization: %s", strerror(-r)); + goto fail; + } + + if ((r = fdset_cloexec(fds, false)) < 0) { + log_error("Failed to disable O_CLOEXEC for serialization fds: %s", strerror(-r)); + goto fail; + } + + *_f = f; + *_fds = fds; + + return 0; + +fail: + fdset_free(fds); + + if (f) + fclose(f); + + return r; +} + +static struct dual_timestamp* parse_initrd_timestamp(struct dual_timestamp *t) { + const char *e; + unsigned long long a, b; + + assert(t); + + if (!(e = getenv("RD_TIMESTAMP"))) + return NULL; + + if (sscanf(e, "%llu %llu", &a, &b) != 2) + return NULL; + + t->realtime = (usec_t) a; + t->monotonic = (usec_t) b; + + return t; +} + +static void test_mtab(void) { + char *p; + + /* Check that /etc/mtab is a symlink */ + + if (readlink_malloc("/etc/mtab", &p) >= 0) { + bool b; + + b = streq(p, "/proc/self/mounts") || streq(p, "/proc/mounts"); + free(p); + + if (b) + return; + } + + log_warning("/etc/mtab is not a symlink or not pointing to /proc/self/mounts. " + "This is not supported anymore. " + "Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output."); +} + +static void test_usr(void) { + + /* Check that /usr is not a separate fs */ + + if (dir_is_empty("/usr") <= 0) + return; + + log_warning("/usr appears to be on its own filesytem and is not already mounted. This is not a supported setup. " + "Some things will probably break (sometimes even silently) in mysterious ways. " + "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information."); +} + +static void test_cgroups(void) { + + if (access("/proc/cgroups", F_OK) >= 0) + return; + + log_warning("CONFIG_CGROUPS was not set when your kernel was compiled. " + "Systems without control groups are not supported. " + "We will now sleep for 10s, and then continue boot-up. " + "Expect breakage and please do not file bugs. " + "Instead fix your kernel and enable CONFIG_CGROUPS." ); + + sleep(10); +} + +int main(int argc, char *argv[]) { + Manager *m = NULL; + int r, retval = EXIT_FAILURE; + usec_t before_startup, after_startup; + char timespan[FORMAT_TIMESPAN_MAX]; + FDSet *fds = NULL; + bool reexecute = false; + const char *shutdown_verb = NULL; + dual_timestamp initrd_timestamp = { 0ULL, 0ULL }; + static char systemd[] = "systemd"; + bool is_reexec = false; + int j; + bool loaded_policy = false; + +#ifdef HAVE_SYSV_COMPAT + if (getpid() != 1 && strstr(program_invocation_short_name, "init")) { + /* This is compatibility support for SysV, where + * calling init as a user is identical to telinit. */ + + errno = -ENOENT; + execv(SYSTEMCTL_BINARY_PATH, argv); + log_error("Failed to exec " SYSTEMCTL_BINARY_PATH ": %m"); + return 1; + } +#endif + + /* Determine if this is a reexecution or normal bootup. We do + * the full command line parsing much later, so let's just + * have a quick peek here. */ + + for (j = 1; j < argc; j++) + if (streq(argv[j], "--deserialize")) { + is_reexec = true; + break; + } + + /* If we get started via the /sbin/init symlink then we are + called 'init'. After a subsequent reexecution we are then + called 'systemd'. That is confusing, hence let's call us + systemd right-away. */ + program_invocation_short_name = systemd; + prctl(PR_SET_NAME, systemd); + + saved_argv = argv; + saved_argc = argc; + + log_show_color(isatty(STDERR_FILENO) > 0); + log_show_location(false); + log_set_max_level(LOG_INFO); + + if (getpid() == 1) { + arg_running_as = MANAGER_SYSTEM; + log_set_target(detect_container(NULL) > 0 ? LOG_TARGET_CONSOLE : LOG_TARGET_JOURNAL_OR_KMSG); + + if (!is_reexec) + if (selinux_setup(&loaded_policy) < 0) + goto finish; + + log_open(); + + if (label_init() < 0) + goto finish; + + if (!is_reexec) + if (hwclock_is_localtime() > 0) { + int min; + + r = hwclock_apply_localtime_delta(&min); + if (r < 0) + log_error("Failed to apply local time delta, ignoring: %s", strerror(-r)); + else + log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min); + } + + } else { + arg_running_as = MANAGER_USER; + log_set_target(LOG_TARGET_AUTO); + log_open(); + } + + /* Initialize default unit */ + if (set_default_unit(SPECIAL_DEFAULT_TARGET) < 0) + goto finish; + + /* By default, mount "cpu" and "cpuacct" together */ + arg_join_controllers = new(char**, 2); + if (!arg_join_controllers) + goto finish; + + arg_join_controllers[0] = strv_new("cpu", "cpuacct", NULL); + arg_join_controllers[1] = NULL; + + if (!arg_join_controllers[0]) + goto finish; + + /* Mount /proc, /sys and friends, so that /proc/cmdline and + * /proc/$PID/fd is available. */ + if (geteuid() == 0 && !getenv("SYSTEMD_SKIP_API_MOUNTS")) { + r = mount_setup(loaded_policy); + if (r < 0) + goto finish; + } + + /* Reset all signal handlers. */ + assert_se(reset_all_signal_handlers() == 0); + + /* If we are init, we can block sigkill. Yay. */ + ignore_signals(SIGNALS_IGNORE, -1); + + if (parse_config_file() < 0) + goto finish; + + if (arg_running_as == MANAGER_SYSTEM) + if (parse_proc_cmdline() < 0) + goto finish; + + log_parse_environment(); + + if (parse_argv(argc, argv) < 0) + goto finish; + + if (arg_action == ACTION_TEST && geteuid() == 0) { + log_error("Don't run test mode as root."); + goto finish; + } + + if (arg_running_as == MANAGER_SYSTEM && + arg_action == ACTION_RUN && + running_in_chroot() > 0) { + log_error("Cannot be run in a chroot() environment."); + goto finish; + } + + if (arg_action == ACTION_HELP) { + retval = help(); + goto finish; + } else if (arg_action == ACTION_DUMP_CONFIGURATION_ITEMS) { + unit_dump_config_items(stdout); + retval = EXIT_SUCCESS; + goto finish; + } else if (arg_action == ACTION_DONE) { + retval = EXIT_SUCCESS; + goto finish; + } + + assert_se(arg_action == ACTION_RUN || arg_action == ACTION_TEST); + + /* Close logging fds, in order not to confuse fdset below */ + log_close(); + + /* Remember open file descriptors for later deserialization */ + if (serialization) { + if ((r = fdset_new_fill(&fds)) < 0) { + log_error("Failed to allocate fd set: %s", strerror(-r)); + goto finish; + } + + assert_se(fdset_remove(fds, fileno(serialization)) >= 0); + } else + close_all_fds(NULL, 0); + + /* Set up PATH unless it is already set */ + setenv("PATH", +#ifdef HAVE_SPLIT_USR + "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", +#else + "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin", +#endif + arg_running_as == MANAGER_SYSTEM); + + if (arg_running_as == MANAGER_SYSTEM) { + /* Parse the data passed to us by the initrd and unset it */ + parse_initrd_timestamp(&initrd_timestamp); + filter_environ("RD_"); + + /* Unset some environment variables passed in from the + * kernel that don't really make sense for us. */ + unsetenv("HOME"); + unsetenv("TERM"); + + /* All other variables are left as is, so that clients + * can still read them via /proc/1/environ */ + } + + /* Move out of the way, so that we won't block unmounts */ + assert_se(chdir("/") == 0); + + if (arg_running_as == MANAGER_SYSTEM) { + /* Become a session leader if we aren't one yet. */ + setsid(); + + /* Disable the umask logic */ + umask(0); + } + + /* Make sure D-Bus doesn't fiddle with the SIGPIPE handlers */ + dbus_connection_set_change_sigpipe(FALSE); + + /* Reset the console, but only if this is really init and we + * are freshly booted */ + if (arg_running_as == MANAGER_SYSTEM && arg_action == ACTION_RUN) { + console_setup(getpid() == 1 && !is_reexec); + make_null_stdio(); + } + + /* Open the logging devices, if possible and necessary */ + log_open(); + + /* Make sure we leave a core dump without panicing the + * kernel. */ + if (getpid() == 1) + install_crash_handler(); + + if (geteuid() == 0 && !getenv("SYSTEMD_SKIP_API_MOUNTS")) { + r = mount_cgroup_controllers(arg_join_controllers); + if (r < 0) + goto finish; + } + + log_full(arg_running_as == MANAGER_SYSTEM ? LOG_INFO : LOG_DEBUG, + PACKAGE_STRING " running in %s mode. (" SYSTEMD_FEATURES "; " DISTRIBUTION ")", manager_running_as_to_string(arg_running_as)); + + if (arg_running_as == MANAGER_SYSTEM && !is_reexec) { + locale_setup(); + + if (arg_show_status || plymouth_running()) + status_welcome(); + + kmod_setup(); + hostname_setup(); + machine_id_setup(); + loopback_setup(); + + test_mtab(); + test_usr(); + test_cgroups(); + } + + if ((r = manager_new(arg_running_as, &m)) < 0) { + log_error("Failed to allocate manager object: %s", strerror(-r)); + goto finish; + } + + m->confirm_spawn = arg_confirm_spawn; +#ifdef HAVE_SYSV_COMPAT + m->sysv_console = arg_sysv_console; +#endif + m->mount_auto = arg_mount_auto; + m->swap_auto = arg_swap_auto; + m->default_std_output = arg_default_std_output; + m->default_std_error = arg_default_std_error; + + if (dual_timestamp_is_set(&initrd_timestamp)) + m->initrd_timestamp = initrd_timestamp; + + if (arg_default_controllers) + manager_set_default_controllers(m, arg_default_controllers); + + manager_set_show_status(m, arg_show_status); + + before_startup = now(CLOCK_MONOTONIC); + + if ((r = manager_startup(m, serialization, fds)) < 0) + log_error("Failed to fully start up daemon: %s", strerror(-r)); + + if (fds) { + /* This will close all file descriptors that were opened, but + * not claimed by any unit. */ + + fdset_free(fds); + fds = NULL; + } + + if (serialization) { + fclose(serialization); + serialization = NULL; + } else { + DBusError error; + Unit *target = NULL; + Job *default_unit_job; + + dbus_error_init(&error); + + log_debug("Activating default unit: %s", arg_default_unit); + + if ((r = manager_load_unit(m, arg_default_unit, NULL, &error, &target)) < 0) { + log_error("Failed to load default target: %s", bus_error(&error, r)); + dbus_error_free(&error); + } else if (target->load_state == UNIT_ERROR) + log_error("Failed to load default target: %s", strerror(-target->load_error)); + else if (target->load_state == UNIT_MASKED) + log_error("Default target masked."); + + if (!target || target->load_state != UNIT_LOADED) { + log_info("Trying to load rescue target..."); + + if ((r = manager_load_unit(m, SPECIAL_RESCUE_TARGET, NULL, &error, &target)) < 0) { + log_error("Failed to load rescue target: %s", bus_error(&error, r)); + dbus_error_free(&error); + goto finish; + } else if (target->load_state == UNIT_ERROR) { + log_error("Failed to load rescue target: %s", strerror(-target->load_error)); + goto finish; + } else if (target->load_state == UNIT_MASKED) { + log_error("Rescue target masked."); + goto finish; + } + } + + assert(target->load_state == UNIT_LOADED); + + if (arg_action == ACTION_TEST) { + printf("-> By units:\n"); + manager_dump_units(m, stdout, "\t"); + } + + r = manager_add_job(m, JOB_START, target, JOB_REPLACE, false, &error, &default_unit_job); + if (r < 0) { + log_error("Failed to start default target: %s", bus_error(&error, r)); + dbus_error_free(&error); + goto finish; + } + m->default_unit_job_id = default_unit_job->id; + + after_startup = now(CLOCK_MONOTONIC); + log_full(arg_action == ACTION_TEST ? LOG_INFO : LOG_DEBUG, + "Loaded units and determined initial transaction in %s.", + format_timespan(timespan, sizeof(timespan), after_startup - before_startup)); + + if (arg_action == ACTION_TEST) { + printf("-> By jobs:\n"); + manager_dump_jobs(m, stdout, "\t"); + retval = EXIT_SUCCESS; + goto finish; + } + } + + for (;;) { + if ((r = manager_loop(m)) < 0) { + log_error("Failed to run mainloop: %s", strerror(-r)); + goto finish; + } + + switch (m->exit_code) { + + case MANAGER_EXIT: + retval = EXIT_SUCCESS; + log_debug("Exit."); + goto finish; + + case MANAGER_RELOAD: + log_info("Reloading."); + if ((r = manager_reload(m)) < 0) + log_error("Failed to reload: %s", strerror(-r)); + break; + + case MANAGER_REEXECUTE: + if (prepare_reexecute(m, &serialization, &fds) < 0) + goto finish; + + reexecute = true; + log_notice("Reexecuting."); + goto finish; + + case MANAGER_REBOOT: + case MANAGER_POWEROFF: + case MANAGER_HALT: + case MANAGER_KEXEC: { + static const char * const table[_MANAGER_EXIT_CODE_MAX] = { + [MANAGER_REBOOT] = "reboot", + [MANAGER_POWEROFF] = "poweroff", + [MANAGER_HALT] = "halt", + [MANAGER_KEXEC] = "kexec" + }; + + assert_se(shutdown_verb = table[m->exit_code]); + + log_notice("Shutting down."); + goto finish; + } + + default: + assert_not_reached("Unknown exit code."); + } + } + +finish: + if (m) + manager_free(m); + + free(arg_default_unit); + strv_free(arg_default_controllers); + free_join_controllers(); + + dbus_shutdown(); + + label_finish(); + + if (reexecute) { + const char *args[15]; + unsigned i = 0; + char sfd[16]; + + assert(serialization); + assert(fds); + + args[i++] = SYSTEMD_BINARY_PATH; + + args[i++] = "--log-level"; + args[i++] = log_level_to_string(log_get_max_level()); + + args[i++] = "--log-target"; + args[i++] = log_target_to_string(log_get_target()); + + if (arg_running_as == MANAGER_SYSTEM) + args[i++] = "--system"; + else + args[i++] = "--user"; + + if (arg_dump_core) + args[i++] = "--dump-core"; + + if (arg_crash_shell) + args[i++] = "--crash-shell"; + + if (arg_confirm_spawn) + args[i++] = "--confirm-spawn"; + + if (arg_show_status) + args[i++] = "--show-status=1"; + else + args[i++] = "--show-status=0"; + +#ifdef HAVE_SYSV_COMPAT + if (arg_sysv_console) + args[i++] = "--sysv-console=1"; + else + args[i++] = "--sysv-console=0"; +#endif + + snprintf(sfd, sizeof(sfd), "%i", fileno(serialization)); + char_array_0(sfd); + + args[i++] = "--deserialize"; + args[i++] = sfd; + + args[i++] = NULL; + + assert(i <= ELEMENTSOF(args)); + + execv(args[0], (char* const*) args); + + log_error("Failed to reexecute: %m"); + } + + if (serialization) + fclose(serialization); + + if (fds) + fdset_free(fds); + + if (shutdown_verb) { + const char * command_line[] = { + SYSTEMD_SHUTDOWN_BINARY_PATH, + shutdown_verb, + NULL + }; + + execv(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line); + log_error("Failed to execute shutdown binary, freezing: %m"); + } + + if (getpid() == 1) + freeze(); + + return retval; +} diff --git a/src/manager.c b/src/manager.c new file mode 100644 index 0000000..74bd740 --- /dev/null +++ b/src/manager.c @@ -0,0 +1,3199 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_AUDIT +#include +#endif + +#include + +#include "manager.h" +#include "hashmap.h" +#include "macro.h" +#include "strv.h" +#include "log.h" +#include "util.h" +#include "ratelimit.h" +#include "cgroup.h" +#include "mount-setup.h" +#include "unit-name.h" +#include "dbus-unit.h" +#include "dbus-job.h" +#include "missing.h" +#include "path-lookup.h" +#include "special.h" +#include "bus-errors.h" +#include "exit-status.h" +#include "virt.h" + +/* As soon as 16 units are in our GC queue, make sure to run a gc sweep */ +#define GC_QUEUE_ENTRIES_MAX 16 + +/* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */ +#define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC) + +/* Where clients shall send notification messages to */ +#define NOTIFY_SOCKET_SYSTEM "/run/systemd/notify" +#define NOTIFY_SOCKET_USER "@/org/freedesktop/systemd1/notify" + +static int manager_setup_notify(Manager *m) { + union { + struct sockaddr sa; + struct sockaddr_un un; + } sa; + struct epoll_event ev; + int one = 1, r; + mode_t u; + + assert(m); + + m->notify_watch.type = WATCH_NOTIFY; + if ((m->notify_watch.fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) { + log_error("Failed to allocate notification socket: %m"); + return -errno; + } + + zero(sa); + sa.sa.sa_family = AF_UNIX; + + if (getpid() != 1) + snprintf(sa.un.sun_path, sizeof(sa.un.sun_path), NOTIFY_SOCKET_USER "/%llu", random_ull()); + else { + unlink(NOTIFY_SOCKET_SYSTEM); + strncpy(sa.un.sun_path, NOTIFY_SOCKET_SYSTEM, sizeof(sa.un.sun_path)); + } + + if (sa.un.sun_path[0] == '@') + sa.un.sun_path[0] = 0; + + u = umask(0111); + r = bind(m->notify_watch.fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)); + umask(u); + + if (r < 0) { + log_error("bind() failed: %m"); + return -errno; + } + + if (setsockopt(m->notify_watch.fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) { + log_error("SO_PASSCRED failed: %m"); + return -errno; + } + + zero(ev); + ev.events = EPOLLIN; + ev.data.ptr = &m->notify_watch; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev) < 0) + return -errno; + + if (sa.un.sun_path[0] == 0) + sa.un.sun_path[0] = '@'; + + if (!(m->notify_socket = strdup(sa.un.sun_path))) + return -ENOMEM; + + log_debug("Using notification socket %s", m->notify_socket); + + return 0; +} + +static int enable_special_signals(Manager *m) { + int fd; + + assert(m); + + /* Enable that we get SIGINT on control-alt-del */ + if (reboot(RB_DISABLE_CAD) < 0) + log_warning("Failed to enable ctrl-alt-del handling: %m"); + + if ((fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0) + log_warning("Failed to open /dev/tty0: %m"); + else { + /* Enable that we get SIGWINCH on kbrequest */ + if (ioctl(fd, KDSIGACCEPT, SIGWINCH) < 0) + log_warning("Failed to enable kbrequest handling: %s", strerror(errno)); + + close_nointr_nofail(fd); + } + + return 0; +} + +static int manager_setup_signals(Manager *m) { + sigset_t mask; + struct epoll_event ev; + struct sigaction sa; + + assert(m); + + /* We are not interested in SIGSTOP and friends. */ + zero(sa); + sa.sa_handler = SIG_DFL; + sa.sa_flags = SA_NOCLDSTOP|SA_RESTART; + assert_se(sigaction(SIGCHLD, &sa, NULL) == 0); + + assert_se(sigemptyset(&mask) == 0); + + sigset_add_many(&mask, + SIGCHLD, /* Child died */ + SIGTERM, /* Reexecute daemon */ + SIGHUP, /* Reload configuration */ + SIGUSR1, /* systemd/upstart: reconnect to D-Bus */ + SIGUSR2, /* systemd: dump status */ + SIGINT, /* Kernel sends us this on control-alt-del */ + SIGWINCH, /* Kernel sends us this on kbrequest (alt-arrowup) */ + SIGPWR, /* Some kernel drivers and upsd send us this on power failure */ + SIGRTMIN+0, /* systemd: start default.target */ + SIGRTMIN+1, /* systemd: isolate rescue.target */ + SIGRTMIN+2, /* systemd: isolate emergency.target */ + SIGRTMIN+3, /* systemd: start halt.target */ + SIGRTMIN+4, /* systemd: start poweroff.target */ + SIGRTMIN+5, /* systemd: start reboot.target */ + SIGRTMIN+6, /* systemd: start kexec.target */ + SIGRTMIN+13, /* systemd: Immediate halt */ + SIGRTMIN+14, /* systemd: Immediate poweroff */ + SIGRTMIN+15, /* systemd: Immediate reboot */ + SIGRTMIN+16, /* systemd: Immediate kexec */ + SIGRTMIN+20, /* systemd: enable status messages */ + SIGRTMIN+21, /* systemd: disable status messages */ + SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */ + SIGRTMIN+23, /* systemd: set log level to LOG_INFO */ + SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */ + SIGRTMIN+27, /* systemd: set log target to console */ + SIGRTMIN+28, /* systemd: set log target to kmsg */ + SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg */ + -1); + assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); + + m->signal_watch.type = WATCH_SIGNAL; + if ((m->signal_watch.fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) + return -errno; + + zero(ev); + ev.events = EPOLLIN; + ev.data.ptr = &m->signal_watch; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->signal_watch.fd, &ev) < 0) + return -errno; + + if (m->running_as == MANAGER_SYSTEM) + return enable_special_signals(m); + + return 0; +} + +int manager_new(ManagerRunningAs running_as, Manager **_m) { + Manager *m; + int r = -ENOMEM; + + assert(_m); + assert(running_as >= 0); + assert(running_as < _MANAGER_RUNNING_AS_MAX); + + if (!(m = new0(Manager, 1))) + return -ENOMEM; + + dual_timestamp_get(&m->startup_timestamp); + + m->running_as = running_as; + m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = -1; + m->exit_code = _MANAGER_EXIT_CODE_INVALID; + m->pin_cgroupfs_fd = -1; + +#ifdef HAVE_AUDIT + m->audit_fd = -1; +#endif + + m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = m->swap_watch.fd = -1; + m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */ + + if (!(m->environment = strv_copy(environ))) + goto fail; + + if (running_as == MANAGER_SYSTEM) { + m->default_controllers = strv_new("cpu", NULL); + if (!m->default_controllers) + goto fail; + } + + if (!(m->units = hashmap_new(string_hash_func, string_compare_func))) + goto fail; + + if (!(m->jobs = hashmap_new(trivial_hash_func, trivial_compare_func))) + goto fail; + + if (!(m->transaction_jobs = hashmap_new(trivial_hash_func, trivial_compare_func))) + goto fail; + + if (!(m->watch_pids = hashmap_new(trivial_hash_func, trivial_compare_func))) + goto fail; + + if (!(m->cgroup_bondings = hashmap_new(string_hash_func, string_compare_func))) + goto fail; + + if (!(m->watch_bus = hashmap_new(string_hash_func, string_compare_func))) + goto fail; + + if ((m->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0) + goto fail; + + if ((r = lookup_paths_init(&m->lookup_paths, m->running_as, true)) < 0) + goto fail; + + if ((r = manager_setup_signals(m)) < 0) + goto fail; + + if ((r = manager_setup_cgroup(m)) < 0) + goto fail; + + if ((r = manager_setup_notify(m)) < 0) + goto fail; + + /* Try to connect to the busses, if possible. */ + if ((r = bus_init(m, running_as != MANAGER_SYSTEM)) < 0) + goto fail; + +#ifdef HAVE_AUDIT + if ((m->audit_fd = audit_open()) < 0 && + /* If the kernel lacks netlink or audit support, + * don't worry about it. */ + errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT) + log_error("Failed to connect to audit log: %m"); +#endif + + m->taint_usr = dir_is_empty("/usr") > 0; + + *_m = m; + return 0; + +fail: + manager_free(m); + return r; +} + +static unsigned manager_dispatch_cleanup_queue(Manager *m) { + Unit *u; + unsigned n = 0; + + assert(m); + + while ((u = m->cleanup_queue)) { + assert(u->in_cleanup_queue); + + unit_free(u); + n++; + } + + return n; +} + +enum { + GC_OFFSET_IN_PATH, /* This one is on the path we were traveling */ + GC_OFFSET_UNSURE, /* No clue */ + GC_OFFSET_GOOD, /* We still need this unit */ + GC_OFFSET_BAD, /* We don't need this unit anymore */ + _GC_OFFSET_MAX +}; + +static void unit_gc_sweep(Unit *u, unsigned gc_marker) { + Iterator i; + Unit *other; + bool is_bad; + + assert(u); + + if (u->gc_marker == gc_marker + GC_OFFSET_GOOD || + u->gc_marker == gc_marker + GC_OFFSET_BAD || + u->gc_marker == gc_marker + GC_OFFSET_IN_PATH) + return; + + if (u->in_cleanup_queue) + goto bad; + + if (unit_check_gc(u)) + goto good; + + u->gc_marker = gc_marker + GC_OFFSET_IN_PATH; + + is_bad = true; + + SET_FOREACH(other, u->dependencies[UNIT_REFERENCED_BY], i) { + unit_gc_sweep(other, gc_marker); + + if (other->gc_marker == gc_marker + GC_OFFSET_GOOD) + goto good; + + if (other->gc_marker != gc_marker + GC_OFFSET_BAD) + is_bad = false; + } + + if (is_bad) + goto bad; + + /* We were unable to find anything out about this entry, so + * let's investigate it later */ + u->gc_marker = gc_marker + GC_OFFSET_UNSURE; + unit_add_to_gc_queue(u); + return; + +bad: + /* We definitely know that this one is not useful anymore, so + * let's mark it for deletion */ + u->gc_marker = gc_marker + GC_OFFSET_BAD; + unit_add_to_cleanup_queue(u); + return; + +good: + u->gc_marker = gc_marker + GC_OFFSET_GOOD; +} + +static unsigned manager_dispatch_gc_queue(Manager *m) { + Unit *u; + unsigned n = 0; + unsigned gc_marker; + + assert(m); + + if ((m->n_in_gc_queue < GC_QUEUE_ENTRIES_MAX) && + (m->gc_queue_timestamp <= 0 || + (m->gc_queue_timestamp + GC_QUEUE_USEC_MAX) > now(CLOCK_MONOTONIC))) + return 0; + + log_debug("Running GC..."); + + m->gc_marker += _GC_OFFSET_MAX; + if (m->gc_marker + _GC_OFFSET_MAX <= _GC_OFFSET_MAX) + m->gc_marker = 1; + + gc_marker = m->gc_marker; + + while ((u = m->gc_queue)) { + assert(u->in_gc_queue); + + unit_gc_sweep(u, gc_marker); + + LIST_REMOVE(Unit, gc_queue, m->gc_queue, u); + u->in_gc_queue = false; + + n++; + + if (u->gc_marker == gc_marker + GC_OFFSET_BAD || + u->gc_marker == gc_marker + GC_OFFSET_UNSURE) { + log_debug("Collecting %s", u->id); + u->gc_marker = gc_marker + GC_OFFSET_BAD; + unit_add_to_cleanup_queue(u); + } + } + + m->n_in_gc_queue = 0; + m->gc_queue_timestamp = 0; + + return n; +} + +static void manager_clear_jobs_and_units(Manager *m) { + Job *j; + Unit *u; + + assert(m); + + while ((j = hashmap_first(m->transaction_jobs))) + job_free(j); + + while ((u = hashmap_first(m->units))) + unit_free(u); + + manager_dispatch_cleanup_queue(m); + + assert(!m->load_queue); + assert(!m->run_queue); + assert(!m->dbus_unit_queue); + assert(!m->dbus_job_queue); + assert(!m->cleanup_queue); + assert(!m->gc_queue); + + assert(hashmap_isempty(m->transaction_jobs)); + assert(hashmap_isempty(m->jobs)); + assert(hashmap_isempty(m->units)); +} + +void manager_free(Manager *m) { + UnitType c; + + assert(m); + + manager_clear_jobs_and_units(m); + + for (c = 0; c < _UNIT_TYPE_MAX; c++) + if (unit_vtable[c]->shutdown) + unit_vtable[c]->shutdown(m); + + /* If we reexecute ourselves, we keep the root cgroup + * around */ + manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE); + + manager_undo_generators(m); + + bus_done(m); + + hashmap_free(m->units); + hashmap_free(m->jobs); + hashmap_free(m->transaction_jobs); + hashmap_free(m->watch_pids); + hashmap_free(m->watch_bus); + + if (m->epoll_fd >= 0) + close_nointr_nofail(m->epoll_fd); + if (m->signal_watch.fd >= 0) + close_nointr_nofail(m->signal_watch.fd); + if (m->notify_watch.fd >= 0) + close_nointr_nofail(m->notify_watch.fd); + +#ifdef HAVE_AUDIT + if (m->audit_fd >= 0) + audit_close(m->audit_fd); +#endif + + free(m->notify_socket); + + lookup_paths_free(&m->lookup_paths); + strv_free(m->environment); + + strv_free(m->default_controllers); + + hashmap_free(m->cgroup_bondings); + set_free_free(m->unit_path_cache); + + free(m); +} + +int manager_enumerate(Manager *m) { + int r = 0, q; + UnitType c; + + assert(m); + + /* Let's ask every type to load all units from disk/kernel + * that it might know */ + for (c = 0; c < _UNIT_TYPE_MAX; c++) + if (unit_vtable[c]->enumerate) + if ((q = unit_vtable[c]->enumerate(m)) < 0) + r = q; + + manager_dispatch_load_queue(m); + return r; +} + +int manager_coldplug(Manager *m) { + int r = 0, q; + Iterator i; + Unit *u; + char *k; + + assert(m); + + /* Then, let's set up their initial state. */ + HASHMAP_FOREACH_KEY(u, k, m->units, i) { + + /* ignore aliases */ + if (u->id != k) + continue; + + if ((q = unit_coldplug(u)) < 0) + r = q; + } + + return r; +} + +static void manager_build_unit_path_cache(Manager *m) { + char **i; + DIR *d = NULL; + int r; + + assert(m); + + set_free_free(m->unit_path_cache); + + if (!(m->unit_path_cache = set_new(string_hash_func, string_compare_func))) { + log_error("Failed to allocate unit path cache."); + return; + } + + /* This simply builds a list of files we know exist, so that + * we don't always have to go to disk */ + + STRV_FOREACH(i, m->lookup_paths.unit_path) { + struct dirent *de; + + if (!(d = opendir(*i))) { + log_error("Failed to open directory: %m"); + continue; + } + + while ((de = readdir(d))) { + char *p; + + if (ignore_file(de->d_name)) + continue; + + p = join(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL); + if (!p) { + r = -ENOMEM; + goto fail; + } + + if ((r = set_put(m->unit_path_cache, p)) < 0) { + free(p); + goto fail; + } + } + + closedir(d); + d = NULL; + } + + return; + +fail: + log_error("Failed to build unit path cache: %s", strerror(-r)); + + set_free_free(m->unit_path_cache); + m->unit_path_cache = NULL; + + if (d) + closedir(d); +} + +int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { + int r, q; + + assert(m); + + manager_run_generators(m); + + manager_build_unit_path_cache(m); + + /* If we will deserialize make sure that during enumeration + * this is already known, so we increase the counter here + * already */ + if (serialization) + m->n_reloading ++; + + /* First, enumerate what we can from all config files */ + r = manager_enumerate(m); + + /* Second, deserialize if there is something to deserialize */ + if (serialization) + if ((q = manager_deserialize(m, serialization, fds)) < 0) + r = q; + + /* Third, fire things up! */ + if ((q = manager_coldplug(m)) < 0) + r = q; + + if (serialization) { + assert(m->n_reloading > 0); + m->n_reloading --; + } + + return r; +} + +static void transaction_delete_job(Manager *m, Job *j, bool delete_dependencies) { + assert(m); + assert(j); + + /* Deletes one job from the transaction */ + + manager_transaction_unlink_job(m, j, delete_dependencies); + + if (!j->installed) + job_free(j); +} + +static void transaction_delete_unit(Manager *m, Unit *u) { + Job *j; + + /* Deletes all jobs associated with a certain unit from the + * transaction */ + + while ((j = hashmap_get(m->transaction_jobs, u))) + transaction_delete_job(m, j, true); +} + +static void transaction_clean_dependencies(Manager *m) { + Iterator i; + Job *j; + + assert(m); + + /* Drops all dependencies of all installed jobs */ + + HASHMAP_FOREACH(j, m->jobs, i) { + while (j->subject_list) + job_dependency_free(j->subject_list); + while (j->object_list) + job_dependency_free(j->object_list); + } + + assert(!m->transaction_anchor); +} + +static void transaction_abort(Manager *m) { + Job *j; + + assert(m); + + while ((j = hashmap_first(m->transaction_jobs))) + if (j->installed) + transaction_delete_job(m, j, true); + else + job_free(j); + + assert(hashmap_isempty(m->transaction_jobs)); + + transaction_clean_dependencies(m); +} + +static void transaction_find_jobs_that_matter_to_anchor(Manager *m, Job *j, unsigned generation) { + JobDependency *l; + + assert(m); + + /* A recursive sweep through the graph that marks all units + * that matter to the anchor job, i.e. are directly or + * indirectly a dependency of the anchor job via paths that + * are fully marked as mattering. */ + + if (j) + l = j->subject_list; + else + l = m->transaction_anchor; + + LIST_FOREACH(subject, l, l) { + + /* This link does not matter */ + if (!l->matters) + continue; + + /* This unit has already been marked */ + if (l->object->generation == generation) + continue; + + l->object->matters_to_anchor = true; + l->object->generation = generation; + + transaction_find_jobs_that_matter_to_anchor(m, l->object, generation); + } +} + +static void transaction_merge_and_delete_job(Manager *m, Job *j, Job *other, JobType t) { + JobDependency *l, *last; + + assert(j); + assert(other); + assert(j->unit == other->unit); + assert(!j->installed); + + /* Merges 'other' into 'j' and then deletes j. */ + + j->type = t; + j->state = JOB_WAITING; + j->override = j->override || other->override; + + j->matters_to_anchor = j->matters_to_anchor || other->matters_to_anchor; + + /* Patch us in as new owner of the JobDependency objects */ + last = NULL; + LIST_FOREACH(subject, l, other->subject_list) { + assert(l->subject == other); + l->subject = j; + last = l; + } + + /* Merge both lists */ + if (last) { + last->subject_next = j->subject_list; + if (j->subject_list) + j->subject_list->subject_prev = last; + j->subject_list = other->subject_list; + } + + /* Patch us in as new owner of the JobDependency objects */ + last = NULL; + LIST_FOREACH(object, l, other->object_list) { + assert(l->object == other); + l->object = j; + last = l; + } + + /* Merge both lists */ + if (last) { + last->object_next = j->object_list; + if (j->object_list) + j->object_list->object_prev = last; + j->object_list = other->object_list; + } + + /* Kill the other job */ + other->subject_list = NULL; + other->object_list = NULL; + transaction_delete_job(m, other, true); +} +static bool job_is_conflicted_by(Job *j) { + JobDependency *l; + + assert(j); + + /* Returns true if this job is pulled in by a least one + * ConflictedBy dependency. */ + + LIST_FOREACH(object, l, j->object_list) + if (l->conflicts) + return true; + + return false; +} + +static int delete_one_unmergeable_job(Manager *m, Job *j) { + Job *k; + + assert(j); + + /* Tries to delete one item in the linked list + * j->transaction_next->transaction_next->... that conflicts + * with another one, in an attempt to make an inconsistent + * transaction work. */ + + /* We rely here on the fact that if a merged with b does not + * merge with c, either a or b merge with c neither */ + LIST_FOREACH(transaction, j, j) + LIST_FOREACH(transaction, k, j->transaction_next) { + Job *d; + + /* Is this one mergeable? Then skip it */ + if (job_type_is_mergeable(j->type, k->type)) + continue; + + /* Ok, we found two that conflict, let's see if we can + * drop one of them */ + if (!j->matters_to_anchor && !k->matters_to_anchor) { + + /* Both jobs don't matter, so let's + * find the one that is smarter to + * remove. Let's think positive and + * rather remove stops then starts -- + * except if something is being + * stopped because it is conflicted by + * another unit in which case we + * rather remove the start. */ + + log_debug("Looking at job %s/%s conflicted_by=%s", j->unit->id, job_type_to_string(j->type), yes_no(j->type == JOB_STOP && job_is_conflicted_by(j))); + log_debug("Looking at job %s/%s conflicted_by=%s", k->unit->id, job_type_to_string(k->type), yes_no(k->type == JOB_STOP && job_is_conflicted_by(k))); + + if (j->type == JOB_STOP) { + + if (job_is_conflicted_by(j)) + d = k; + else + d = j; + + } else if (k->type == JOB_STOP) { + + if (job_is_conflicted_by(k)) + d = j; + else + d = k; + } else + d = j; + + } else if (!j->matters_to_anchor) + d = j; + else if (!k->matters_to_anchor) + d = k; + else + return -ENOEXEC; + + /* Ok, we can drop one, so let's do so. */ + log_debug("Fixing conflicting jobs by deleting job %s/%s", d->unit->id, job_type_to_string(d->type)); + transaction_delete_job(m, d, true); + return 0; + } + + return -EINVAL; +} + +static int transaction_merge_jobs(Manager *m, DBusError *e) { + Job *j; + Iterator i; + int r; + + assert(m); + + /* First step, check whether any of the jobs for one specific + * task conflict. If so, try to drop one of them. */ + HASHMAP_FOREACH(j, m->transaction_jobs, i) { + JobType t; + Job *k; + + t = j->type; + LIST_FOREACH(transaction, k, j->transaction_next) { + if (job_type_merge(&t, k->type) >= 0) + continue; + + /* OK, we could not merge all jobs for this + * action. Let's see if we can get rid of one + * of them */ + + if ((r = delete_one_unmergeable_job(m, j)) >= 0) + /* Ok, we managed to drop one, now + * let's ask our callers to call us + * again after garbage collecting */ + return -EAGAIN; + + /* We couldn't merge anything. Failure */ + dbus_set_error(e, BUS_ERROR_TRANSACTION_JOBS_CONFLICTING, "Transaction contains conflicting jobs '%s' and '%s' for %s. Probably contradicting requirement dependencies configured.", + job_type_to_string(t), job_type_to_string(k->type), k->unit->id); + return r; + } + } + + /* Second step, merge the jobs. */ + HASHMAP_FOREACH(j, m->transaction_jobs, i) { + JobType t = j->type; + Job *k; + + /* Merge all transactions */ + LIST_FOREACH(transaction, k, j->transaction_next) + assert_se(job_type_merge(&t, k->type) == 0); + + /* If an active job is mergeable, merge it too */ + if (j->unit->job) + job_type_merge(&t, j->unit->job->type); /* Might fail. Which is OK */ + + while ((k = j->transaction_next)) { + if (j->installed) { + transaction_merge_and_delete_job(m, k, j, t); + j = k; + } else + transaction_merge_and_delete_job(m, j, k, t); + } + + if (j->unit->job && !j->installed) + transaction_merge_and_delete_job(m, j, j->unit->job, t); + + assert(!j->transaction_next); + assert(!j->transaction_prev); + } + + return 0; +} + +static void transaction_drop_redundant(Manager *m) { + bool again; + + assert(m); + + /* Goes through the transaction and removes all jobs that are + * a noop */ + + do { + Job *j; + Iterator i; + + again = false; + + HASHMAP_FOREACH(j, m->transaction_jobs, i) { + bool changes_something = false; + Job *k; + + LIST_FOREACH(transaction, k, j) { + + if (!job_is_anchor(k) && + (k->installed || job_type_is_redundant(k->type, unit_active_state(k->unit))) && + (!k->unit->job || !job_type_is_conflicting(k->type, k->unit->job->type))) + continue; + + changes_something = true; + break; + } + + if (changes_something) + continue; + + /* log_debug("Found redundant job %s/%s, dropping.", j->unit->id, job_type_to_string(j->type)); */ + transaction_delete_job(m, j, false); + again = true; + break; + } + + } while (again); +} + +static bool unit_matters_to_anchor(Unit *u, Job *j) { + assert(u); + assert(!j->transaction_prev); + + /* Checks whether at least one of the jobs for this unit + * matters to the anchor. */ + + LIST_FOREACH(transaction, j, j) + if (j->matters_to_anchor) + return true; + + return false; +} + +static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned generation, DBusError *e) { + Iterator i; + Unit *u; + int r; + + assert(m); + assert(j); + assert(!j->transaction_prev); + + /* Does a recursive sweep through the ordering graph, looking + * for a cycle. If we find cycle we try to break it. */ + + /* Have we seen this before? */ + if (j->generation == generation) { + Job *k, *delete; + + /* If the marker is NULL we have been here already and + * decided the job was loop-free from here. Hence + * shortcut things and return right-away. */ + if (!j->marker) + return 0; + + /* So, the marker is not NULL and we already have been + * here. We have a cycle. Let's try to break it. We go + * backwards in our path and try to find a suitable + * job to remove. We use the marker to find our way + * back, since smart how we are we stored our way back + * in there. */ + log_warning("Found ordering cycle on %s/%s", j->unit->id, job_type_to_string(j->type)); + + delete = NULL; + for (k = from; k; k = ((k->generation == generation && k->marker != k) ? k->marker : NULL)) { + + log_info("Walked on cycle path to %s/%s", k->unit->id, job_type_to_string(k->type)); + + if (!delete && + !k->installed && + !unit_matters_to_anchor(k->unit, k)) { + /* Ok, we can drop this one, so let's + * do so. */ + delete = k; + } + + /* Check if this in fact was the beginning of + * the cycle */ + if (k == j) + break; + } + + + if (delete) { + log_warning("Breaking ordering cycle by deleting job %s/%s", delete->unit->id, job_type_to_string(delete->type)); + transaction_delete_unit(m, delete->unit); + return -EAGAIN; + } + + log_error("Unable to break cycle"); + + dbus_set_error(e, BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC, "Transaction order is cyclic. See system logs for details."); + return -ENOEXEC; + } + + /* Make the marker point to where we come from, so that we can + * find our way backwards if we want to break a cycle. We use + * a special marker for the beginning: we point to + * ourselves. */ + j->marker = from ? from : j; + j->generation = generation; + + /* We assume that the the dependencies are bidirectional, and + * hence can ignore UNIT_AFTER */ + SET_FOREACH(u, j->unit->dependencies[UNIT_BEFORE], i) { + Job *o; + + /* Is there a job for this unit? */ + if (!(o = hashmap_get(m->transaction_jobs, u))) + + /* Ok, there is no job for this in the + * transaction, but maybe there is already one + * running? */ + if (!(o = u->job)) + continue; + + if ((r = transaction_verify_order_one(m, o, j, generation, e)) < 0) + return r; + } + + /* Ok, let's backtrack, and remember that this entry is not on + * our path anymore. */ + j->marker = NULL; + + return 0; +} + +static int transaction_verify_order(Manager *m, unsigned *generation, DBusError *e) { + Job *j; + int r; + Iterator i; + unsigned g; + + assert(m); + assert(generation); + + /* Check if the ordering graph is cyclic. If it is, try to fix + * that up by dropping one of the jobs. */ + + g = (*generation)++; + + HASHMAP_FOREACH(j, m->transaction_jobs, i) + if ((r = transaction_verify_order_one(m, j, NULL, g, e)) < 0) + return r; + + return 0; +} + +static void transaction_collect_garbage(Manager *m) { + bool again; + + assert(m); + + /* Drop jobs that are not required by any other job */ + + do { + Iterator i; + Job *j; + + again = false; + + HASHMAP_FOREACH(j, m->transaction_jobs, i) { + if (j->object_list) { + /* log_debug("Keeping job %s/%s because of %s/%s", */ + /* j->unit->id, job_type_to_string(j->type), */ + /* j->object_list->subject ? j->object_list->subject->unit->id : "root", */ + /* j->object_list->subject ? job_type_to_string(j->object_list->subject->type) : "root"); */ + continue; + } + + /* log_debug("Garbage collecting job %s/%s", j->unit->id, job_type_to_string(j->type)); */ + transaction_delete_job(m, j, true); + again = true; + break; + } + + } while (again); +} + +static int transaction_is_destructive(Manager *m, DBusError *e) { + Iterator i; + Job *j; + + assert(m); + + /* Checks whether applying this transaction means that + * existing jobs would be replaced */ + + HASHMAP_FOREACH(j, m->transaction_jobs, i) { + + /* Assume merged */ + assert(!j->transaction_prev); + assert(!j->transaction_next); + + if (j->unit->job && + j->unit->job != j && + !job_type_is_superset(j->type, j->unit->job->type)) { + + dbus_set_error(e, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, "Transaction is destructive."); + return -EEXIST; + } + } + + return 0; +} + +static void transaction_minimize_impact(Manager *m) { + bool again; + assert(m); + + /* Drops all unnecessary jobs that reverse already active jobs + * or that stop a running service. */ + + do { + Job *j; + Iterator i; + + again = false; + + HASHMAP_FOREACH(j, m->transaction_jobs, i) { + LIST_FOREACH(transaction, j, j) { + bool stops_running_service, changes_existing_job; + + /* If it matters, we shouldn't drop it */ + if (j->matters_to_anchor) + continue; + + /* Would this stop a running service? + * Would this change an existing job? + * If so, let's drop this entry */ + + stops_running_service = + j->type == JOB_STOP && UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(j->unit)); + + changes_existing_job = + j->unit->job && + job_type_is_conflicting(j->type, j->unit->job->type); + + if (!stops_running_service && !changes_existing_job) + continue; + + if (stops_running_service) + log_debug("%s/%s would stop a running service.", j->unit->id, job_type_to_string(j->type)); + + if (changes_existing_job) + log_debug("%s/%s would change existing job.", j->unit->id, job_type_to_string(j->type)); + + /* Ok, let's get rid of this */ + log_debug("Deleting %s/%s to minimize impact.", j->unit->id, job_type_to_string(j->type)); + + transaction_delete_job(m, j, true); + again = true; + break; + } + + if (again) + break; + } + + } while (again); +} + +static int transaction_apply(Manager *m, JobMode mode) { + Iterator i; + Job *j; + int r; + + /* Moves the transaction jobs to the set of active jobs */ + + if (mode == JOB_ISOLATE) { + + /* When isolating first kill all installed jobs which + * aren't part of the new transaction */ + rescan: + HASHMAP_FOREACH(j, m->jobs, i) { + assert(j->installed); + + if (hashmap_get(m->transaction_jobs, j->unit)) + continue; + + /* 'j' itself is safe to remove, but if other jobs + are invalidated recursively, our iterator may become + invalid and we need to start over. */ + if (job_finish_and_invalidate(j, JOB_CANCELED) > 0) + goto rescan; + } + } + + HASHMAP_FOREACH(j, m->transaction_jobs, i) { + /* Assume merged */ + assert(!j->transaction_prev); + assert(!j->transaction_next); + + if (j->installed) + continue; + + if ((r = hashmap_put(m->jobs, UINT32_TO_PTR(j->id), j)) < 0) + goto rollback; + } + + while ((j = hashmap_steal_first(m->transaction_jobs))) { + if (j->installed) { + /* log_debug("Skipping already installed job %s/%s as %u", j->unit->id, job_type_to_string(j->type), (unsigned) j->id); */ + continue; + } + + if (j->unit->job) + job_free(j->unit->job); + + j->unit->job = j; + j->installed = true; + m->n_installed_jobs ++; + + /* We're fully installed. Now let's free data we don't + * need anymore. */ + + assert(!j->transaction_next); + assert(!j->transaction_prev); + + job_add_to_run_queue(j); + job_add_to_dbus_queue(j); + job_start_timer(j); + + log_debug("Installed new job %s/%s as %u", j->unit->id, job_type_to_string(j->type), (unsigned) j->id); + } + + /* As last step, kill all remaining job dependencies. */ + transaction_clean_dependencies(m); + + return 0; + +rollback: + + HASHMAP_FOREACH(j, m->transaction_jobs, i) { + if (j->installed) + continue; + + hashmap_remove(m->jobs, UINT32_TO_PTR(j->id)); + } + + return r; +} + +static int transaction_activate(Manager *m, JobMode mode, DBusError *e) { + int r; + unsigned generation = 1; + + assert(m); + + /* This applies the changes recorded in transaction_jobs to + * the actual list of jobs, if possible. */ + + /* First step: figure out which jobs matter */ + transaction_find_jobs_that_matter_to_anchor(m, NULL, generation++); + + /* Second step: Try not to stop any running services if + * we don't have to. Don't try to reverse running + * jobs if we don't have to. */ + if (mode == JOB_FAIL) + transaction_minimize_impact(m); + + /* Third step: Drop redundant jobs */ + transaction_drop_redundant(m); + + for (;;) { + /* Fourth step: Let's remove unneeded jobs that might + * be lurking. */ + if (mode != JOB_ISOLATE) + transaction_collect_garbage(m); + + /* Fifth step: verify order makes sense and correct + * cycles if necessary and possible */ + if ((r = transaction_verify_order(m, &generation, e)) >= 0) + break; + + if (r != -EAGAIN) { + log_warning("Requested transaction contains an unfixable cyclic ordering dependency: %s", bus_error(e, r)); + goto rollback; + } + + /* Let's see if the resulting transaction ordering + * graph is still cyclic... */ + } + + for (;;) { + /* Sixth step: let's drop unmergeable entries if + * necessary and possible, merge entries we can + * merge */ + if ((r = transaction_merge_jobs(m, e)) >= 0) + break; + + if (r != -EAGAIN) { + log_warning("Requested transaction contains unmergeable jobs: %s", bus_error(e, r)); + goto rollback; + } + + /* Seventh step: an entry got dropped, let's garbage + * collect its dependencies. */ + if (mode != JOB_ISOLATE) + transaction_collect_garbage(m); + + /* Let's see if the resulting transaction still has + * unmergeable entries ... */ + } + + /* Eights step: Drop redundant jobs again, if the merging now allows us to drop more. */ + transaction_drop_redundant(m); + + /* Ninth step: check whether we can actually apply this */ + if (mode == JOB_FAIL) + if ((r = transaction_is_destructive(m, e)) < 0) { + log_notice("Requested transaction contradicts existing jobs: %s", bus_error(e, r)); + goto rollback; + } + + /* Tenth step: apply changes */ + if ((r = transaction_apply(m, mode)) < 0) { + log_warning("Failed to apply transaction: %s", strerror(-r)); + goto rollback; + } + + assert(hashmap_isempty(m->transaction_jobs)); + assert(!m->transaction_anchor); + + return 0; + +rollback: + transaction_abort(m); + return r; +} + +static Job* transaction_add_one_job(Manager *m, JobType type, Unit *unit, bool override, bool *is_new) { + Job *j, *f; + + assert(m); + assert(unit); + + /* Looks for an existing prospective job and returns that. If + * it doesn't exist it is created and added to the prospective + * jobs list. */ + + f = hashmap_get(m->transaction_jobs, unit); + + LIST_FOREACH(transaction, j, f) { + assert(j->unit == unit); + + if (j->type == type) { + if (is_new) + *is_new = false; + return j; + } + } + + if (unit->job && unit->job->type == type) + j = unit->job; + else if (!(j = job_new(m, type, unit))) + return NULL; + + j->generation = 0; + j->marker = NULL; + j->matters_to_anchor = false; + j->override = override; + + LIST_PREPEND(Job, transaction, f, j); + + if (hashmap_replace(m->transaction_jobs, unit, f) < 0) { + job_free(j); + return NULL; + } + + if (is_new) + *is_new = true; + + /* log_debug("Added job %s/%s to transaction.", unit->id, job_type_to_string(type)); */ + + return j; +} + +void manager_transaction_unlink_job(Manager *m, Job *j, bool delete_dependencies) { + assert(m); + assert(j); + + if (j->transaction_prev) + j->transaction_prev->transaction_next = j->transaction_next; + else if (j->transaction_next) + hashmap_replace(m->transaction_jobs, j->unit, j->transaction_next); + else + hashmap_remove_value(m->transaction_jobs, j->unit, j); + + if (j->transaction_next) + j->transaction_next->transaction_prev = j->transaction_prev; + + j->transaction_prev = j->transaction_next = NULL; + + while (j->subject_list) + job_dependency_free(j->subject_list); + + while (j->object_list) { + Job *other = j->object_list->matters ? j->object_list->subject : NULL; + + job_dependency_free(j->object_list); + + if (other && delete_dependencies) { + log_debug("Deleting job %s/%s as dependency of job %s/%s", + other->unit->id, job_type_to_string(other->type), + j->unit->id, job_type_to_string(j->type)); + transaction_delete_job(m, other, delete_dependencies); + } + } +} + +static int transaction_add_job_and_dependencies( + Manager *m, + JobType type, + Unit *unit, + Job *by, + bool matters, + bool override, + bool conflicts, + bool ignore_requirements, + bool ignore_order, + DBusError *e, + Job **_ret) { + Job *ret; + Iterator i; + Unit *dep; + int r; + bool is_new; + + assert(m); + assert(type < _JOB_TYPE_MAX); + assert(unit); + + /* log_debug("Pulling in %s/%s from %s/%s", */ + /* unit->id, job_type_to_string(type), */ + /* by ? by->unit->id : "NA", */ + /* by ? job_type_to_string(by->type) : "NA"); */ + + if (unit->load_state != UNIT_LOADED && + unit->load_state != UNIT_ERROR && + unit->load_state != UNIT_MASKED) { + dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id); + return -EINVAL; + } + + if (type != JOB_STOP && unit->load_state == UNIT_ERROR) { + dbus_set_error(e, BUS_ERROR_LOAD_FAILED, + "Unit %s failed to load: %s. " + "See system logs and 'systemctl status %s' for details.", + unit->id, + strerror(-unit->load_error), + unit->id); + return -EINVAL; + } + + if (type != JOB_STOP && unit->load_state == UNIT_MASKED) { + dbus_set_error(e, BUS_ERROR_MASKED, "Unit %s is masked.", unit->id); + return -EINVAL; + } + + if (!unit_job_is_applicable(unit, type)) { + dbus_set_error(e, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, "Job type %s is not applicable for unit %s.", job_type_to_string(type), unit->id); + return -EBADR; + } + + /* First add the job. */ + if (!(ret = transaction_add_one_job(m, type, unit, override, &is_new))) + return -ENOMEM; + + ret->ignore_order = ret->ignore_order || ignore_order; + + /* Then, add a link to the job. */ + if (!job_dependency_new(by, ret, matters, conflicts)) + return -ENOMEM; + + if (is_new && !ignore_requirements) { + Set *following; + + /* If we are following some other unit, make sure we + * add all dependencies of everybody following. */ + if (unit_following_set(ret->unit, &following) > 0) { + SET_FOREACH(dep, following, i) + if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, false, override, false, false, ignore_order, e, NULL)) < 0) { + log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->id, bus_error(e, r)); + + if (e) + dbus_error_free(e); + } + + set_free(following); + } + + /* Finally, recursively add in all dependencies. */ + if (type == JOB_START || type == JOB_RELOAD_OR_START) { + SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUIRES], i) + if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) { + if (r != -EBADR) + goto fail; + + if (e) + dbus_error_free(e); + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_BIND_TO], i) + if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) { + + if (r != -EBADR) + goto fail; + + if (e) + dbus_error_free(e); + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUIRES_OVERRIDABLE], i) + if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, !override, override, false, false, ignore_order, e, NULL)) < 0) { + log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->id, bus_error(e, r)); + + if (e) + dbus_error_free(e); + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_WANTS], i) + if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, false, false, false, false, ignore_order, e, NULL)) < 0) { + log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->id, bus_error(e, r)); + + if (e) + dbus_error_free(e); + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUISITE], i) + if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) { + + if (r != -EBADR) + goto fail; + + if (e) + dbus_error_free(e); + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUISITE_OVERRIDABLE], i) + if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, !override, override, false, false, ignore_order, e, NULL)) < 0) { + log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->id, bus_error(e, r)); + + if (e) + dbus_error_free(e); + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_CONFLICTS], i) + if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, true, override, true, false, ignore_order, e, NULL)) < 0) { + + if (r != -EBADR) + goto fail; + + if (e) + dbus_error_free(e); + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_CONFLICTED_BY], i) + if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, false, override, false, false, ignore_order, e, NULL)) < 0) { + log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->id, bus_error(e, r)); + + if (e) + dbus_error_free(e); + } + + } + + if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) { + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUIRED_BY], i) + if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) { + + if (r != -EBADR) + goto fail; + + if (e) + dbus_error_free(e); + } + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_BOUND_BY], i) + if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, false, ignore_order, e, NULL)) < 0) { + + if (r != -EBADR) + goto fail; + + if (e) + dbus_error_free(e); + } + } + + if (type == JOB_RELOAD || type == JOB_RELOAD_OR_START) { + + SET_FOREACH(dep, ret->unit->dependencies[UNIT_PROPAGATE_RELOAD_TO], i) { + r = transaction_add_job_and_dependencies(m, JOB_RELOAD, dep, ret, false, override, false, false, ignore_order, e, NULL); + + if (r < 0) { + log_warning("Cannot add dependency reload job for unit %s, ignoring: %s", dep->id, bus_error(e, r)); + + if (e) + dbus_error_free(e); + } + } + } + + /* JOB_VERIFY_STARTED, JOB_RELOAD require no dependency handling */ + } + + if (_ret) + *_ret = ret; + + return 0; + +fail: + return r; +} + +static int transaction_add_isolate_jobs(Manager *m) { + Iterator i; + Unit *u; + char *k; + int r; + + assert(m); + + HASHMAP_FOREACH_KEY(u, k, m->units, i) { + + /* ignore aliases */ + if (u->id != k) + continue; + + if (u->ignore_on_isolate) + continue; + + /* No need to stop inactive jobs */ + if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)) && !u->job) + continue; + + /* Is there already something listed for this? */ + if (hashmap_get(m->transaction_jobs, u)) + continue; + + if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, u, NULL, true, false, false, false, false, NULL, NULL)) < 0) + log_warning("Cannot add isolate job for unit %s, ignoring: %s", u->id, strerror(-r)); + } + + return 0; +} + +int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, DBusError *e, Job **_ret) { + int r; + Job *ret; + + assert(m); + assert(type < _JOB_TYPE_MAX); + assert(unit); + assert(mode < _JOB_MODE_MAX); + + if (mode == JOB_ISOLATE && type != JOB_START) { + dbus_set_error(e, BUS_ERROR_INVALID_JOB_MODE, "Isolate is only valid for start."); + return -EINVAL; + } + + if (mode == JOB_ISOLATE && !unit->allow_isolate) { + dbus_set_error(e, BUS_ERROR_NO_ISOLATION, "Operation refused, unit may not be isolated."); + return -EPERM; + } + + log_debug("Trying to enqueue job %s/%s/%s", unit->id, job_type_to_string(type), job_mode_to_string(mode)); + + if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, override, false, + mode == JOB_IGNORE_DEPENDENCIES || mode == JOB_IGNORE_REQUIREMENTS, + mode == JOB_IGNORE_DEPENDENCIES, e, &ret)) < 0) { + transaction_abort(m); + return r; + } + + if (mode == JOB_ISOLATE) + if ((r = transaction_add_isolate_jobs(m)) < 0) { + transaction_abort(m); + return r; + } + + if ((r = transaction_activate(m, mode, e)) < 0) + return r; + + log_debug("Enqueued job %s/%s as %u", unit->id, job_type_to_string(type), (unsigned) ret->id); + + if (_ret) + *_ret = ret; + + return 0; +} + +int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, DBusError *e, Job **_ret) { + Unit *unit; + int r; + + assert(m); + assert(type < _JOB_TYPE_MAX); + assert(name); + assert(mode < _JOB_MODE_MAX); + + if ((r = manager_load_unit(m, name, NULL, NULL, &unit)) < 0) + return r; + + return manager_add_job(m, type, unit, mode, override, e, _ret); +} + +Job *manager_get_job(Manager *m, uint32_t id) { + assert(m); + + return hashmap_get(m->jobs, UINT32_TO_PTR(id)); +} + +Unit *manager_get_unit(Manager *m, const char *name) { + assert(m); + assert(name); + + return hashmap_get(m->units, name); +} + +unsigned manager_dispatch_load_queue(Manager *m) { + Unit *u; + unsigned n = 0; + + assert(m); + + /* Make sure we are not run recursively */ + if (m->dispatching_load_queue) + return 0; + + m->dispatching_load_queue = true; + + /* Dispatches the load queue. Takes a unit from the queue and + * tries to load its data until the queue is empty */ + + while ((u = m->load_queue)) { + assert(u->in_load_queue); + + unit_load(u); + n++; + } + + m->dispatching_load_queue = false; + return n; +} + +int manager_load_unit_prepare(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) { + Unit *ret; + UnitType t; + int r; + + assert(m); + assert(name || path); + + /* This will prepare the unit for loading, but not actually + * load anything from disk. */ + + if (path && !is_path(path)) { + dbus_set_error(e, BUS_ERROR_INVALID_PATH, "Path %s is not absolute.", path); + return -EINVAL; + } + + if (!name) + name = file_name_from_path(path); + + t = unit_name_to_type(name); + + if (t == _UNIT_TYPE_INVALID || !unit_name_is_valid_no_type(name, false)) { + dbus_set_error(e, BUS_ERROR_INVALID_NAME, "Unit name %s is not valid.", name); + return -EINVAL; + } + + ret = manager_get_unit(m, name); + if (ret) { + *_ret = ret; + return 1; + } + + ret = unit_new(m, unit_vtable[t]->object_size); + if (!ret) + return -ENOMEM; + + if (path) { + ret->fragment_path = strdup(path); + if (!ret->fragment_path) { + unit_free(ret); + return -ENOMEM; + } + } + + if ((r = unit_add_name(ret, name)) < 0) { + unit_free(ret); + return r; + } + + unit_add_to_load_queue(ret); + unit_add_to_dbus_queue(ret); + unit_add_to_gc_queue(ret); + + if (_ret) + *_ret = ret; + + return 0; +} + +int manager_load_unit(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret) { + int r; + + assert(m); + + /* This will load the service information files, but not actually + * start any services or anything. */ + + if ((r = manager_load_unit_prepare(m, name, path, e, _ret)) != 0) + return r; + + manager_dispatch_load_queue(m); + + if (_ret) + *_ret = unit_follow_merge(*_ret); + + return 0; +} + +void manager_dump_jobs(Manager *s, FILE *f, const char *prefix) { + Iterator i; + Job *j; + + assert(s); + assert(f); + + HASHMAP_FOREACH(j, s->jobs, i) + job_dump(j, f, prefix); +} + +void manager_dump_units(Manager *s, FILE *f, const char *prefix) { + Iterator i; + Unit *u; + const char *t; + + assert(s); + assert(f); + + HASHMAP_FOREACH_KEY(u, t, s->units, i) + if (u->id == t) + unit_dump(u, f, prefix); +} + +void manager_clear_jobs(Manager *m) { + Job *j; + + assert(m); + + transaction_abort(m); + + while ((j = hashmap_first(m->jobs))) + job_finish_and_invalidate(j, JOB_CANCELED); +} + +unsigned manager_dispatch_run_queue(Manager *m) { + Job *j; + unsigned n = 0; + + if (m->dispatching_run_queue) + return 0; + + m->dispatching_run_queue = true; + + while ((j = m->run_queue)) { + assert(j->installed); + assert(j->in_run_queue); + + job_run_and_invalidate(j); + n++; + } + + m->dispatching_run_queue = false; + return n; +} + +unsigned manager_dispatch_dbus_queue(Manager *m) { + Job *j; + Unit *u; + unsigned n = 0; + + assert(m); + + if (m->dispatching_dbus_queue) + return 0; + + m->dispatching_dbus_queue = true; + + while ((u = m->dbus_unit_queue)) { + assert(u->in_dbus_queue); + + bus_unit_send_change_signal(u); + n++; + } + + while ((j = m->dbus_job_queue)) { + assert(j->in_dbus_queue); + + bus_job_send_change_signal(j); + n++; + } + + m->dispatching_dbus_queue = false; + return n; +} + +static int manager_process_notify_fd(Manager *m) { + ssize_t n; + + assert(m); + + for (;;) { + char buf[4096]; + struct msghdr msghdr; + struct iovec iovec; + struct ucred *ucred; + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; + } control; + Unit *u; + char **tags; + + zero(iovec); + iovec.iov_base = buf; + iovec.iov_len = sizeof(buf)-1; + + zero(control); + zero(msghdr); + msghdr.msg_iov = &iovec; + msghdr.msg_iovlen = 1; + msghdr.msg_control = &control; + msghdr.msg_controllen = sizeof(control); + + if ((n = recvmsg(m->notify_watch.fd, &msghdr, MSG_DONTWAIT)) <= 0) { + if (n >= 0) + return -EIO; + + if (errno == EAGAIN || errno == EINTR) + break; + + return -errno; + } + + if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) || + control.cmsghdr.cmsg_level != SOL_SOCKET || + control.cmsghdr.cmsg_type != SCM_CREDENTIALS || + control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) { + log_warning("Received notify message without credentials. Ignoring."); + continue; + } + + ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr); + + if (!(u = hashmap_get(m->watch_pids, LONG_TO_PTR(ucred->pid)))) + if (!(u = cgroup_unit_by_pid(m, ucred->pid))) { + log_warning("Cannot find unit for notify message of PID %lu.", (unsigned long) ucred->pid); + continue; + } + + assert((size_t) n < sizeof(buf)); + buf[n] = 0; + if (!(tags = strv_split(buf, "\n\r"))) + return -ENOMEM; + + log_debug("Got notification message for unit %s", u->id); + + if (UNIT_VTABLE(u)->notify_message) + UNIT_VTABLE(u)->notify_message(u, ucred->pid, tags); + + strv_free(tags); + } + + return 0; +} + +static int manager_dispatch_sigchld(Manager *m) { + assert(m); + + for (;;) { + siginfo_t si; + Unit *u; + int r; + + zero(si); + + /* First we call waitd() for a PID and do not reap the + * zombie. That way we can still access /proc/$PID for + * it while it is a zombie. */ + if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) { + + if (errno == ECHILD) + break; + + if (errno == EINTR) + continue; + + return -errno; + } + + if (si.si_pid <= 0) + break; + + if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) { + char *name = NULL; + + get_process_comm(si.si_pid, &name); + log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name)); + free(name); + } + + /* Let's flush any message the dying child might still + * have queued for us. This ensures that the process + * still exists in /proc so that we can figure out + * which cgroup and hence unit it belongs to. */ + if ((r = manager_process_notify_fd(m)) < 0) + return r; + + /* And now figure out the unit this belongs to */ + if (!(u = hashmap_get(m->watch_pids, LONG_TO_PTR(si.si_pid)))) + u = cgroup_unit_by_pid(m, si.si_pid); + + /* And now, we actually reap the zombie. */ + if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) { + if (errno == EINTR) + continue; + + return -errno; + } + + if (si.si_code != CLD_EXITED && si.si_code != CLD_KILLED && si.si_code != CLD_DUMPED) + continue; + + log_debug("Child %lu died (code=%s, status=%i/%s)", + (long unsigned) si.si_pid, + sigchld_code_to_string(si.si_code), + si.si_status, + strna(si.si_code == CLD_EXITED + ? exit_status_to_string(si.si_status, EXIT_STATUS_FULL) + : signal_to_string(si.si_status))); + + if (!u) + continue; + + log_debug("Child %lu belongs to %s", (long unsigned) si.si_pid, u->id); + + hashmap_remove(m->watch_pids, LONG_TO_PTR(si.si_pid)); + UNIT_VTABLE(u)->sigchld_event(u, si.si_pid, si.si_code, si.si_status); + } + + return 0; +} + +static int manager_start_target(Manager *m, const char *name, JobMode mode) { + int r; + DBusError error; + + dbus_error_init(&error); + + log_debug("Activating special unit %s", name); + + if ((r = manager_add_job_by_name(m, JOB_START, name, mode, true, &error, NULL)) < 0) + log_error("Failed to enqueue %s job: %s", name, bus_error(&error, r)); + + dbus_error_free(&error); + + return r; +} + +static int manager_process_signal_fd(Manager *m) { + ssize_t n; + struct signalfd_siginfo sfsi; + bool sigchld = false; + + assert(m); + + for (;;) { + if ((n = read(m->signal_watch.fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) { + + if (n >= 0) + return -EIO; + + if (errno == EINTR || errno == EAGAIN) + break; + + return -errno; + } + + if (sfsi.ssi_pid > 0) { + char *p = NULL; + + get_process_comm(sfsi.ssi_pid, &p); + + log_debug("Received SIG%s from PID %lu (%s).", + signal_to_string(sfsi.ssi_signo), + (unsigned long) sfsi.ssi_pid, strna(p)); + free(p); + } else + log_debug("Received SIG%s.", signal_to_string(sfsi.ssi_signo)); + + switch (sfsi.ssi_signo) { + + case SIGCHLD: + sigchld = true; + break; + + case SIGTERM: + if (m->running_as == MANAGER_SYSTEM) { + /* This is for compatibility with the + * original sysvinit */ + m->exit_code = MANAGER_REEXECUTE; + break; + } + + /* Fall through */ + + case SIGINT: + if (m->running_as == MANAGER_SYSTEM) { + manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE); + break; + } + + /* Run the exit target if there is one, if not, just exit. */ + if (manager_start_target(m, SPECIAL_EXIT_TARGET, JOB_REPLACE) < 0) { + m->exit_code = MANAGER_EXIT; + return 0; + } + + break; + + case SIGWINCH: + if (m->running_as == MANAGER_SYSTEM) + manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE); + + /* This is a nop on non-init */ + break; + + case SIGPWR: + if (m->running_as == MANAGER_SYSTEM) + manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE); + + /* This is a nop on non-init */ + break; + + case SIGUSR1: { + Unit *u; + + u = manager_get_unit(m, SPECIAL_DBUS_SERVICE); + + if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) { + log_info("Trying to reconnect to bus..."); + bus_init(m, true); + } + + if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) { + log_info("Loading D-Bus service..."); + manager_start_target(m, SPECIAL_DBUS_SERVICE, JOB_REPLACE); + } + + break; + } + + case SIGUSR2: { + FILE *f; + char *dump = NULL; + size_t size; + + if (!(f = open_memstream(&dump, &size))) { + log_warning("Failed to allocate memory stream."); + break; + } + + manager_dump_units(m, f, "\t"); + manager_dump_jobs(m, f, "\t"); + + if (ferror(f)) { + fclose(f); + free(dump); + log_warning("Failed to write status stream"); + break; + } + + fclose(f); + log_dump(LOG_INFO, dump); + free(dump); + + break; + } + + case SIGHUP: + m->exit_code = MANAGER_RELOAD; + break; + + default: { + + /* Starting SIGRTMIN+0 */ + static const char * const target_table[] = { + [0] = SPECIAL_DEFAULT_TARGET, + [1] = SPECIAL_RESCUE_TARGET, + [2] = SPECIAL_EMERGENCY_TARGET, + [3] = SPECIAL_HALT_TARGET, + [4] = SPECIAL_POWEROFF_TARGET, + [5] = SPECIAL_REBOOT_TARGET, + [6] = SPECIAL_KEXEC_TARGET + }; + + /* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */ + static const ManagerExitCode code_table[] = { + [0] = MANAGER_HALT, + [1] = MANAGER_POWEROFF, + [2] = MANAGER_REBOOT, + [3] = MANAGER_KEXEC + }; + + if ((int) sfsi.ssi_signo >= SIGRTMIN+0 && + (int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) { + int idx = (int) sfsi.ssi_signo - SIGRTMIN; + manager_start_target(m, target_table[idx], + (idx == 1 || idx == 2) ? JOB_ISOLATE : JOB_REPLACE); + break; + } + + if ((int) sfsi.ssi_signo >= SIGRTMIN+13 && + (int) sfsi.ssi_signo < SIGRTMIN+13+(int) ELEMENTSOF(code_table)) { + m->exit_code = code_table[sfsi.ssi_signo - SIGRTMIN - 13]; + break; + } + + switch (sfsi.ssi_signo - SIGRTMIN) { + + case 20: + log_debug("Enabling showing of status."); + manager_set_show_status(m, true); + break; + + case 21: + log_debug("Disabling showing of status."); + manager_set_show_status(m, false); + break; + + case 22: + log_set_max_level(LOG_DEBUG); + log_notice("Setting log level to debug."); + break; + + case 23: + log_set_max_level(LOG_INFO); + log_notice("Setting log level to info."); + break; + + case 26: + log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); + log_notice("Setting log target to journal-or-kmsg."); + break; + + case 27: + log_set_target(LOG_TARGET_CONSOLE); + log_notice("Setting log target to console."); + break; + + case 28: + log_set_target(LOG_TARGET_KMSG); + log_notice("Setting log target to kmsg."); + break; + + case 29: + log_set_target(LOG_TARGET_SYSLOG_OR_KMSG); + log_notice("Setting log target to syslog-or-kmsg."); + break; + + default: + log_warning("Got unhandled signal <%s>.", signal_to_string(sfsi.ssi_signo)); + } + } + } + } + + if (sigchld) + return manager_dispatch_sigchld(m); + + return 0; +} + +static int process_event(Manager *m, struct epoll_event *ev) { + int r; + Watch *w; + + assert(m); + assert(ev); + + assert_se(w = ev->data.ptr); + + if (w->type == WATCH_INVALID) + return 0; + + switch (w->type) { + + case WATCH_SIGNAL: + + /* An incoming signal? */ + if (ev->events != EPOLLIN) + return -EINVAL; + + if ((r = manager_process_signal_fd(m)) < 0) + return r; + + break; + + case WATCH_NOTIFY: + + /* An incoming daemon notification event? */ + if (ev->events != EPOLLIN) + return -EINVAL; + + if ((r = manager_process_notify_fd(m)) < 0) + return r; + + break; + + case WATCH_FD: + + /* Some fd event, to be dispatched to the units */ + UNIT_VTABLE(w->data.unit)->fd_event(w->data.unit, w->fd, ev->events, w); + break; + + case WATCH_UNIT_TIMER: + case WATCH_JOB_TIMER: { + uint64_t v; + ssize_t k; + + /* Some timer event, to be dispatched to the units */ + if ((k = read(w->fd, &v, sizeof(v))) != sizeof(v)) { + + if (k < 0 && (errno == EINTR || errno == EAGAIN)) + break; + + return k < 0 ? -errno : -EIO; + } + + if (w->type == WATCH_UNIT_TIMER) + UNIT_VTABLE(w->data.unit)->timer_event(w->data.unit, v, w); + else + job_timer_event(w->data.job, v, w); + break; + } + + case WATCH_MOUNT: + /* Some mount table change, intended for the mount subsystem */ + mount_fd_event(m, ev->events); + break; + + case WATCH_SWAP: + /* Some swap table change, intended for the swap subsystem */ + swap_fd_event(m, ev->events); + break; + + case WATCH_UDEV: + /* Some notification from udev, intended for the device subsystem */ + device_fd_event(m, ev->events); + break; + + case WATCH_DBUS_WATCH: + bus_watch_event(m, w, ev->events); + break; + + case WATCH_DBUS_TIMEOUT: + bus_timeout_event(m, w, ev->events); + break; + + default: + log_error("event type=%i", w->type); + assert_not_reached("Unknown epoll event type."); + } + + return 0; +} + +int manager_loop(Manager *m) { + int r; + + RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000); + + assert(m); + m->exit_code = MANAGER_RUNNING; + + /* Release the path cache */ + set_free_free(m->unit_path_cache); + m->unit_path_cache = NULL; + + manager_check_finished(m); + + /* There might still be some zombies hanging around from + * before we were exec()'ed. Leat's reap them */ + if ((r = manager_dispatch_sigchld(m)) < 0) + return r; + + while (m->exit_code == MANAGER_RUNNING) { + struct epoll_event event; + int n; + + if (!ratelimit_test(&rl)) { + /* Yay, something is going seriously wrong, pause a little */ + log_warning("Looping too fast. Throttling execution a little."); + sleep(1); + } + + if (manager_dispatch_load_queue(m) > 0) + continue; + + if (manager_dispatch_run_queue(m) > 0) + continue; + + if (bus_dispatch(m) > 0) + continue; + + if (manager_dispatch_cleanup_queue(m) > 0) + continue; + + if (manager_dispatch_gc_queue(m) > 0) + continue; + + if (manager_dispatch_dbus_queue(m) > 0) + continue; + + if (swap_dispatch_reload(m) > 0) + continue; + + if ((n = epoll_wait(m->epoll_fd, &event, 1, -1)) < 0) { + + if (errno == EINTR) + continue; + + return -errno; + } + + assert(n == 1); + + if ((r = process_event(m, &event)) < 0) + return r; + } + + return m->exit_code; +} + +int manager_get_unit_from_dbus_path(Manager *m, const char *s, Unit **_u) { + char *n; + Unit *u; + + assert(m); + assert(s); + assert(_u); + + if (!startswith(s, "/org/freedesktop/systemd1/unit/")) + return -EINVAL; + + if (!(n = bus_path_unescape(s+31))) + return -ENOMEM; + + u = manager_get_unit(m, n); + free(n); + + if (!u) + return -ENOENT; + + *_u = u; + + return 0; +} + +int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j) { + Job *j; + unsigned id; + int r; + + assert(m); + assert(s); + assert(_j); + + if (!startswith(s, "/org/freedesktop/systemd1/job/")) + return -EINVAL; + + if ((r = safe_atou(s + 30, &id)) < 0) + return r; + + if (!(j = manager_get_job(m, id))) + return -ENOENT; + + *_j = j; + + return 0; +} + +void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) { + +#ifdef HAVE_AUDIT + char *p; + + if (m->audit_fd < 0) + return; + + /* Don't generate audit events if the service was already + * started and we're just deserializing */ + if (m->n_reloading > 0) + return; + + if (m->running_as != MANAGER_SYSTEM) + return; + + if (u->type != UNIT_SERVICE) + return; + + if (!(p = unit_name_to_prefix_and_instance(u->id))) { + log_error("Failed to allocate unit name for audit message: %s", strerror(ENOMEM)); + return; + } + + if (audit_log_user_comm_message(m->audit_fd, type, "", p, NULL, NULL, NULL, success) < 0) { + log_warning("Failed to send audit message: %m"); + + if (errno == EPERM) { + /* We aren't allowed to send audit messages? + * Then let's not retry again, to avoid + * spamming the user with the same and same + * messages over and over. */ + + audit_close(m->audit_fd); + m->audit_fd = -1; + } + } + + free(p); +#endif + +} + +void manager_send_unit_plymouth(Manager *m, Unit *u) { + int fd = -1; + union sockaddr_union sa; + int n = 0; + char *message = NULL; + + /* Don't generate plymouth events if the service was already + * started and we're just deserializing */ + if (m->n_reloading > 0) + return; + + if (m->running_as != MANAGER_SYSTEM) + return; + + if (u->type != UNIT_SERVICE && + u->type != UNIT_MOUNT && + u->type != UNIT_SWAP) + return; + + /* We set SOCK_NONBLOCK here so that we rather drop the + * message then wait for plymouth */ + if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) { + log_error("socket() failed: %m"); + return; + } + + zero(sa); + sa.sa.sa_family = AF_UNIX; + strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1); + if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) { + + if (errno != EPIPE && + errno != EAGAIN && + errno != ENOENT && + errno != ECONNREFUSED && + errno != ECONNRESET && + errno != ECONNABORTED) + log_error("connect() failed: %m"); + + goto finish; + } + + if (asprintf(&message, "U\002%c%s%n", (int) (strlen(u->id) + 1), u->id, &n) < 0) { + log_error("Out of memory"); + goto finish; + } + + errno = 0; + if (write(fd, message, n + 1) != n + 1) { + + if (errno != EPIPE && + errno != EAGAIN && + errno != ENOENT && + errno != ECONNREFUSED && + errno != ECONNRESET && + errno != ECONNABORTED) + log_error("Failed to write Plymouth message: %m"); + + goto finish; + } + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + free(message); +} + +void manager_dispatch_bus_name_owner_changed( + Manager *m, + const char *name, + const char* old_owner, + const char *new_owner) { + + Unit *u; + + assert(m); + assert(name); + + if (!(u = hashmap_get(m->watch_bus, name))) + return; + + UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner); +} + +void manager_dispatch_bus_query_pid_done( + Manager *m, + const char *name, + pid_t pid) { + + Unit *u; + + assert(m); + assert(name); + assert(pid >= 1); + + if (!(u = hashmap_get(m->watch_bus, name))) + return; + + UNIT_VTABLE(u)->bus_query_pid_done(u, name, pid); +} + +int manager_open_serialization(Manager *m, FILE **_f) { + char *path = NULL; + mode_t saved_umask; + int fd; + FILE *f; + + assert(_f); + + if (m->running_as == MANAGER_SYSTEM) + asprintf(&path, "/run/systemd/dump-%lu-XXXXXX", (unsigned long) getpid()); + else + asprintf(&path, "/tmp/systemd-dump-%lu-XXXXXX", (unsigned long) getpid()); + + if (!path) + return -ENOMEM; + + saved_umask = umask(0077); + fd = mkostemp(path, O_RDWR|O_CLOEXEC); + umask(saved_umask); + + if (fd < 0) { + free(path); + return -errno; + } + + unlink(path); + + log_debug("Serializing state to %s", path); + free(path); + + if (!(f = fdopen(fd, "w+"))) + return -errno; + + *_f = f; + + return 0; +} + +int manager_serialize(Manager *m, FILE *f, FDSet *fds) { + Iterator i; + Unit *u; + const char *t; + int r; + + assert(m); + assert(f); + assert(fds); + + m->n_reloading ++; + + fprintf(f, "current-job-id=%i\n", m->current_job_id); + fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr)); + + dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp); + dual_timestamp_serialize(f, "startup-timestamp", &m->startup_timestamp); + dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp); + + fputc('\n', f); + + HASHMAP_FOREACH_KEY(u, t, m->units, i) { + if (u->id != t) + continue; + + if (!unit_can_serialize(u)) + continue; + + /* Start marker */ + fputs(u->id, f); + fputc('\n', f); + + if ((r = unit_serialize(u, f, fds)) < 0) { + m->n_reloading --; + return r; + } + } + + assert(m->n_reloading > 0); + m->n_reloading --; + + if (ferror(f)) + return -EIO; + + r = bus_fdset_add_all(m, fds); + if (r < 0) + return r; + + return 0; +} + +int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { + int r = 0; + + assert(m); + assert(f); + + log_debug("Deserializing state..."); + + m->n_reloading ++; + + for (;;) { + char line[LINE_MAX], *l; + + if (!fgets(line, sizeof(line), f)) { + if (feof(f)) + r = 0; + else + r = -errno; + + goto finish; + } + + char_array_0(line); + l = strstrip(line); + + if (l[0] == 0) + break; + + if (startswith(l, "current-job-id=")) { + uint32_t id; + + if (safe_atou32(l+15, &id) < 0) + log_debug("Failed to parse current job id value %s", l+15); + else + m->current_job_id = MAX(m->current_job_id, id); + } else if (startswith(l, "taint-usr=")) { + int b; + + if ((b = parse_boolean(l+10)) < 0) + log_debug("Failed to parse taint /usr flag %s", l+10); + else + m->taint_usr = m->taint_usr || b; + } else if (startswith(l, "initrd-timestamp=")) + dual_timestamp_deserialize(l+17, &m->initrd_timestamp); + else if (startswith(l, "startup-timestamp=")) + dual_timestamp_deserialize(l+18, &m->startup_timestamp); + else if (startswith(l, "finish-timestamp=")) + dual_timestamp_deserialize(l+17, &m->finish_timestamp); + else + log_debug("Unknown serialization item '%s'", l); + } + + for (;;) { + Unit *u; + char name[UNIT_NAME_MAX+2]; + + /* Start marker */ + if (!fgets(name, sizeof(name), f)) { + if (feof(f)) + r = 0; + else + r = -errno; + + goto finish; + } + + char_array_0(name); + + if ((r = manager_load_unit(m, strstrip(name), NULL, NULL, &u)) < 0) + goto finish; + + if ((r = unit_deserialize(u, f, fds)) < 0) + goto finish; + } + +finish: + if (ferror(f)) { + r = -EIO; + goto finish; + } + + assert(m->n_reloading > 0); + m->n_reloading --; + + return r; +} + +int manager_reload(Manager *m) { + int r, q; + FILE *f; + FDSet *fds; + + assert(m); + + if ((r = manager_open_serialization(m, &f)) < 0) + return r; + + m->n_reloading ++; + + if (!(fds = fdset_new())) { + m->n_reloading --; + r = -ENOMEM; + goto finish; + } + + if ((r = manager_serialize(m, f, fds)) < 0) { + m->n_reloading --; + goto finish; + } + + if (fseeko(f, 0, SEEK_SET) < 0) { + m->n_reloading --; + r = -errno; + goto finish; + } + + /* From here on there is no way back. */ + manager_clear_jobs_and_units(m); + manager_undo_generators(m); + + /* Find new unit paths */ + lookup_paths_free(&m->lookup_paths); + if ((q = lookup_paths_init(&m->lookup_paths, m->running_as, true)) < 0) + r = q; + + manager_run_generators(m); + + manager_build_unit_path_cache(m); + + /* First, enumerate what we can from all config files */ + if ((q = manager_enumerate(m)) < 0) + r = q; + + /* Second, deserialize our stored data */ + if ((q = manager_deserialize(m, f, fds)) < 0) + r = q; + + fclose(f); + f = NULL; + + /* Third, fire things up! */ + if ((q = manager_coldplug(m)) < 0) + r = q; + + assert(m->n_reloading > 0); + m->n_reloading--; + +finish: + if (f) + fclose(f); + + if (fds) + fdset_free(fds); + + return r; +} + +bool manager_is_booting_or_shutting_down(Manager *m) { + Unit *u; + + assert(m); + + /* Is the initial job still around? */ + if (manager_get_job(m, m->default_unit_job_id)) + return true; + + /* Is there a job for the shutdown target? */ + u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET); + if (u) + return !!u->job; + + return false; +} + +void manager_reset_failed(Manager *m) { + Unit *u; + Iterator i; + + assert(m); + + HASHMAP_FOREACH(u, m->units, i) + unit_reset_failed(u); +} + +bool manager_unit_pending_inactive(Manager *m, const char *name) { + Unit *u; + + assert(m); + assert(name); + + /* Returns true if the unit is inactive or going down */ + if (!(u = manager_get_unit(m, name))) + return true; + + return unit_pending_inactive(u); +} + +void manager_check_finished(Manager *m) { + char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX]; + usec_t kernel_usec = 0, initrd_usec = 0, userspace_usec = 0, total_usec = 0; + + assert(m); + + if (dual_timestamp_is_set(&m->finish_timestamp)) + return; + + if (hashmap_size(m->jobs) > 0) + return; + + dual_timestamp_get(&m->finish_timestamp); + + if (m->running_as == MANAGER_SYSTEM && detect_container(NULL) <= 0) { + + userspace_usec = m->finish_timestamp.monotonic - m->startup_timestamp.monotonic; + total_usec = m->finish_timestamp.monotonic; + + if (dual_timestamp_is_set(&m->initrd_timestamp)) { + + kernel_usec = m->initrd_timestamp.monotonic; + initrd_usec = m->startup_timestamp.monotonic - m->initrd_timestamp.monotonic; + + log_info("Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.", + format_timespan(kernel, sizeof(kernel), kernel_usec), + format_timespan(initrd, sizeof(initrd), initrd_usec), + format_timespan(userspace, sizeof(userspace), userspace_usec), + format_timespan(sum, sizeof(sum), total_usec)); + } else { + kernel_usec = m->startup_timestamp.monotonic; + initrd_usec = 0; + + log_info("Startup finished in %s (kernel) + %s (userspace) = %s.", + format_timespan(kernel, sizeof(kernel), kernel_usec), + format_timespan(userspace, sizeof(userspace), userspace_usec), + format_timespan(sum, sizeof(sum), total_usec)); + } + } else { + userspace_usec = initrd_usec = kernel_usec = 0; + total_usec = m->finish_timestamp.monotonic - m->startup_timestamp.monotonic; + + log_debug("Startup finished in %s.", + format_timespan(sum, sizeof(sum), total_usec)); + } + + bus_broadcast_finished(m, kernel_usec, initrd_usec, userspace_usec, total_usec); + + sd_notifyf(false, + "READY=1\nSTATUS=Startup finished in %s.", + format_timespan(sum, sizeof(sum), total_usec)); +} + +void manager_run_generators(Manager *m) { + DIR *d = NULL; + const char *generator_path; + const char *argv[3]; + mode_t u; + + assert(m); + + generator_path = m->running_as == MANAGER_SYSTEM ? SYSTEM_GENERATOR_PATH : USER_GENERATOR_PATH; + if (!(d = opendir(generator_path))) { + + if (errno == ENOENT) + return; + + log_error("Failed to enumerate generator directory: %m"); + return; + } + + if (!m->generator_unit_path) { + const char *p; + char user_path[] = "/tmp/systemd-generator-XXXXXX"; + + if (m->running_as == MANAGER_SYSTEM && getpid() == 1) { + p = "/run/systemd/generator"; + + if (mkdir_p(p, 0755) < 0) { + log_error("Failed to create generator directory: %m"); + goto finish; + } + + } else { + if (!(p = mkdtemp(user_path))) { + log_error("Failed to create generator directory: %m"); + goto finish; + } + } + + if (!(m->generator_unit_path = strdup(p))) { + log_error("Failed to allocate generator unit path."); + goto finish; + } + } + + argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */ + argv[1] = m->generator_unit_path; + argv[2] = NULL; + + u = umask(0022); + execute_directory(generator_path, d, (char**) argv); + umask(u); + + if (rmdir(m->generator_unit_path) >= 0) { + /* Uh? we were able to remove this dir? I guess that + * means the directory was empty, hence let's shortcut + * this */ + + free(m->generator_unit_path); + m->generator_unit_path = NULL; + goto finish; + } + + if (!strv_find(m->lookup_paths.unit_path, m->generator_unit_path)) { + char **l; + + if (!(l = strv_append(m->lookup_paths.unit_path, m->generator_unit_path))) { + log_error("Failed to add generator directory to unit search path: %m"); + goto finish; + } + + strv_free(m->lookup_paths.unit_path); + m->lookup_paths.unit_path = l; + + log_debug("Added generator unit path %s to search path.", m->generator_unit_path); + } + +finish: + if (d) + closedir(d); +} + +void manager_undo_generators(Manager *m) { + assert(m); + + if (!m->generator_unit_path) + return; + + strv_remove(m->lookup_paths.unit_path, m->generator_unit_path); + rm_rf(m->generator_unit_path, false, true, false); + + free(m->generator_unit_path); + m->generator_unit_path = NULL; +} + +int manager_set_default_controllers(Manager *m, char **controllers) { + char **l; + + assert(m); + + if (!(l = strv_copy(controllers))) + return -ENOMEM; + + strv_free(m->default_controllers); + m->default_controllers = l; + + return 0; +} + +void manager_recheck_journal(Manager *m) { + Unit *u; + + assert(m); + + if (m->running_as != MANAGER_SYSTEM) + return; + + u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET); + if (u && SOCKET(u)->state != SOCKET_RUNNING) { + log_close_journal(); + return; + } + + u = manager_get_unit(m, SPECIAL_JOURNALD_SERVICE); + if (u && SERVICE(u)->state != SERVICE_RUNNING) { + log_close_journal(); + return; + } + + /* Hmm, OK, so the socket is fully up and the service is up + * too, then let's make use of the thing. */ + log_open(); +} + +void manager_set_show_status(Manager *m, bool b) { + assert(m); + + if (m->running_as != MANAGER_SYSTEM) + return; + + m->show_status = b; + + if (b) + touch("/run/systemd/show-status"); + else + unlink("/run/systemd/show-status"); +} + +bool manager_get_show_status(Manager *m) { + assert(m); + + if (m->running_as != MANAGER_SYSTEM) + return false; + + if (m->show_status) + return true; + + /* If Plymouth is running make sure we show the status, so + * that there's something nice to see when people press Esc */ + + return plymouth_running(); +} + +static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = { + [MANAGER_SYSTEM] = "system", + [MANAGER_USER] = "user" +}; + +DEFINE_STRING_TABLE_LOOKUP(manager_running_as, ManagerRunningAs); diff --git a/src/manager.h b/src/manager.h new file mode 100644 index 0000000..a9d08f0 --- /dev/null +++ b/src/manager.h @@ -0,0 +1,301 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foomanagerhfoo +#define foomanagerhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "fdset.h" + +/* Enforce upper limit how many names we allow */ +#define MANAGER_MAX_NAMES 131072 /* 128K */ + +typedef struct Manager Manager; +typedef enum WatchType WatchType; +typedef struct Watch Watch; + +typedef enum ManagerExitCode { + MANAGER_RUNNING, + MANAGER_EXIT, + MANAGER_RELOAD, + MANAGER_REEXECUTE, + MANAGER_REBOOT, + MANAGER_POWEROFF, + MANAGER_HALT, + MANAGER_KEXEC, + _MANAGER_EXIT_CODE_MAX, + _MANAGER_EXIT_CODE_INVALID = -1 +} ManagerExitCode; + +typedef enum ManagerRunningAs { + MANAGER_SYSTEM, + MANAGER_USER, + _MANAGER_RUNNING_AS_MAX, + _MANAGER_RUNNING_AS_INVALID = -1 +} ManagerRunningAs; + +enum WatchType { + WATCH_INVALID, + WATCH_SIGNAL, + WATCH_NOTIFY, + WATCH_FD, + WATCH_UNIT_TIMER, + WATCH_JOB_TIMER, + WATCH_MOUNT, + WATCH_SWAP, + WATCH_UDEV, + WATCH_DBUS_WATCH, + WATCH_DBUS_TIMEOUT +}; + +struct Watch { + int fd; + WatchType type; + union { + struct Unit *unit; + struct Job *job; + DBusWatch *bus_watch; + DBusTimeout *bus_timeout; + } data; + bool fd_is_dupped:1; + bool socket_accept:1; +}; + +#include "unit.h" +#include "job.h" +#include "hashmap.h" +#include "list.h" +#include "set.h" +#include "dbus.h" +#include "path-lookup.h" + +struct Manager { + /* Note that the set of units we know of is allowed to be + * inconsistent. However the subset of it that is loaded may + * not, and the list of jobs may neither. */ + + /* Active jobs and units */ + Hashmap *units; /* name string => Unit object n:1 */ + Hashmap *jobs; /* job id => Job object 1:1 */ + + /* To make it easy to iterate through the units of a specific + * type we maintain a per type linked list */ + LIST_HEAD(Unit, units_by_type[_UNIT_TYPE_MAX]); + + /* Units that need to be loaded */ + LIST_HEAD(Unit, load_queue); /* this is actually more a stack than a queue, but uh. */ + + /* Jobs that need to be run */ + LIST_HEAD(Job, run_queue); /* more a stack than a queue, too */ + + /* Units and jobs that have not yet been announced via + * D-Bus. When something about a job changes it is added here + * if it is not in there yet. This allows easy coalescing of + * D-Bus change signals. */ + LIST_HEAD(Unit, dbus_unit_queue); + LIST_HEAD(Job, dbus_job_queue); + + /* Units to remove */ + LIST_HEAD(Unit, cleanup_queue); + + /* Units to check when doing GC */ + LIST_HEAD(Unit, gc_queue); + + /* Jobs to be added */ + Hashmap *transaction_jobs; /* Unit object => Job object list 1:1 */ + JobDependency *transaction_anchor; + + Hashmap *watch_pids; /* pid => Unit object n:1 */ + + char *notify_socket; + + Watch notify_watch; + Watch signal_watch; + + int epoll_fd; + + unsigned n_snapshots; + + LookupPaths lookup_paths; + Set *unit_path_cache; + + char **environment; + char **default_controllers; + + dual_timestamp initrd_timestamp; + dual_timestamp startup_timestamp; + dual_timestamp finish_timestamp; + + char *generator_unit_path; + + /* Data specific to the device subsystem */ + struct udev* udev; + struct udev_monitor* udev_monitor; + Watch udev_watch; + Hashmap *devices_by_sysfs; + + /* Data specific to the mount subsystem */ + FILE *proc_self_mountinfo; + Watch mount_watch; + + /* Data specific to the swap filesystem */ + FILE *proc_swaps; + Hashmap *swaps_by_proc_swaps; + bool request_reload; + Watch swap_watch; + + /* Data specific to the D-Bus subsystem */ + DBusConnection *api_bus, *system_bus; + DBusServer *private_bus; + Set *bus_connections, *bus_connections_for_dispatch; + + DBusMessage *queued_message; /* This is used during reloading: + * before the reload we queue the + * reply message here, and + * afterwards we send it */ + DBusConnection *queued_message_connection; /* The connection to send the queued message on */ + + Hashmap *watch_bus; /* D-Bus names => Unit object n:1 */ + int32_t name_data_slot; + int32_t conn_data_slot; + int32_t subscribed_data_slot; + + uint32_t current_job_id; + uint32_t default_unit_job_id; + + /* Data specific to the Automount subsystem */ + int dev_autofs_fd; + + /* Data specific to the cgroup subsystem */ + Hashmap *cgroup_bondings; /* path string => CGroupBonding object 1:n */ + char *cgroup_hierarchy; + + usec_t gc_queue_timestamp; + int gc_marker; + unsigned n_in_gc_queue; + + /* Make sure the user cannot accidentally unmount our cgroup + * file system */ + int pin_cgroupfs_fd; + + /* Audit fd */ +#ifdef HAVE_AUDIT + int audit_fd; +#endif + + /* Flags */ + ManagerRunningAs running_as; + ManagerExitCode exit_code:5; + + bool dispatching_load_queue:1; + bool dispatching_run_queue:1; + bool dispatching_dbus_queue:1; + + bool taint_usr:1; + + bool show_status; + bool confirm_spawn; +#ifdef HAVE_SYSV_COMPAT + bool sysv_console; +#endif + bool mount_auto; + bool swap_auto; + + ExecOutput default_std_output, default_std_error; + + /* non-zero if we are reloading or reexecuting, */ + int n_reloading; + + unsigned n_installed_jobs; + unsigned n_failed_jobs; +}; + +int manager_new(ManagerRunningAs running_as, Manager **m); +void manager_free(Manager *m); + +int manager_enumerate(Manager *m); +int manager_coldplug(Manager *m); +int manager_startup(Manager *m, FILE *serialization, FDSet *fds); + +Job *manager_get_job(Manager *m, uint32_t id); +Unit *manager_get_unit(Manager *m, const char *name); + +int manager_get_unit_from_dbus_path(Manager *m, const char *s, Unit **_u); +int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j); + +int manager_load_unit_prepare(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret); +int manager_load_unit(Manager *m, const char *name, const char *path, DBusError *e, Unit **_ret); + +int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool force, DBusError *e, Job **_ret); +int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool force, DBusError *e, Job **_ret); + +void manager_dump_units(Manager *s, FILE *f, const char *prefix); +void manager_dump_jobs(Manager *s, FILE *f, const char *prefix); + +void manager_transaction_unlink_job(Manager *m, Job *j, bool delete_dependencies); + +void manager_clear_jobs(Manager *m); + +unsigned manager_dispatch_load_queue(Manager *m); +unsigned manager_dispatch_run_queue(Manager *m); +unsigned manager_dispatch_dbus_queue(Manager *m); + +int manager_set_default_controllers(Manager *m, char **controllers); + +int manager_loop(Manager *m); + +void manager_dispatch_bus_name_owner_changed(Manager *m, const char *name, const char* old_owner, const char *new_owner); +void manager_dispatch_bus_query_pid_done(Manager *m, const char *name, pid_t pid); + +int manager_open_serialization(Manager *m, FILE **_f); + +int manager_serialize(Manager *m, FILE *f, FDSet *fds); +int manager_deserialize(Manager *m, FILE *f, FDSet *fds); + +int manager_reload(Manager *m); + +bool manager_is_booting_or_shutting_down(Manager *m); + +void manager_reset_failed(Manager *m); + +void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success); +void manager_send_unit_plymouth(Manager *m, Unit *u); + +bool manager_unit_pending_inactive(Manager *m, const char *name); + +void manager_check_finished(Manager *m); + +void manager_run_generators(Manager *m); +void manager_undo_generators(Manager *m); + +void manager_recheck_journal(Manager *m); + +void manager_set_show_status(Manager *m, bool b); +bool manager_get_show_status(Manager *m); + +const char *manager_running_as_to_string(ManagerRunningAs i); +ManagerRunningAs manager_running_as_from_string(const char *s); + +#endif diff --git a/src/missing.h b/src/missing.h new file mode 100644 index 0000000..213ef2f --- /dev/null +++ b/src/missing.h @@ -0,0 +1,183 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foomissinghfoo +#define foomissinghfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +/* Missing glibc definitions to access certain kernel APIs */ + +#include +#include +#include +#include +#include + +#ifdef HAVE_AUDIT +#include +#endif + +#include "macro.h" + +#ifdef ARCH_MIPS +#include +#endif + +#ifndef RLIMIT_RTTIME +#define RLIMIT_RTTIME 15 +#endif + +#ifndef F_LINUX_SPECIFIC_BASE +#define F_LINUX_SPECIFIC_BASE 1024 +#endif + +#ifndef F_SETPIPE_SZ +#define F_SETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 7) +#endif + +#ifndef F_GETPIPE_SZ +#define F_GETPIPE_SZ (F_LINUX_SPECIFIC_BASE + 8) +#endif + +#ifndef IP_FREEBIND +#define IP_FREEBIND 15 +#endif + +#ifndef OOM_SCORE_ADJ_MIN +#define OOM_SCORE_ADJ_MIN (-1000) +#endif + +#ifndef OOM_SCORE_ADJ_MAX +#define OOM_SCORE_ADJ_MAX 1000 +#endif + +#ifndef AUDIT_SERVICE_START +#define AUDIT_SERVICE_START 1130 /* Service (daemon) start */ +#endif + +#ifndef AUDIT_SERVICE_STOP +#define AUDIT_SERVICE_STOP 1131 /* Service (daemon) stop */ +#endif + +#ifndef TIOCVHANGUP +#define TIOCVHANGUP 0x5437 +#endif + +#ifndef IP_TRANSPARENT +#define IP_TRANSPARENT 19 +#endif + +static inline int pivot_root(const char *new_root, const char *put_old) { + return syscall(SYS_pivot_root, new_root, put_old); +} + +#ifdef __x86_64__ +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 300 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 301 +# endif +#elif defined _MIPS_SIM +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 4336 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 4337 +# endif +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 6300 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 6301 +# endif +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 5295 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 5296 +# endif +# endif +#else +# ifndef __NR_fanotify_init +# define __NR_fanotify_init 338 +# endif +# ifndef __NR_fanotify_mark +# define __NR_fanotify_mark 339 +# endif +#endif + +static inline int fanotify_init(unsigned int flags, unsigned int event_f_flags) { + return syscall(__NR_fanotify_init, flags, event_f_flags); +} + +static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t mask, + int dfd, const char *pathname) { +#if defined _MIPS_SIM && _MIPS_SIM == _MIPS_SIM_ABI32 + union { + uint64_t _64; + uint32_t _32[2]; + } _mask; + _mask._64 = mask; + + return syscall(__NR_fanotify_mark, fanotify_fd, flags, + _mask._32[0], _mask._32[1], dfd, pathname); +#else + return syscall(__NR_fanotify_mark, fanotify_fd, flags, mask, dfd, pathname); +#endif +} + +#ifndef BTRFS_IOCTL_MAGIC +#define BTRFS_IOCTL_MAGIC 0x94 +#endif + +#ifndef BTRFS_PATH_NAME_MAX +#define BTRFS_PATH_NAME_MAX 4087 +#endif + +struct btrfs_ioctl_vol_args { + int64_t fd; + char name[BTRFS_PATH_NAME_MAX + 1]; +}; + +#ifndef BTRFS_IOC_DEFRAG +#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, struct btrfs_ioctl_vol_args) +#endif + +#ifndef BTRFS_SUPER_MAGIC +#define BTRFS_SUPER_MAGIC 0x9123683E +#endif + +#ifndef MS_MOVE +#define MS_MOVE 8192 +#endif + +#ifndef MS_PRIVATE +#define MS_PRIVATE (1 << 18) +#endif + +static inline pid_t gettid(void) { + return (pid_t) syscall(SYS_gettid); +} + +#endif diff --git a/src/modules-load.c b/src/modules-load.c new file mode 100644 index 0000000..043e909 --- /dev/null +++ b/src/modules-load.c @@ -0,0 +1,150 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "strv.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +static void systemd_kmod_log(void *data, int priority, const char *file, int line, + const char *fn, const char *format, va_list args) +{ + log_meta(priority, file, line, fn, format, args); +} +#pragma GCC diagnostic pop + +int main(int argc, char *argv[]) { + int r = EXIT_FAILURE; + char **files, **fn; + struct kmod_ctx *ctx; + const int probe_flags = KMOD_PROBE_APPLY_BLACKLIST|KMOD_PROBE_IGNORE_LOADED; + + if (argc > 1) { + log_error("This program takes no argument."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (!(ctx = kmod_new(NULL, NULL))) { + log_error("Failed to allocate memory for kmod."); + goto finish; + } + + kmod_load_resources(ctx); + + kmod_set_log_fn(ctx, systemd_kmod_log, NULL); + + if (conf_files_list(&files, ".conf", + "/run/modules-load.d", + "/etc/modules-load.d", + "/usr/local/lib/modules-load.d", + "/usr/lib/modules-load.d", + "/lib/modules-load.d", + NULL) < 0) { + log_error("Failed to enumerate modules-load.d files: %s", strerror(-r)); + goto finish; + } + + r = EXIT_SUCCESS; + + STRV_FOREACH(fn, files) { + FILE *f; + + f = fopen(*fn, "re"); + if (!f) { + if (errno == ENOENT) + continue; + + log_error("Failed to open %s: %m", *fn); + r = EXIT_FAILURE; + continue; + } + + log_debug("apply: %s\n", *fn); + for (;;) { + char line[LINE_MAX], *l; + struct kmod_list *itr, *modlist = NULL; + int err; + + if (!(fgets(line, sizeof(line), f))) + break; + + l = strstrip(line); + if (*l == '#' || *l == 0) + continue; + + err = kmod_module_new_from_lookup(ctx, l, &modlist); + if (err < 0) { + log_error("Failed to lookup alias '%s'", l); + r = EXIT_FAILURE; + continue; + } + + kmod_list_foreach(itr, modlist) { + struct kmod_module *mod = kmod_module_get_module(itr); + err = kmod_module_probe_insert_module(mod, probe_flags, + NULL, NULL, NULL, NULL); + + if (err == 0) + log_info("Inserted module '%s'", kmod_module_get_name(mod)); + else if (err == KMOD_PROBE_APPLY_BLACKLIST) + log_info("Module '%s' is blacklisted", kmod_module_get_name(mod)); + else { + log_error("Failed to insert '%s': %s", kmod_module_get_name(mod), + strerror(-err)); + r = EXIT_FAILURE; + } + + kmod_module_unref(mod); + } + + kmod_module_unref_list(modlist); + } + + if (ferror(f)) { + log_error("Failed to read from file: %m"); + r = EXIT_FAILURE; + } + + fclose(f); + } + +finish: + strv_free(files); + kmod_unref(ctx); + + return r; +} diff --git a/src/mount-setup.c b/src/mount-setup.c new file mode 100644 index 0000000..7c14ea8 --- /dev/null +++ b/src/mount-setup.c @@ -0,0 +1,420 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mount-setup.h" +#include "log.h" +#include "macro.h" +#include "util.h" +#include "label.h" +#include "set.h" +#include "strv.h" + +#ifndef TTY_GID +#define TTY_GID 5 +#endif + +typedef struct MountPoint { + const char *what; + const char *where; + const char *type; + const char *options; + unsigned long flags; + bool fatal; +} MountPoint; + +/* The first three entries we might need before SELinux is up. The + * other ones we can delay until SELinux is loaded. */ +#define N_EARLY_MOUNT 3 + +static const MountPoint mount_table[] = { + { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, + { "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, + { "devtmpfs", "/dev", "devtmpfs", "mode=755", MS_NOSUID, true }, + { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV, true }, + { "devpts", "/dev/pts", "devpts", "mode=620,gid=" STRINGIFY(TTY_GID), MS_NOSUID|MS_NOEXEC, false }, + { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV, true }, + { "tmpfs", "/sys/fs/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, false }, + { "cgroup", "/sys/fs/cgroup/systemd", "cgroup", "none,name=systemd", MS_NOSUID|MS_NOEXEC|MS_NODEV, false }, +}; + +/* These are API file systems that might be mounted by other software, + * we just list them here so that we know that we should ignore them */ + +static const char * const ignore_paths[] = { + "/sys/fs/selinux", + "/selinux", + "/proc/bus/usb" +}; + +bool mount_point_is_api(const char *path) { + unsigned i; + + /* Checks if this mount point is considered "API", and hence + * should be ignored */ + + for (i = 0; i < ELEMENTSOF(mount_table); i ++) + if (path_equal(path, mount_table[i].where)) + return true; + + return path_startswith(path, "/sys/fs/cgroup/"); +} + +bool mount_point_ignore(const char *path) { + unsigned i; + + for (i = 0; i < ELEMENTSOF(ignore_paths); i++) + if (path_equal(path, ignore_paths[i])) + return true; + + return false; +} + +static int mount_one(const MountPoint *p, bool relabel) { + int r; + + assert(p); + + /* Relabel first, just in case */ + if (relabel) + label_fix(p->where, true); + + if ((r = path_is_mount_point(p->where, true)) < 0) + return r; + + if (r > 0) + return 0; + + /* The access mode here doesn't really matter too much, since + * the mounted file system will take precedence anyway. */ + mkdir_p(p->where, 0755); + + log_debug("Mounting %s to %s of type %s with options %s.", + p->what, + p->where, + p->type, + strna(p->options)); + + if (mount(p->what, + p->where, + p->type, + p->flags, + p->options) < 0) { + log_error("Failed to mount %s: %s", p->where, strerror(errno)); + return p->fatal ? -errno : 0; + } + + /* Relabel again, since we now mounted something fresh here */ + if (relabel) + label_fix(p->where, false); + + return 1; +} + +int mount_setup_early(void) { + unsigned i; + int r = 0; + + assert_cc(N_EARLY_MOUNT <= ELEMENTSOF(mount_table)); + + /* Do a minimal mount of /proc and friends to enable the most + * basic stuff, such as SELinux */ + for (i = 0; i < N_EARLY_MOUNT; i ++) { + int j; + + j = mount_one(mount_table + i, false); + if (r == 0) + r = j; + } + + return r; +} + +int mount_cgroup_controllers(char ***join_controllers) { + int r; + FILE *f; + char buf[LINE_MAX]; + Set *controllers; + + /* Mount all available cgroup controllers that are built into the kernel. */ + + f = fopen("/proc/cgroups", "re"); + if (!f) { + log_error("Failed to enumerate cgroup controllers: %m"); + return 0; + } + + controllers = set_new(string_hash_func, string_compare_func); + if (!controllers) { + r = -ENOMEM; + log_error("Failed to allocate controller set."); + goto finish; + } + + /* Ignore the header line */ + (void) fgets(buf, sizeof(buf), f); + + for (;;) { + char *controller; + int enabled = 0; + + if (fscanf(f, "%ms %*i %*i %i", &controller, &enabled) != 2) { + + if (feof(f)) + break; + + log_error("Failed to parse /proc/cgroups."); + r = -EIO; + goto finish; + } + + if (!enabled) { + free(controller); + continue; + } + + r = set_put(controllers, controller); + if (r < 0) { + log_error("Failed to add controller to set."); + free(controller); + goto finish; + } + } + + for (;;) { + MountPoint p; + char *controller, *where, *options; + char ***k = NULL; + + controller = set_steal_first(controllers); + if (!controller) + break; + + if (join_controllers) + for (k = join_controllers; *k; k++) + if (strv_find(*k, controller)) + break; + + if (k && *k) { + char **i, **j; + + for (i = *k, j = *k; *i; i++) { + + if (!streq(*i, controller)) { + char *t; + + t = set_remove(controllers, *i); + if (!t) { + free(*i); + continue; + } + free(t); + } + + *(j++) = *i; + } + + *j = NULL; + + options = strv_join(*k, ","); + if (!options) { + log_error("Failed to join options"); + free(controller); + r = -ENOMEM; + goto finish; + } + + } else { + options = controller; + controller = NULL; + } + + where = strappend("/sys/fs/cgroup/", options); + if (!where) { + log_error("Failed to build path"); + free(options); + r = -ENOMEM; + goto finish; + } + + zero(p); + p.what = "cgroup"; + p.where = where; + p.type = "cgroup"; + p.options = options; + p.flags = MS_NOSUID|MS_NOEXEC|MS_NODEV; + p.fatal = false; + + r = mount_one(&p, true); + free(controller); + free(where); + + if (r < 0) { + free(options); + goto finish; + } + + if (r > 0 && k && *k) { + char **i; + + for (i = *k; *i; i++) { + char *t; + + t = strappend("/sys/fs/cgroup/", *i); + if (!t) { + log_error("Failed to build path"); + r = -ENOMEM; + free(options); + goto finish; + } + + r = symlink(options, t); + free(t); + + if (r < 0 && errno != EEXIST) { + log_error("Failed to create symlink: %m"); + r = -errno; + free(options); + goto finish; + } + } + } + + free(options); + } + + r = 0; + +finish: + set_free_free(controllers); + + fclose(f); + + return r; +} + +static int symlink_and_label(const char *old_path, const char *new_path) { + int r; + + assert(old_path); + assert(new_path); + + if ((r = label_symlinkfile_set(new_path)) < 0) + return r; + + if (symlink(old_path, new_path) < 0) + r = -errno; + + label_file_clear(); + + return r; +} + +static int nftw_cb( + const char *fpath, + const struct stat *sb, + int tflag, + struct FTW *ftwbuf) { + + /* No need to label /dev twice in a row... */ + if (_unlikely_(ftwbuf->level == 0)) + return FTW_CONTINUE; + + label_fix(fpath, true); + + /* /run/initramfs is static data and big, no need to + * dynamically relabel its contents at boot... */ + if (_unlikely_(ftwbuf->level == 1 && + tflag == FTW_D && + streq(fpath, "/run/initramfs"))) + return FTW_SKIP_SUBTREE; + + return FTW_CONTINUE; +}; + +int mount_setup(bool loaded_policy) { + + static const char symlinks[] = + "/proc/kcore\0" "/dev/core\0" + "/proc/self/fd\0" "/dev/fd\0" + "/proc/self/fd/0\0" "/dev/stdin\0" + "/proc/self/fd/1\0" "/dev/stdout\0" + "/proc/self/fd/2\0" "/dev/stderr\0"; + + static const char relabel[] = + "/run/initramfs/root-fsck\0" + "/run/initramfs/shutdown\0"; + + int r; + unsigned i; + const char *j, *k; + + for (i = 0; i < ELEMENTSOF(mount_table); i ++) { + r = mount_one(mount_table + i, true); + + if (r < 0) + return r; + } + + /* Nodes in devtmpfs and /run need to be manually updated for + * the appropriate labels, after mounting. The other virtual + * API file systems like /sys and /proc do not need that, they + * use the same label for all their files. */ + if (loaded_policy) { + usec_t before_relabel, after_relabel; + char timespan[FORMAT_TIMESPAN_MAX]; + + before_relabel = now(CLOCK_MONOTONIC); + + nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL); + nftw("/run", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL); + + /* Explicitly relabel these */ + NULSTR_FOREACH(j, relabel) + label_fix(j, true); + + after_relabel = now(CLOCK_MONOTONIC); + + log_info("Relabelled /dev and /run in %s.", + format_timespan(timespan, sizeof(timespan), after_relabel - before_relabel)); + } + + /* Create a few default symlinks, which are normally created + * by udevd, but some scripts might need them before we start + * udevd. */ + NULSTR_FOREACH_PAIR(j, k, symlinks) + symlink_and_label(j, k); + + /* Create a few directories we always want around */ + label_mkdir("/run/systemd", 0755); + label_mkdir("/run/systemd/system", 0755); + + return 0; +} diff --git a/src/mount-setup.h b/src/mount-setup.h new file mode 100644 index 0000000..c1a27ba --- /dev/null +++ b/src/mount-setup.h @@ -0,0 +1,36 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foomountsetuphfoo +#define foomountsetuphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +int mount_setup_early(void); + +int mount_setup(bool loaded_policy); + +int mount_cgroup_controllers(char ***join_controllers); + +bool mount_point_is_api(const char *path); +bool mount_point_ignore(const char *path); + +#endif diff --git a/src/mount.c b/src/mount.c new file mode 100644 index 0000000..0ae964b --- /dev/null +++ b/src/mount.c @@ -0,0 +1,1929 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "unit.h" +#include "mount.h" +#include "load-fragment.h" +#include "load-dropin.h" +#include "log.h" +#include "strv.h" +#include "mount-setup.h" +#include "unit-name.h" +#include "dbus-mount.h" +#include "special.h" +#include "bus-errors.h" +#include "exit-status.h" +#include "def.h" + +static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = { + [MOUNT_DEAD] = UNIT_INACTIVE, + [MOUNT_MOUNTING] = UNIT_ACTIVATING, + [MOUNT_MOUNTING_DONE] = UNIT_ACTIVE, + [MOUNT_MOUNTED] = UNIT_ACTIVE, + [MOUNT_REMOUNTING] = UNIT_RELOADING, + [MOUNT_UNMOUNTING] = UNIT_DEACTIVATING, + [MOUNT_MOUNTING_SIGTERM] = UNIT_DEACTIVATING, + [MOUNT_MOUNTING_SIGKILL] = UNIT_DEACTIVATING, + [MOUNT_REMOUNTING_SIGTERM] = UNIT_RELOADING, + [MOUNT_REMOUNTING_SIGKILL] = UNIT_RELOADING, + [MOUNT_UNMOUNTING_SIGTERM] = UNIT_DEACTIVATING, + [MOUNT_UNMOUNTING_SIGKILL] = UNIT_DEACTIVATING, + [MOUNT_FAILED] = UNIT_FAILED +}; + +static void mount_init(Unit *u) { + Mount *m = MOUNT(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + m->timeout_usec = DEFAULT_TIMEOUT_USEC; + m->directory_mode = 0755; + + exec_context_init(&m->exec_context); + + /* The stdio/kmsg bridge socket is on /, in order to avoid a + * dep loop, don't use kmsg logging for -.mount */ + if (!unit_has_name(u, "-.mount")) { + m->exec_context.std_output = u->manager->default_std_output; + m->exec_context.std_error = u->manager->default_std_error; + } + + /* We need to make sure that /bin/mount is always called in + * the same process group as us, so that the autofs kernel + * side doesn't send us another mount request while we are + * already trying to comply its last one. */ + m->exec_context.same_pgrp = true; + + m->timer_watch.type = WATCH_INVALID; + + m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID; + + UNIT(m)->ignore_on_isolate = true; +} + +static void mount_unwatch_control_pid(Mount *m) { + assert(m); + + if (m->control_pid <= 0) + return; + + unit_unwatch_pid(UNIT(m), m->control_pid); + m->control_pid = 0; +} + +static void mount_parameters_done(MountParameters *p) { + assert(p); + + free(p->what); + free(p->options); + free(p->fstype); + + p->what = p->options = p->fstype = NULL; +} + +static void mount_done(Unit *u) { + Mount *m = MOUNT(u); + + assert(m); + + free(m->where); + m->where = NULL; + + mount_parameters_done(&m->parameters_etc_fstab); + mount_parameters_done(&m->parameters_proc_self_mountinfo); + mount_parameters_done(&m->parameters_fragment); + + exec_context_done(&m->exec_context); + exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX); + m->control_command = NULL; + + mount_unwatch_control_pid(m); + + unit_unwatch_timer(u, &m->timer_watch); +} + +static MountParameters* get_mount_parameters_configured(Mount *m) { + assert(m); + + if (m->from_fragment) + return &m->parameters_fragment; + else if (m->from_etc_fstab) + return &m->parameters_etc_fstab; + + return NULL; +} + +static MountParameters* get_mount_parameters(Mount *m) { + assert(m); + + if (m->from_proc_self_mountinfo) + return &m->parameters_proc_self_mountinfo; + + return get_mount_parameters_configured(m); +} + +static int mount_add_mount_links(Mount *m) { + Unit *other; + int r; + MountParameters *pm; + + assert(m); + + pm = get_mount_parameters_configured(m); + + /* Adds in links to other mount points that might lie below or + * above us in the hierarchy */ + + LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_MOUNT]) { + Mount *n = MOUNT(other); + MountParameters *pn; + + if (n == m) + continue; + + if (UNIT(n)->load_state != UNIT_LOADED) + continue; + + pn = get_mount_parameters_configured(n); + + if (path_startswith(m->where, n->where)) { + + if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0) + return r; + + if (pn) + if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0) + return r; + + } else if (path_startswith(n->where, m->where)) { + + if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0) + return r; + + if (pm) + if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0) + return r; + + } else if (pm && path_startswith(pm->what, n->where)) { + + if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0) + return r; + + if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0) + return r; + + } else if (pn && path_startswith(pn->what, m->where)) { + + if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0) + return r; + + if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0) + return r; + } + } + + return 0; +} + +static int mount_add_swap_links(Mount *m) { + Unit *other; + int r; + + assert(m); + + LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SWAP]) + if ((r = swap_add_one_mount_link(SWAP(other), m)) < 0) + return r; + + return 0; +} + +static int mount_add_path_links(Mount *m) { + Unit *other; + int r; + + assert(m); + + LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_PATH]) + if ((r = path_add_one_mount_link(PATH(other), m)) < 0) + return r; + + return 0; +} + +static int mount_add_automount_links(Mount *m) { + Unit *other; + int r; + + assert(m); + + LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_AUTOMOUNT]) + if ((r = automount_add_one_mount_link(AUTOMOUNT(other), m)) < 0) + return r; + + return 0; +} + +static int mount_add_socket_links(Mount *m) { + Unit *other; + int r; + + assert(m); + + LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SOCKET]) + if ((r = socket_add_one_mount_link(SOCKET(other), m)) < 0) + return r; + + return 0; +} + +static char* mount_test_option(const char *haystack, const char *needle) { + struct mntent me; + + assert(needle); + + /* Like glibc's hasmntopt(), but works on a string, not a + * struct mntent */ + + if (!haystack) + return false; + + zero(me); + me.mnt_opts = (char*) haystack; + + return hasmntopt(&me, needle); +} + +static bool mount_is_network(MountParameters *p) { + assert(p); + + if (mount_test_option(p->options, "_netdev")) + return true; + + if (p->fstype && fstype_is_network(p->fstype)) + return true; + + return false; +} + +static bool mount_is_bind(MountParameters *p) { + assert(p); + + if (mount_test_option(p->options, "bind")) + return true; + + if (p->fstype && streq(p->fstype, "bind")) + return true; + + return false; +} + +static bool needs_quota(MountParameters *p) { + assert(p); + + if (mount_is_network(p)) + return false; + + if (mount_is_bind(p)) + return false; + + return mount_test_option(p->options, "usrquota") || + mount_test_option(p->options, "grpquota") || + mount_test_option(p->options, "quota") || + mount_test_option(p->options, "usrjquota") || + mount_test_option(p->options, "grpjquota"); +} + +static int mount_add_fstab_links(Mount *m) { + const char *target, *after, *tu_wants = NULL; + MountParameters *p; + Unit *tu; + int r; + bool noauto, nofail, handle, automount; + + assert(m); + + if (UNIT(m)->manager->running_as != MANAGER_SYSTEM) + return 0; + + if (!(p = get_mount_parameters_configured(m))) + return 0; + + if (p != &m->parameters_etc_fstab) + return 0; + + noauto = !!mount_test_option(p->options, "noauto"); + nofail = !!mount_test_option(p->options, "nofail"); + automount = + mount_test_option(p->options, "comment=systemd.automount") || + mount_test_option(p->options, "x-systemd-automount"); + handle = + automount || + mount_test_option(p->options, "comment=systemd.mount") || + mount_test_option(p->options, "x-systemd-mount") || + UNIT(m)->manager->mount_auto; + + if (mount_is_network(p)) { + target = SPECIAL_REMOTE_FS_TARGET; + after = tu_wants = SPECIAL_REMOTE_FS_PRE_TARGET; + } else { + target = SPECIAL_LOCAL_FS_TARGET; + after = SPECIAL_LOCAL_FS_PRE_TARGET; + } + + r = manager_load_unit(UNIT(m)->manager, target, NULL, NULL, &tu); + if (r < 0) + return r; + + if (tu_wants) { + r = unit_add_dependency_by_name(tu, UNIT_WANTS, tu_wants, NULL, true); + if (r < 0) + return r; + } + + if (after) { + r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true); + if (r < 0) + return r; + } + + if (automount) { + Unit *am; + + if ((r = unit_load_related_unit(UNIT(m), ".automount", &am)) < 0) + return r; + + /* If auto is configured as well also pull in the + * mount right-away, but don't rely on it. */ + if (!noauto) /* automount + auto */ + if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(m), true)) < 0) + return r; + + /* Install automount unit */ + if (!nofail) /* automount + fail */ + return unit_add_two_dependencies(tu, UNIT_AFTER, UNIT_REQUIRES, am, true); + else /* automount + nofail */ + return unit_add_two_dependencies(tu, UNIT_AFTER, UNIT_WANTS, am, true); + + } else if (handle && !noauto) { + + /* Automatically add mount points that aren't natively + * configured to local-fs.target */ + + if (!nofail) /* auto + fail */ + return unit_add_two_dependencies(tu, UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true); + else /* auto + nofail */ + return unit_add_dependency(tu, UNIT_WANTS, UNIT(m), true); + } + + return 0; +} + +static int mount_add_device_links(Mount *m) { + MountParameters *p; + int r; + + assert(m); + + if (!(p = get_mount_parameters_configured(m))) + return 0; + + if (!p->what) + return 0; + + if (!mount_is_bind(p) && + !path_equal(m->where, "/") && + p == &m->parameters_etc_fstab) { + bool nofail, noauto; + + noauto = !!mount_test_option(p->options, "noauto"); + nofail = !!mount_test_option(p->options, "nofail"); + + if ((r = unit_add_node_link(UNIT(m), p->what, + !noauto && nofail && + UNIT(m)->manager->running_as == MANAGER_SYSTEM)) < 0) + return r; + } + + if (p->passno > 0 && + !mount_is_bind(p) && + UNIT(m)->manager->running_as == MANAGER_SYSTEM && + !path_equal(m->where, "/")) { + char *name; + Unit *fsck; + /* Let's add in the fsck service */ + + /* aka SPECIAL_FSCK_SERVICE */ + if (!(name = unit_name_from_path_instance("fsck", p->what, ".service"))) + return -ENOMEM; + + if ((r = manager_load_unit_prepare(UNIT(m)->manager, name, NULL, NULL, &fsck)) < 0) { + log_warning("Failed to prepare unit %s: %s", name, strerror(-r)); + free(name); + return r; + } + + free(name); + + SERVICE(fsck)->fsck_passno = p->passno; + + if ((r = unit_add_two_dependencies(UNIT(m), UNIT_AFTER, UNIT_REQUIRES, fsck, true)) < 0) + return r; + } + + return 0; +} + +static int mount_add_default_dependencies(Mount *m) { + int r; + MountParameters *p; + + assert(m); + + if (UNIT(m)->manager->running_as != MANAGER_SYSTEM) + return 0; + + p = get_mount_parameters_configured(m); + if (p && needs_quota(p)) { + if ((r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true)) < 0 || + (r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true)) < 0) + return r; + } + + if (!path_equal(m->where, "/")) + if ((r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0) + return r; + + return 0; +} + +static int mount_fix_timeouts(Mount *m) { + MountParameters *p; + const char *timeout = NULL; + Unit *other; + Iterator i; + usec_t u; + char *t; + int r; + + assert(m); + + if (!(p = get_mount_parameters_configured(m))) + return 0; + + /* Allow configuration how long we wait for a device that + * backs a mount point to show up. This is useful to support + * endless device timeouts for devices that show up only after + * user input, like crypto devices. */ + + if ((timeout = mount_test_option(p->options, "comment=systemd.device-timeout"))) + timeout += 31; + else if ((timeout = mount_test_option(p->options, "x-systemd-device-timeout"))) + timeout += 25; + else + return 0; + + t = strndup(timeout, strcspn(timeout, ",;" WHITESPACE)); + if (!t) + return -ENOMEM; + + r = parse_usec(t, &u); + free(t); + + if (r < 0) { + log_warning("Failed to parse timeout for %s, ignoring: %s", m->where, timeout); + return r; + } + + SET_FOREACH(other, UNIT(m)->dependencies[UNIT_AFTER], i) { + if (other->type != UNIT_DEVICE) + continue; + + other->job_timeout = u; + } + + return 0; +} + +static int mount_verify(Mount *m) { + bool b; + char *e; + assert(m); + + if (UNIT(m)->load_state != UNIT_LOADED) + return 0; + + if (!m->from_etc_fstab && !m->from_fragment && !m->from_proc_self_mountinfo) + return -ENOENT; + + if (!(e = unit_name_from_path(m->where, ".mount"))) + return -ENOMEM; + + b = unit_has_name(UNIT(m), e); + free(e); + + if (!b) { + log_error("%s's Where setting doesn't match unit name. Refusing.", UNIT(m)->id); + return -EINVAL; + } + + if (mount_point_is_api(m->where) || mount_point_ignore(m->where)) { + log_error("Cannot create mount unit for API file system %s. Refusing.", m->where); + return -EINVAL; + } + + if (UNIT(m)->fragment_path && !m->parameters_fragment.what) { + log_error("%s's What setting is missing. Refusing.", UNIT(m)->id); + return -EBADMSG; + } + + if (m->exec_context.pam_name && m->exec_context.kill_mode != KILL_CONTROL_GROUP) { + log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(m)->id); + return -EINVAL; + } + + return 0; +} + +static int mount_load(Unit *u) { + Mount *m = MOUNT(u); + int r; + + assert(u); + assert(u->load_state == UNIT_STUB); + + if ((r = unit_load_fragment_and_dropin_optional(u)) < 0) + return r; + + /* This is a new unit? Then let's add in some extras */ + if (u->load_state == UNIT_LOADED) { + if ((r = unit_add_exec_dependencies(u, &m->exec_context)) < 0) + return r; + + if (UNIT(m)->fragment_path) + m->from_fragment = true; + else if (m->from_etc_fstab) + /* We always add several default dependencies to fstab mounts, + * but we do not want the implicit complementing of Wants= with After= + * in the target unit that this mount unit will be hooked into. */ + UNIT(m)->default_dependencies = false; + + if (!m->where) + if (!(m->where = unit_name_to_path(u->id))) + return -ENOMEM; + + path_kill_slashes(m->where); + + if (!UNIT(m)->description) + if ((r = unit_set_description(u, m->where)) < 0) + return r; + + if ((r = mount_add_device_links(m)) < 0) + return r; + + if ((r = mount_add_mount_links(m)) < 0) + return r; + + if ((r = mount_add_socket_links(m)) < 0) + return r; + + if ((r = mount_add_swap_links(m)) < 0) + return r; + + if ((r = mount_add_path_links(m)) < 0) + return r; + + if ((r = mount_add_automount_links(m)) < 0) + return r; + + if ((r = mount_add_fstab_links(m)) < 0) + return r; + + if (UNIT(m)->default_dependencies || m->from_etc_fstab) + if ((r = mount_add_default_dependencies(m)) < 0) + return r; + + if ((r = unit_add_default_cgroups(u)) < 0) + return r; + + mount_fix_timeouts(m); + } + + return mount_verify(m); +} + +static int mount_notify_automount(Mount *m, int status) { + Unit *p; + int r; + Iterator i; + + assert(m); + + SET_FOREACH(p, UNIT(m)->dependencies[UNIT_TRIGGERED_BY], i) + if (p->type == UNIT_AUTOMOUNT) { + r = automount_send_ready(AUTOMOUNT(p), status); + if (r < 0) + return r; + } + + return 0; +} + +static void mount_set_state(Mount *m, MountState state) { + MountState old_state; + assert(m); + + old_state = m->state; + m->state = state; + + if (state != MOUNT_MOUNTING && + state != MOUNT_MOUNTING_DONE && + state != MOUNT_REMOUNTING && + state != MOUNT_UNMOUNTING && + state != MOUNT_MOUNTING_SIGTERM && + state != MOUNT_MOUNTING_SIGKILL && + state != MOUNT_UNMOUNTING_SIGTERM && + state != MOUNT_UNMOUNTING_SIGKILL && + state != MOUNT_REMOUNTING_SIGTERM && + state != MOUNT_REMOUNTING_SIGKILL) { + unit_unwatch_timer(UNIT(m), &m->timer_watch); + mount_unwatch_control_pid(m); + m->control_command = NULL; + m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID; + } + + if (state == MOUNT_MOUNTED || + state == MOUNT_REMOUNTING) + mount_notify_automount(m, 0); + else if (state == MOUNT_DEAD || + state == MOUNT_UNMOUNTING || + state == MOUNT_MOUNTING_SIGTERM || + state == MOUNT_MOUNTING_SIGKILL || + state == MOUNT_REMOUNTING_SIGTERM || + state == MOUNT_REMOUNTING_SIGKILL || + state == MOUNT_UNMOUNTING_SIGTERM || + state == MOUNT_UNMOUNTING_SIGKILL || + state == MOUNT_FAILED) + mount_notify_automount(m, -ENODEV); + + if (state != old_state) + log_debug("%s changed %s -> %s", + UNIT(m)->id, + mount_state_to_string(old_state), + mount_state_to_string(state)); + + unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS); + m->reload_result = MOUNT_SUCCESS; +} + +static int mount_coldplug(Unit *u) { + Mount *m = MOUNT(u); + MountState new_state = MOUNT_DEAD; + int r; + + assert(m); + assert(m->state == MOUNT_DEAD); + + if (m->deserialized_state != m->state) + new_state = m->deserialized_state; + else if (m->from_proc_self_mountinfo) + new_state = MOUNT_MOUNTED; + + if (new_state != m->state) { + + if (new_state == MOUNT_MOUNTING || + new_state == MOUNT_MOUNTING_DONE || + new_state == MOUNT_REMOUNTING || + new_state == MOUNT_UNMOUNTING || + new_state == MOUNT_MOUNTING_SIGTERM || + new_state == MOUNT_MOUNTING_SIGKILL || + new_state == MOUNT_UNMOUNTING_SIGTERM || + new_state == MOUNT_UNMOUNTING_SIGKILL || + new_state == MOUNT_REMOUNTING_SIGTERM || + new_state == MOUNT_REMOUNTING_SIGKILL) { + + if (m->control_pid <= 0) + return -EBADMSG; + + if ((r = unit_watch_pid(UNIT(m), m->control_pid)) < 0) + return r; + + if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 0) + return r; + } + + mount_set_state(m, new_state); + } + + return 0; +} + +static void mount_dump(Unit *u, FILE *f, const char *prefix) { + Mount *m = MOUNT(u); + MountParameters *p; + + assert(m); + assert(f); + + p = get_mount_parameters(m); + + fprintf(f, + "%sMount State: %s\n" + "%sResult: %s\n" + "%sWhere: %s\n" + "%sWhat: %s\n" + "%sFile System Type: %s\n" + "%sOptions: %s\n" + "%sFrom /etc/fstab: %s\n" + "%sFrom /proc/self/mountinfo: %s\n" + "%sFrom fragment: %s\n" + "%sDirectoryMode: %04o\n", + prefix, mount_state_to_string(m->state), + prefix, mount_result_to_string(m->result), + prefix, m->where, + prefix, strna(p->what), + prefix, strna(p->fstype), + prefix, strna(p->options), + prefix, yes_no(m->from_etc_fstab), + prefix, yes_no(m->from_proc_self_mountinfo), + prefix, yes_no(m->from_fragment), + prefix, m->directory_mode); + + if (m->control_pid > 0) + fprintf(f, + "%sControl PID: %lu\n", + prefix, (unsigned long) m->control_pid); + + exec_context_dump(&m->exec_context, f, prefix); +} + +static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { + pid_t pid; + int r; + + assert(m); + assert(c); + assert(_pid); + + if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 0) + goto fail; + + if ((r = exec_spawn(c, + NULL, + &m->exec_context, + NULL, 0, + UNIT(m)->manager->environment, + true, + true, + true, + UNIT(m)->manager->confirm_spawn, + UNIT(m)->cgroup_bondings, + UNIT(m)->cgroup_attributes, + &pid)) < 0) + goto fail; + + if ((r = unit_watch_pid(UNIT(m), pid)) < 0) + /* FIXME: we need to do something here */ + goto fail; + + *_pid = pid; + + return 0; + +fail: + unit_unwatch_timer(UNIT(m), &m->timer_watch); + + return r; +} + +static void mount_enter_dead(Mount *m, MountResult f) { + assert(m); + + if (f != MOUNT_SUCCESS) + m->result = f; + + mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD); +} + +static void mount_enter_mounted(Mount *m, MountResult f) { + assert(m); + + if (f != MOUNT_SUCCESS) + m->result = f; + + mount_set_state(m, MOUNT_MOUNTED); +} + +static void mount_enter_signal(Mount *m, MountState state, MountResult f) { + int r; + Set *pid_set = NULL; + bool wait_for_exit = false; + + assert(m); + + if (f != MOUNT_SUCCESS) + m->result = f; + + if (m->exec_context.kill_mode != KILL_NONE) { + int sig = (state == MOUNT_MOUNTING_SIGTERM || + state == MOUNT_UNMOUNTING_SIGTERM || + state == MOUNT_REMOUNTING_SIGTERM) ? m->exec_context.kill_signal : SIGKILL; + + if (m->control_pid > 0) { + if (kill_and_sigcont(m->control_pid, sig) < 0 && errno != ESRCH) + + log_warning("Failed to kill control process %li: %m", (long) m->control_pid); + else + wait_for_exit = true; + } + + if (m->exec_context.kill_mode == KILL_CONTROL_GROUP) { + + if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) { + r = -ENOMEM; + goto fail; + } + + /* Exclude the control pid from being killed via the cgroup */ + if (m->control_pid > 0) + if ((r = set_put(pid_set, LONG_TO_PTR(m->control_pid))) < 0) + goto fail; + + if ((r = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, sig, true, pid_set)) < 0) { + if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) + log_warning("Failed to kill control group: %s", strerror(-r)); + } else if (r > 0) + wait_for_exit = true; + + set_free(pid_set); + pid_set = NULL; + } + } + + if (wait_for_exit) { + if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 0) + goto fail; + + mount_set_state(m, state); + } else if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL) + mount_enter_mounted(m, MOUNT_SUCCESS); + else + mount_enter_dead(m, MOUNT_SUCCESS); + + return; + +fail: + log_warning("%s failed to kill processes: %s", UNIT(m)->id, strerror(-r)); + + if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL) + mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES); + else + mount_enter_dead(m, MOUNT_FAILURE_RESOURCES); + + if (pid_set) + set_free(pid_set); +} + +static void mount_enter_unmounting(Mount *m) { + int r; + + assert(m); + + m->control_command_id = MOUNT_EXEC_UNMOUNT; + m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT; + + if ((r = exec_command_set( + m->control_command, + "/bin/umount", + m->where, + NULL)) < 0) + goto fail; + + mount_unwatch_control_pid(m); + + if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0) + goto fail; + + mount_set_state(m, MOUNT_UNMOUNTING); + + return; + +fail: + log_warning("%s failed to run 'umount' task: %s", UNIT(m)->id, strerror(-r)); + mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES); +} + +static void mount_enter_mounting(Mount *m) { + int r; + MountParameters *p; + + assert(m); + + m->control_command_id = MOUNT_EXEC_MOUNT; + m->control_command = m->exec_command + MOUNT_EXEC_MOUNT; + + mkdir_p(m->where, m->directory_mode); + + /* Create the source directory for bind-mounts if needed */ + p = get_mount_parameters_configured(m); + if (p && mount_is_bind(p)) + mkdir_p(p->what, m->directory_mode); + + if (m->from_fragment) + r = exec_command_set( + m->control_command, + "/bin/mount", + m->parameters_fragment.what, + m->where, + "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto", + m->parameters_fragment.options ? "-o" : NULL, m->parameters_fragment.options, + NULL); + else if (m->from_etc_fstab) + r = exec_command_set( + m->control_command, + "/bin/mount", + m->where, + NULL); + else + r = -ENOENT; + + if (r < 0) + goto fail; + + mount_unwatch_control_pid(m); + + if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0) + goto fail; + + mount_set_state(m, MOUNT_MOUNTING); + + return; + +fail: + log_warning("%s failed to run 'mount' task: %s", UNIT(m)->id, strerror(-r)); + mount_enter_dead(m, MOUNT_FAILURE_RESOURCES); +} + +static void mount_enter_mounting_done(Mount *m) { + assert(m); + + mount_set_state(m, MOUNT_MOUNTING_DONE); +} + +static void mount_enter_remounting(Mount *m) { + int r; + + assert(m); + + m->control_command_id = MOUNT_EXEC_REMOUNT; + m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT; + + if (m->from_fragment) { + char *buf = NULL; + const char *o; + + if (m->parameters_fragment.options) { + if (!(buf = strappend("remount,", m->parameters_fragment.options))) { + r = -ENOMEM; + goto fail; + } + + o = buf; + } else + o = "remount"; + + r = exec_command_set( + m->control_command, + "/bin/mount", + m->parameters_fragment.what, + m->where, + "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto", + "-o", o, + NULL); + + free(buf); + } else if (m->from_etc_fstab) + r = exec_command_set( + m->control_command, + "/bin/mount", + m->where, + "-o", "remount", + NULL); + else + r = -ENOENT; + + if (r < 0) + goto fail; + + mount_unwatch_control_pid(m); + + if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0) + goto fail; + + mount_set_state(m, MOUNT_REMOUNTING); + + return; + +fail: + log_warning("%s failed to run 'remount' task: %s", UNIT(m)->id, strerror(-r)); + m->reload_result = MOUNT_FAILURE_RESOURCES; + mount_enter_mounted(m, MOUNT_SUCCESS); +} + +static int mount_start(Unit *u) { + Mount *m = MOUNT(u); + + assert(m); + + /* We cannot fulfill this request right now, try again later + * please! */ + if (m->state == MOUNT_UNMOUNTING || + m->state == MOUNT_UNMOUNTING_SIGTERM || + m->state == MOUNT_UNMOUNTING_SIGKILL || + m->state == MOUNT_MOUNTING_SIGTERM || + m->state == MOUNT_MOUNTING_SIGKILL) + return -EAGAIN; + + /* Already on it! */ + if (m->state == MOUNT_MOUNTING) + return 0; + + assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED); + + m->result = MOUNT_SUCCESS; + m->reload_result = MOUNT_SUCCESS; + + mount_enter_mounting(m); + return 0; +} + +static int mount_stop(Unit *u) { + Mount *m = MOUNT(u); + + assert(m); + + /* Already on it */ + if (m->state == MOUNT_UNMOUNTING || + m->state == MOUNT_UNMOUNTING_SIGKILL || + m->state == MOUNT_UNMOUNTING_SIGTERM || + m->state == MOUNT_MOUNTING_SIGTERM || + m->state == MOUNT_MOUNTING_SIGKILL) + return 0; + + assert(m->state == MOUNT_MOUNTING || + m->state == MOUNT_MOUNTING_DONE || + m->state == MOUNT_MOUNTED || + m->state == MOUNT_REMOUNTING || + m->state == MOUNT_REMOUNTING_SIGTERM || + m->state == MOUNT_REMOUNTING_SIGKILL); + + mount_enter_unmounting(m); + return 0; +} + +static int mount_reload(Unit *u) { + Mount *m = MOUNT(u); + + assert(m); + + if (m->state == MOUNT_MOUNTING_DONE) + return -EAGAIN; + + assert(m->state == MOUNT_MOUNTED); + + mount_enter_remounting(m); + return 0; +} + +static int mount_serialize(Unit *u, FILE *f, FDSet *fds) { + Mount *m = MOUNT(u); + + assert(m); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", mount_state_to_string(m->state)); + unit_serialize_item(u, f, "result", mount_result_to_string(m->result)); + unit_serialize_item(u, f, "reload-result", mount_result_to_string(m->reload_result)); + + if (m->control_pid > 0) + unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) m->control_pid); + + if (m->control_command_id >= 0) + unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id)); + + return 0; +} + +static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Mount *m = MOUNT(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + MountState state; + + if ((state = mount_state_from_string(value)) < 0) + log_debug("Failed to parse state value %s", value); + else + m->deserialized_state = state; + } else if (streq(key, "result")) { + MountResult f; + + f = mount_result_from_string(value); + if (f < 0) + log_debug("Failed to parse result value %s", value); + else if (f != MOUNT_SUCCESS) + m->result = f; + + } else if (streq(key, "reload-result")) { + MountResult f; + + f = mount_result_from_string(value); + if (f < 0) + log_debug("Failed to parse reload result value %s", value); + else if (f != MOUNT_SUCCESS) + m->reload_result = f; + + } else if (streq(key, "control-pid")) { + pid_t pid; + + if (parse_pid(value, &pid) < 0) + log_debug("Failed to parse control-pid value %s", value); + else + m->control_pid = pid; + } else if (streq(key, "control-command")) { + MountExecCommand id; + + if ((id = mount_exec_command_from_string(value)) < 0) + log_debug("Failed to parse exec-command value %s", value); + else { + m->control_command_id = id; + m->control_command = m->exec_command + id; + } + + } else + log_debug("Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState mount_active_state(Unit *u) { + assert(u); + + return state_translation_table[MOUNT(u)->state]; +} + +static const char *mount_sub_state_to_string(Unit *u) { + assert(u); + + return mount_state_to_string(MOUNT(u)->state); +} + +static bool mount_check_gc(Unit *u) { + Mount *m = MOUNT(u); + + assert(m); + + return m->from_etc_fstab || m->from_proc_self_mountinfo; +} + +static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) { + Mount *m = MOUNT(u); + MountResult f; + + assert(m); + assert(pid >= 0); + + if (pid != m->control_pid) + return; + + m->control_pid = 0; + + if (is_clean_exit(code, status)) + f = MOUNT_SUCCESS; + else if (code == CLD_EXITED) + f = MOUNT_FAILURE_EXIT_CODE; + else if (code == CLD_KILLED) + f = MOUNT_FAILURE_SIGNAL; + else if (code == CLD_DUMPED) + f = MOUNT_FAILURE_CORE_DUMP; + else + assert_not_reached("Unknown code"); + + if (f != MOUNT_SUCCESS) + m->result = f; + + if (m->control_command) { + exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status); + + m->control_command = NULL; + m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID; + } + + log_full(f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE, + "%s mount process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status); + + /* Note that mount(8) returning and the kernel sending us a + * mount table change event might happen out-of-order. If an + * operation succeed we assume the kernel will follow soon too + * and already change into the resulting state. If it fails + * we check if the kernel still knows about the mount. and + * change state accordingly. */ + + switch (m->state) { + + case MOUNT_MOUNTING: + case MOUNT_MOUNTING_DONE: + case MOUNT_MOUNTING_SIGKILL: + case MOUNT_MOUNTING_SIGTERM: + + if (f == MOUNT_SUCCESS) + mount_enter_mounted(m, f); + else if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, f); + else + mount_enter_dead(m, f); + break; + + case MOUNT_REMOUNTING: + case MOUNT_REMOUNTING_SIGKILL: + case MOUNT_REMOUNTING_SIGTERM: + + m->reload_result = f; + if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, MOUNT_SUCCESS); + else + mount_enter_dead(m, MOUNT_SUCCESS); + + break; + + case MOUNT_UNMOUNTING: + case MOUNT_UNMOUNTING_SIGKILL: + case MOUNT_UNMOUNTING_SIGTERM: + + if (f == MOUNT_SUCCESS) + mount_enter_dead(m, f); + else if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, f); + else + mount_enter_dead(m, f); + break; + + default: + assert_not_reached("Uh, control process died at wrong time."); + } + + /* Notify clients about changed exit status */ + unit_add_to_dbus_queue(u); +} + +static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) { + Mount *m = MOUNT(u); + + assert(m); + assert(elapsed == 1); + assert(w == &m->timer_watch); + + switch (m->state) { + + case MOUNT_MOUNTING: + case MOUNT_MOUNTING_DONE: + log_warning("%s mounting timed out. Stopping.", u->id); + mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT); + break; + + case MOUNT_REMOUNTING: + log_warning("%s remounting timed out. Stopping.", u->id); + m->reload_result = MOUNT_FAILURE_TIMEOUT; + mount_enter_mounted(m, MOUNT_SUCCESS); + break; + + case MOUNT_UNMOUNTING: + log_warning("%s unmounting timed out. Stopping.", u->id); + mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT); + break; + + case MOUNT_MOUNTING_SIGTERM: + if (m->exec_context.send_sigkill) { + log_warning("%s mounting timed out. Killing.", u->id); + mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT); + } else { + log_warning("%s mounting timed out. Skipping SIGKILL. Ignoring.", u->id); + + if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT); + else + mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT); + } + break; + + case MOUNT_REMOUNTING_SIGTERM: + if (m->exec_context.send_sigkill) { + log_warning("%s remounting timed out. Killing.", u->id); + mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT); + } else { + log_warning("%s remounting timed out. Skipping SIGKILL. Ignoring.", u->id); + + if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT); + else + mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT); + } + break; + + case MOUNT_UNMOUNTING_SIGTERM: + if (m->exec_context.send_sigkill) { + log_warning("%s unmounting timed out. Killing.", u->id); + mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT); + } else { + log_warning("%s unmounting timed out. Skipping SIGKILL. Ignoring.", u->id); + + if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT); + else + mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT); + } + break; + + case MOUNT_MOUNTING_SIGKILL: + case MOUNT_REMOUNTING_SIGKILL: + case MOUNT_UNMOUNTING_SIGKILL: + log_warning("%s mount process still around after SIGKILL. Ignoring.", u->id); + + if (m->from_proc_self_mountinfo) + mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT); + else + mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT); + break; + + default: + assert_not_reached("Timeout at wrong time."); + } +} + +static int mount_add_one( + Manager *m, + const char *what, + const char *where, + const char *options, + const char *fstype, + int passno, + bool from_proc_self_mountinfo, + bool set_flags) { + int r; + Unit *u; + bool delete; + char *e, *w = NULL, *o = NULL, *f = NULL; + MountParameters *p; + + assert(m); + assert(what); + assert(where); + assert(options); + assert(fstype); + + assert(!set_flags || from_proc_self_mountinfo); + + /* Ignore API mount points. They should never be referenced in + * dependencies ever. */ + if (mount_point_is_api(where) || mount_point_ignore(where)) + return 0; + + if (streq(fstype, "autofs")) + return 0; + + /* probably some kind of swap, ignore */ + if (!is_path(where)) + return 0; + + e = unit_name_from_path(where, ".mount"); + if (!e) + return -ENOMEM; + + u = manager_get_unit(m, e); + if (!u) { + delete = true; + + u = unit_new(m, sizeof(Mount)); + if (!u) { + free(e); + return -ENOMEM; + } + + r = unit_add_name(u, e); + free(e); + + if (r < 0) + goto fail; + + MOUNT(u)->where = strdup(where); + if (!MOUNT(u)->where) { + r = -ENOMEM; + goto fail; + } + + unit_add_to_load_queue(u); + } else { + delete = false; + free(e); + } + + if (!(w = strdup(what)) || + !(o = strdup(options)) || + !(f = strdup(fstype))) { + r = -ENOMEM; + goto fail; + } + + if (from_proc_self_mountinfo) { + p = &MOUNT(u)->parameters_proc_self_mountinfo; + + if (set_flags) { + MOUNT(u)->is_mounted = true; + MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo; + MOUNT(u)->just_changed = !streq_ptr(p->options, o); + } + + MOUNT(u)->from_proc_self_mountinfo = true; + } else { + p = &MOUNT(u)->parameters_etc_fstab; + MOUNT(u)->from_etc_fstab = true; + } + + free(p->what); + p->what = w; + + free(p->options); + p->options = o; + + free(p->fstype); + p->fstype = f; + + p->passno = passno; + + unit_add_to_dbus_queue(u); + + return 0; + +fail: + free(w); + free(o); + free(f); + + if (delete && u) + unit_free(u); + + return r; +} + +static int mount_find_pri(char *options) { + char *end, *pri; + unsigned long r; + + if (!(pri = mount_test_option(options, "pri"))) + return 0; + + pri += 4; + + errno = 0; + r = strtoul(pri, &end, 10); + + if (errno != 0) + return -errno; + + if (end == pri || (*end != ',' && *end != 0)) + return -EINVAL; + + return (int) r; +} + +static int mount_load_etc_fstab(Manager *m) { + FILE *f; + int r = 0; + struct mntent* me; + + assert(m); + + errno = 0; + if (!(f = setmntent("/etc/fstab", "r"))) + return -errno; + + while ((me = getmntent(f))) { + char *where, *what; + int k; + + if (!(what = fstab_node_to_udev_node(me->mnt_fsname))) { + r = -ENOMEM; + goto finish; + } + + if (!(where = strdup(me->mnt_dir))) { + free(what); + r = -ENOMEM; + goto finish; + } + + if (what[0] == '/') + path_kill_slashes(what); + + if (where[0] == '/') + path_kill_slashes(where); + + if (streq(me->mnt_type, "swap")) { + int pri; + + if ((pri = mount_find_pri(me->mnt_opts)) < 0) + k = pri; + else + k = swap_add_one(m, + what, + NULL, + pri, + !!mount_test_option(me->mnt_opts, "noauto"), + !!mount_test_option(me->mnt_opts, "nofail"), + !!mount_test_option(me->mnt_opts, "comment=systemd.swapon"), + false); + } else + k = mount_add_one(m, what, where, me->mnt_opts, me->mnt_type, me->mnt_passno, false, false); + + free(what); + free(where); + + if (r < 0) + r = k; + } + +finish: + + endmntent(f); + return r; +} + +static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { + int r = 0; + unsigned i; + char *device, *path, *options, *options2, *fstype, *d, *p, *o; + + assert(m); + + rewind(m->proc_self_mountinfo); + + for (i = 1;; i++) { + int k; + + device = path = options = options2 = fstype = d = p = o = NULL; + + if ((k = fscanf(m->proc_self_mountinfo, + "%*s " /* (1) mount id */ + "%*s " /* (2) parent id */ + "%*s " /* (3) major:minor */ + "%*s " /* (4) root */ + "%ms " /* (5) mount point */ + "%ms" /* (6) mount options */ + "%*[^-]" /* (7) optional fields */ + "- " /* (8) separator */ + "%ms " /* (9) file system type */ + "%ms" /* (10) mount source */ + "%ms" /* (11) mount options 2 */ + "%*[^\n]", /* some rubbish at the end */ + &path, + &options, + &fstype, + &device, + &options2)) != 5) { + + if (k == EOF) + break; + + log_warning("Failed to parse /proc/self/mountinfo:%u.", i); + goto clean_up; + } + + if (asprintf(&o, "%s,%s", options, options2) < 0) { + r = -ENOMEM; + goto finish; + } + + if (!(d = cunescape(device)) || + !(p = cunescape(path))) { + r = -ENOMEM; + goto finish; + } + + if ((k = mount_add_one(m, d, p, o, fstype, 0, true, set_flags)) < 0) + r = k; + +clean_up: + free(device); + free(path); + free(options); + free(options2); + free(fstype); + free(d); + free(p); + free(o); + } + +finish: + free(device); + free(path); + free(options); + free(options2); + free(fstype); + free(d); + free(p); + free(o); + + return r; +} + +static void mount_shutdown(Manager *m) { + assert(m); + + if (m->proc_self_mountinfo) { + fclose(m->proc_self_mountinfo); + m->proc_self_mountinfo = NULL; + } +} + +static int mount_enumerate(Manager *m) { + int r; + struct epoll_event ev; + assert(m); + + if (!m->proc_self_mountinfo) { + if (!(m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"))) + return -errno; + + m->mount_watch.type = WATCH_MOUNT; + m->mount_watch.fd = fileno(m->proc_self_mountinfo); + + zero(ev); + ev.events = EPOLLPRI; + ev.data.ptr = &m->mount_watch; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->mount_watch.fd, &ev) < 0) + return -errno; + } + + if ((r = mount_load_etc_fstab(m)) < 0) + goto fail; + + if ((r = mount_load_proc_self_mountinfo(m, false)) < 0) + goto fail; + + return 0; + +fail: + mount_shutdown(m); + return r; +} + +void mount_fd_event(Manager *m, int events) { + Unit *u; + int r; + + assert(m); + assert(events & EPOLLPRI); + + /* The manager calls this for every fd event happening on the + * /proc/self/mountinfo file, which informs us about mounting + * table changes */ + + if ((r = mount_load_proc_self_mountinfo(m, true)) < 0) { + log_error("Failed to reread /proc/self/mountinfo: %s", strerror(-r)); + + /* Reset flags, just in case, for later calls */ + LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) { + Mount *mount = MOUNT(u); + + mount->is_mounted = mount->just_mounted = mount->just_changed = false; + } + + return; + } + + manager_dispatch_load_queue(m); + + LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) { + Mount *mount = MOUNT(u); + + if (!mount->is_mounted) { + /* This has just been unmounted. */ + + mount->from_proc_self_mountinfo = false; + + switch (mount->state) { + + case MOUNT_MOUNTED: + mount_enter_dead(mount, MOUNT_SUCCESS); + break; + + default: + mount_set_state(mount, mount->state); + break; + + } + + } else if (mount->just_mounted || mount->just_changed) { + + /* New or changed mount entry */ + + switch (mount->state) { + + case MOUNT_DEAD: + case MOUNT_FAILED: + mount_enter_mounted(mount, MOUNT_SUCCESS); + break; + + case MOUNT_MOUNTING: + mount_enter_mounting_done(mount); + break; + + default: + /* Nothing really changed, but let's + * issue an notification call + * nonetheless, in case somebody is + * waiting for this. (e.g. file system + * ro/rw remounts.) */ + mount_set_state(mount, mount->state); + break; + } + } + + /* Reset the flags for later calls */ + mount->is_mounted = mount->just_mounted = mount->just_changed = false; + } +} + +static void mount_reset_failed(Unit *u) { + Mount *m = MOUNT(u); + + assert(m); + + if (m->state == MOUNT_FAILED) + mount_set_state(m, MOUNT_DEAD); + + m->result = MOUNT_SUCCESS; + m->reload_result = MOUNT_SUCCESS; +} + +static int mount_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) { + Mount *m = MOUNT(u); + int r = 0; + Set *pid_set = NULL; + + assert(m); + + if (who == KILL_MAIN) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Mount units have no main processes"); + return -ESRCH; + } + + if (m->control_pid <= 0 && who == KILL_CONTROL) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill"); + return -ESRCH; + } + + if (who == KILL_CONTROL || who == KILL_ALL) + if (m->control_pid > 0) + if (kill(m->control_pid, signo) < 0) + r = -errno; + + if (who == KILL_ALL && mode == KILL_CONTROL_GROUP) { + int q; + + if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + /* Exclude the control pid from being killed via the cgroup */ + if (m->control_pid > 0) + if ((q = set_put(pid_set, LONG_TO_PTR(m->control_pid))) < 0) { + r = q; + goto finish; + } + + if ((q = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, signo, false, pid_set)) < 0) + if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) + r = q; + } + +finish: + if (pid_set) + set_free(pid_set); + + return r; +} + +static const char* const mount_state_table[_MOUNT_STATE_MAX] = { + [MOUNT_DEAD] = "dead", + [MOUNT_MOUNTING] = "mounting", + [MOUNT_MOUNTING_DONE] = "mounting-done", + [MOUNT_MOUNTED] = "mounted", + [MOUNT_REMOUNTING] = "remounting", + [MOUNT_UNMOUNTING] = "unmounting", + [MOUNT_MOUNTING_SIGTERM] = "mounting-sigterm", + [MOUNT_MOUNTING_SIGKILL] = "mounting-sigkill", + [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm", + [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill", + [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm", + [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill", + [MOUNT_FAILED] = "failed" +}; + +DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState); + +static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = { + [MOUNT_EXEC_MOUNT] = "ExecMount", + [MOUNT_EXEC_UNMOUNT] = "ExecUnmount", + [MOUNT_EXEC_REMOUNT] = "ExecRemount", +}; + +DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand); + +static const char* const mount_result_table[_MOUNT_RESULT_MAX] = { + [MOUNT_SUCCESS] = "success", + [MOUNT_FAILURE_RESOURCES] = "resources", + [MOUNT_FAILURE_TIMEOUT] = "timeout", + [MOUNT_FAILURE_EXIT_CODE] = "exit-code", + [MOUNT_FAILURE_SIGNAL] = "signal", + [MOUNT_FAILURE_CORE_DUMP] = "core-dump" +}; + +DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult); + +const UnitVTable mount_vtable = { + .suffix = ".mount", + .object_size = sizeof(Mount), + .sections = + "Unit\0" + "Mount\0" + "Install\0", + + .no_alias = true, + .no_instances = true, + .show_status = true, + + .init = mount_init, + .load = mount_load, + .done = mount_done, + + .coldplug = mount_coldplug, + + .dump = mount_dump, + + .start = mount_start, + .stop = mount_stop, + .reload = mount_reload, + + .kill = mount_kill, + + .serialize = mount_serialize, + .deserialize_item = mount_deserialize_item, + + .active_state = mount_active_state, + .sub_state_to_string = mount_sub_state_to_string, + + .check_gc = mount_check_gc, + + .sigchld_event = mount_sigchld_event, + .timer_event = mount_timer_event, + + .reset_failed = mount_reset_failed, + + .bus_interface = "org.freedesktop.systemd1.Mount", + .bus_message_handler = bus_mount_message_handler, + .bus_invalidating_properties = bus_mount_invalidating_properties, + + .enumerate = mount_enumerate, + .shutdown = mount_shutdown +}; diff --git a/src/mount.h b/src/mount.h new file mode 100644 index 0000000..9318444 --- /dev/null +++ b/src/mount.h @@ -0,0 +1,124 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foomounthfoo +#define foomounthfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct Mount Mount; + +#include "unit.h" + +typedef enum MountState { + MOUNT_DEAD, + MOUNT_MOUNTING, /* /bin/mount is running, but the mount is not done yet. */ + MOUNT_MOUNTING_DONE, /* /bin/mount is running, and the mount is done. */ + MOUNT_MOUNTED, + MOUNT_REMOUNTING, + MOUNT_UNMOUNTING, + MOUNT_MOUNTING_SIGTERM, + MOUNT_MOUNTING_SIGKILL, + MOUNT_REMOUNTING_SIGTERM, + MOUNT_REMOUNTING_SIGKILL, + MOUNT_UNMOUNTING_SIGTERM, + MOUNT_UNMOUNTING_SIGKILL, + MOUNT_FAILED, + _MOUNT_STATE_MAX, + _MOUNT_STATE_INVALID = -1 +} MountState; + +typedef enum MountExecCommand { + MOUNT_EXEC_MOUNT, + MOUNT_EXEC_UNMOUNT, + MOUNT_EXEC_REMOUNT, + _MOUNT_EXEC_COMMAND_MAX, + _MOUNT_EXEC_COMMAND_INVALID = -1 +} MountExecCommand; + +typedef struct MountParameters { + char *what; + char *options; + char *fstype; + int passno; +} MountParameters; + +typedef enum MountResult { + MOUNT_SUCCESS, + MOUNT_FAILURE_RESOURCES, + MOUNT_FAILURE_TIMEOUT, + MOUNT_FAILURE_EXIT_CODE, + MOUNT_FAILURE_SIGNAL, + MOUNT_FAILURE_CORE_DUMP, + _MOUNT_RESULT_MAX, + _MOUNT_RESULT_INVALID = -1 +} MountResult; + +struct Mount { + Unit meta; + + char *where; + + MountParameters parameters_etc_fstab; + MountParameters parameters_proc_self_mountinfo; + MountParameters parameters_fragment; + + bool from_etc_fstab:1; + bool from_proc_self_mountinfo:1; + bool from_fragment:1; + + /* Used while looking for mount points that vanished or got + * added from/to /proc/self/mountinfo */ + bool is_mounted:1; + bool just_mounted:1; + bool just_changed:1; + + MountResult result; + MountResult reload_result; + + mode_t directory_mode; + + usec_t timeout_usec; + + ExecCommand exec_command[_MOUNT_EXEC_COMMAND_MAX]; + ExecContext exec_context; + + MountState state, deserialized_state; + + ExecCommand* control_command; + MountExecCommand control_command_id; + pid_t control_pid; + + Watch timer_watch; +}; + +extern const UnitVTable mount_vtable; + +void mount_fd_event(Manager *m, int events); + +const char* mount_state_to_string(MountState i); +MountState mount_state_from_string(const char *s); + +const char* mount_exec_command_to_string(MountExecCommand i); +MountExecCommand mount_exec_command_from_string(const char *s); + +const char* mount_result_to_string(MountResult i); +MountResult mount_result_from_string(const char *s); + +#endif diff --git a/src/namespace.c b/src/namespace.c new file mode 100644 index 0000000..09bc829 --- /dev/null +++ b/src/namespace.c @@ -0,0 +1,346 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "strv.h" +#include "util.h" +#include "namespace.h" +#include "missing.h" + +typedef enum PathMode { + /* This is ordered by priority! */ + INACCESSIBLE, + READONLY, + PRIVATE, + READWRITE +} PathMode; + +typedef struct Path { + const char *path; + PathMode mode; +} Path; + +static int append_paths(Path **p, char **strv, PathMode mode) { + char **i; + + STRV_FOREACH(i, strv) { + + if (!path_is_absolute(*i)) + return -EINVAL; + + (*p)->path = *i; + (*p)->mode = mode; + (*p)++; + } + + return 0; +} + +static int path_compare(const void *a, const void *b) { + const Path *p = a, *q = b; + + if (path_equal(p->path, q->path)) { + + /* If the paths are equal, check the mode */ + if (p->mode < q->mode) + return -1; + + if (p->mode > q->mode) + return 1; + + return 0; + } + + /* If the paths are not equal, then order prefixes first */ + if (path_startswith(p->path, q->path)) + return 1; + + if (path_startswith(q->path, p->path)) + return -1; + + return 0; +} + +static void drop_duplicates(Path *p, unsigned *n, bool *need_inaccessible, bool *need_private) { + Path *f, *t, *previous; + + assert(p); + assert(n); + assert(need_inaccessible); + assert(need_private); + + for (f = p, t = p, previous = NULL; f < p+*n; f++) { + + if (previous && path_equal(f->path, previous->path)) + continue; + + t->path = f->path; + t->mode = f->mode; + + if (t->mode == PRIVATE) + *need_private = true; + + if (t->mode == INACCESSIBLE) + *need_inaccessible = true; + + previous = t; + + t++; + } + + *n = t - p; +} + +static int apply_mount(Path *p, const char *root_dir, const char *inaccessible_dir, const char *private_dir, unsigned long flags) { + const char *what; + char *where; + int r; + + assert(p); + assert(root_dir); + assert(inaccessible_dir); + assert(private_dir); + + if (!(where = strappend(root_dir, p->path))) + return -ENOMEM; + + switch (p->mode) { + + case INACCESSIBLE: + what = inaccessible_dir; + flags |= MS_RDONLY; + break; + + case READONLY: + flags |= MS_RDONLY; + /* Fall through */ + + case READWRITE: + what = p->path; + break; + + case PRIVATE: + what = private_dir; + break; + + default: + assert_not_reached("Unknown mode"); + } + + if ((r = mount(what, where, NULL, MS_BIND|MS_REC, NULL)) >= 0) { + log_debug("Successfully mounted %s to %s", what, where); + + /* The bind mount will always inherit the original + * flags. If we want to set any flag we need + * to do so in a second independent step. */ + if (flags) + r = mount(NULL, where, NULL, MS_REMOUNT|MS_BIND|MS_REC|flags, NULL); + + /* Avoid exponential growth of trees */ + if (r >= 0 && path_equal(p->path, "/")) + r = mount(NULL, where, NULL, MS_REMOUNT|MS_BIND|MS_UNBINDABLE|flags, NULL); + + if (r < 0) { + r = -errno; + umount2(where, MNT_DETACH); + } + } + + free(where); + return r; +} + +int setup_namespace( + char **writable, + char **readable, + char **inaccessible, + bool private_tmp, + unsigned long flags) { + + char + tmp_dir[] = "/tmp/systemd-namespace-XXXXXX", + root_dir[] = "/tmp/systemd-namespace-XXXXXX/root", + old_root_dir[] = "/tmp/systemd-namespace-XXXXXX/root/tmp/old-root-XXXXXX", + inaccessible_dir[] = "/tmp/systemd-namespace-XXXXXX/inaccessible", + private_dir[] = "/tmp/systemd-namespace-XXXXXX/private"; + + Path *paths, *p; + unsigned n; + bool need_private = false, need_inaccessible = false; + bool remove_tmp = false, remove_root = false, remove_old_root = false, remove_inaccessible = false, remove_private = false; + int r; + const char *t; + + n = + strv_length(writable) + + strv_length(readable) + + strv_length(inaccessible) + + (private_tmp ? 2 : 1); + + if (!(paths = new(Path, n))) + return -ENOMEM; + + p = paths; + if ((r = append_paths(&p, writable, READWRITE)) < 0 || + (r = append_paths(&p, readable, READONLY)) < 0 || + (r = append_paths(&p, inaccessible, INACCESSIBLE)) < 0) + goto fail; + + if (private_tmp) { + p->path = "/tmp"; + p->mode = PRIVATE; + p++; + } + + p->path = "/"; + p->mode = READWRITE; + p++; + + assert(paths + n == p); + + qsort(paths, n, sizeof(Path), path_compare); + drop_duplicates(paths, &n, &need_inaccessible, &need_private); + + if (!mkdtemp(tmp_dir)) { + r = -errno; + goto fail; + } + remove_tmp = true; + + memcpy(root_dir, tmp_dir, sizeof(tmp_dir)-1); + if (mkdir(root_dir, 0777) < 0) { + r = -errno; + goto fail; + } + remove_root = true; + + if (need_inaccessible) { + memcpy(inaccessible_dir, tmp_dir, sizeof(tmp_dir)-1); + if (mkdir(inaccessible_dir, 0) < 0) { + r = -errno; + goto fail; + } + remove_inaccessible = true; + } + + if (need_private) { + mode_t u; + + memcpy(private_dir, tmp_dir, sizeof(tmp_dir)-1); + + u = umask(0000); + if (mkdir(private_dir, 0777 + S_ISVTX) < 0) { + umask(u); + + r = -errno; + goto fail; + } + + umask(u); + remove_private = true; + } + + if (unshare(CLONE_NEWNS) < 0) { + r = -errno; + goto fail; + } + + /* Remount / as SLAVE so that nothing mounted in the namespace + shows up in the parent */ + if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) { + r = -errno; + goto fail; + } + + for (p = paths; p < paths + n; p++) + if ((r = apply_mount(p, root_dir, inaccessible_dir, private_dir, flags)) < 0) + goto undo_mounts; + + memcpy(old_root_dir, tmp_dir, sizeof(tmp_dir)-1); + if (!mkdtemp(old_root_dir)) { + r = -errno; + goto undo_mounts; + } + remove_old_root = true; + + if (chdir(root_dir) < 0) { + r = -errno; + goto undo_mounts; + } + + if (pivot_root(root_dir, old_root_dir) < 0) { + r = -errno; + goto undo_mounts; + } + + t = old_root_dir + sizeof(root_dir) - 1; + if (umount2(t, MNT_DETACH) < 0) + /* At this point it's too late to turn anything back, + * since we are already in the new root. */ + return -errno; + + if (rmdir(t) < 0) + return -errno; + + return 0; + +undo_mounts: + + for (p--; p >= paths; p--) { + char full_path[PATH_MAX]; + + snprintf(full_path, sizeof(full_path), "%s%s", root_dir, p->path); + char_array_0(full_path); + + umount2(full_path, MNT_DETACH); + } + +fail: + if (remove_old_root) + rmdir(old_root_dir); + + if (remove_inaccessible) + rmdir(inaccessible_dir); + + if (remove_private) + rmdir(private_dir); + + if (remove_root) + rmdir(root_dir); + + if (remove_tmp) + rmdir(tmp_dir); + + free(paths); + + return r; +} diff --git a/src/namespace.h b/src/namespace.h new file mode 100644 index 0000000..7cf1ded --- /dev/null +++ b/src/namespace.h @@ -0,0 +1,34 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foonamespacehfoo +#define foonamespacehfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +int setup_namespace( + char **writable, + char **readable, + char **inaccessible, + bool private_tmp, + unsigned long flags); + +#endif diff --git a/src/notify.c b/src/notify.c new file mode 100644 index 0000000..9d52bdf --- /dev/null +++ b/src/notify.c @@ -0,0 +1,218 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "strv.h" +#include "util.h" +#include "log.h" +#include "sd-readahead.h" + +static bool arg_ready = false; +static pid_t arg_pid = 0; +static const char *arg_status = NULL; +static bool arg_booted = false; +static const char *arg_readahead = NULL; + +static int help(void) { + + printf("%s [OPTIONS...] [VARIABLE=VALUE...]\n\n" + "Notify the init system about service status updates.\n\n" + " -h --help Show this help\n" + " --ready Inform the init system about service start-up completion\n" + " --pid[=PID] Set main pid of daemon\n" + " --status=TEXT Set status text\n" + " --booted Returns 0 if the system was booted up with systemd, non-zero otherwise\n" + " --readahead=ACTION Controls read-ahead operations\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_READY = 0x100, + ARG_PID, + ARG_STATUS, + ARG_BOOTED, + ARG_READAHEAD + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "ready", no_argument, NULL, ARG_READY }, + { "pid", optional_argument, NULL, ARG_PID }, + { "status", required_argument, NULL, ARG_STATUS }, + { "booted", no_argument, NULL, ARG_BOOTED }, + { "readahead", required_argument, NULL, ARG_READAHEAD }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_READY: + arg_ready = true; + break; + + case ARG_PID: + + if (optarg) { + if (parse_pid(optarg, &arg_pid) < 0) { + log_error("Failed to parse PID %s.", optarg); + return -EINVAL; + } + } else + arg_pid = getppid(); + + break; + + case ARG_STATUS: + arg_status = optarg; + break; + + case ARG_BOOTED: + arg_booted = true; + break; + + case ARG_READAHEAD: + arg_readahead = optarg; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind >= argc && + !arg_ready && + !arg_status && + !arg_pid && + !arg_booted && + !arg_readahead) { + help(); + return -EINVAL; + } + + return 1; +} + +int main(int argc, char* argv[]) { + char* our_env[4], **final_env = NULL; + unsigned i = 0; + char *status = NULL, *cpid = NULL, *n = NULL; + int r, retval = EXIT_FAILURE; + + log_parse_environment(); + log_open(); + + if ((r = parse_argv(argc, argv)) <= 0) { + retval = r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + goto finish; + } + + if (arg_booted) + return sd_booted() <= 0; + + if (arg_readahead) { + if ((r = sd_readahead(arg_readahead)) < 0) { + log_error("Failed to issue read-ahead control command: %s", strerror(-r)); + goto finish; + } + } + + if (arg_ready) + our_env[i++] = (char*) "READY=1"; + + if (arg_status) { + if (!(status = strappend("STATUS=", arg_status))) { + log_error("Failed to allocate STATUS string."); + goto finish; + } + + our_env[i++] = status; + } + + if (arg_pid > 0) { + if (asprintf(&cpid, "MAINPID=%lu", (unsigned long) arg_pid) < 0) { + log_error("Failed to allocate MAINPID string."); + goto finish; + } + + our_env[i++] = cpid; + } + + our_env[i++] = NULL; + + if (!(final_env = strv_env_merge(2, our_env, argv + optind))) { + log_error("Failed to merge string sets."); + goto finish; + } + + if (strv_length(final_env) <= 0) { + retval = EXIT_SUCCESS; + goto finish; + } + + if (!(n = strv_join(final_env, "\n"))) { + log_error("Failed to concatenate strings."); + goto finish; + } + + if ((r = sd_notify(false, n)) < 0) { + log_error("Failed to notify init system: %s", strerror(-r)); + goto finish; + } + + retval = r <= 0 ? EXIT_FAILURE : EXIT_SUCCESS; + +finish: + free(status); + free(cpid); + free(n); + + strv_free(final_env); + + return retval; +} diff --git a/src/nspawn.c b/src/nspawn.c new file mode 100644 index 0000000..b8b379d --- /dev/null +++ b/src/nspawn.c @@ -0,0 +1,881 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "log.h" +#include "util.h" +#include "missing.h" +#include "cgroup-util.h" +#include "strv.h" +#include "loopback-setup.h" + +static char *arg_directory = NULL; +static char *arg_user = NULL; +static bool arg_private_network = false; + +static int help(void) { + + printf("%s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n" + "Spawn a minimal namespace container for debugging, testing and building.\n\n" + " -h --help Show this help\n" + " -D --directory=NAME Root directory for the container\n" + " -u --user=USER Run the command under specified user or uid\n" + " --private-network Disable network in container\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_PRIVATE_NETWORK = 0x100 + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "directory", required_argument, NULL, 'D' }, + { "user", required_argument, NULL, 'u' }, + { "private-network", no_argument, NULL, ARG_PRIVATE_NETWORK }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "+hD:u:", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case 'D': + free(arg_directory); + if (!(arg_directory = strdup(optarg))) { + log_error("Failed to duplicate root directory."); + return -ENOMEM; + } + + break; + + case 'u': + free(arg_user); + if (!(arg_user = strdup(optarg))) { + log_error("Failed to duplicate user name."); + return -ENOMEM; + } + + break; + + case ARG_PRIVATE_NETWORK: + arg_private_network = true; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +static int mount_all(const char *dest) { + + typedef struct MountPoint { + const char *what; + const char *where; + const char *type; + const char *options; + unsigned long flags; + bool fatal; + } MountPoint; + + static const MountPoint mount_table[] = { + { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, + { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND, true }, /* Bind mount first */ + { "/proc/sys", "/proc/sys", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, true }, /* Then, make it r/o */ + { "/sys", "/sys", "bind", NULL, MS_BIND, true }, /* Bind mount first */ + { "/sys", "/sys", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, true }, /* Then, make it r/o */ + { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID, true }, + { "/dev/pts", "/dev/pts", "bind", NULL, MS_BIND, true }, + { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV, true }, +#ifdef HAVE_SELINUX + { "/sys/fs/selinux", "/sys/fs/selinux", "bind", NULL, MS_BIND, false }, /* Bind mount first */ + { "/sys/fs/selinux", "/sys/fs/selinux", "bind", NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, false }, /* Then, make it r/o */ +#endif + }; + + unsigned k; + int r = 0; + char *where; + + for (k = 0; k < ELEMENTSOF(mount_table); k++) { + int t; + + if (asprintf(&where, "%s/%s", dest, mount_table[k].where) < 0) { + log_error("Out of memory"); + + if (r == 0) + r = -ENOMEM; + + break; + } + + if ((t = path_is_mount_point(where, false)) < 0) { + log_error("Failed to detect whether %s is a mount point: %s", where, strerror(-t)); + free(where); + + if (r == 0) + r = t; + + continue; + } + + mkdir_p(where, 0755); + + if (mount(mount_table[k].what, + where, + mount_table[k].type, + mount_table[k].flags, + mount_table[k].options) < 0 && + mount_table[k].fatal) { + + log_error("mount(%s) failed: %m", where); + + if (r == 0) + r = -errno; + } + + free(where); + } + + /* Fix the timezone, if possible */ + if (asprintf(&where, "%s/%s", dest, "/etc/localtime") >= 0) { + + if (mount("/etc/localtime", where, "bind", MS_BIND, NULL) >= 0) + mount("/etc/localtime", where, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL); + + free(where); + } + + return r; +} + +static int copy_devnodes(const char *dest, const char *console) { + + static const char devnodes[] = + "null\0" + "zero\0" + "full\0" + "random\0" + "urandom\0" + "tty\0" + "ptmx\0" + "kmsg\0" + "rtc0\0"; + + const char *d; + int r = 0, k; + mode_t u; + struct stat st; + char *from = NULL, *to = NULL; + + assert(dest); + assert(console); + + u = umask(0000); + + NULSTR_FOREACH(d, devnodes) { + from = to = NULL; + + asprintf(&from, "/dev/%s", d); + asprintf(&to, "%s/dev/%s", dest, d); + + if (!from || !to) { + log_error("Failed to allocate devnode path"); + + free(from); + free(to); + + from = to = NULL; + + if (r == 0) + r = -ENOMEM; + + break; + } + + if (stat(from, &st) < 0) { + + if (errno != ENOENT) { + log_error("Failed to stat %s: %m", from); + if (r == 0) + r = -errno; + } + + } else if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) { + + log_error("%s is not a char or block device, cannot copy.", from); + if (r == 0) + r = -EIO; + + } else if (mknod(to, st.st_mode, st.st_rdev) < 0) { + + log_error("mknod(%s) failed: %m", dest); + if (r == 0) + r = -errno; + } + + free(from); + free(to); + } + + if (stat(console, &st) < 0) { + + log_error("Failed to stat %s: %m", console); + if (r == 0) + r = -errno; + + goto finish; + + } else if (!S_ISCHR(st.st_mode)) { + + log_error("/dev/console is not a char device."); + if (r == 0) + r = -EIO; + + goto finish; + } + + if (asprintf(&to, "%s/dev/console", dest) < 0) { + + log_error("Out of memory"); + if (r == 0) + r = -ENOMEM; + + goto finish; + } + + /* We need to bind mount the right tty to /dev/console since + * ptys can only exist on pts file systems. To have something + * to bind mount things on we create a device node first, that + * has the right major/minor (note that the major minor + * doesn't actually matter here, since we mount it over + * anyway). */ + + if (mknod(to, (st.st_mode & ~07777) | 0600, st.st_rdev) < 0) + log_error("mknod for /dev/console failed: %m"); + + if (mount(console, to, "bind", MS_BIND, NULL) < 0) { + log_error("bind mount for /dev/console failed: %m"); + + if (r == 0) + r = -errno; + } + + free(to); + + if ((k = chmod_and_chown(console, 0600, 0, 0)) < 0) { + log_error("Failed to correct access mode for TTY: %s", strerror(-k)); + + if (r == 0) + r = k; + } + +finish: + umask(u); + + return r; +} + +static int drop_capabilities(void) { + static const unsigned long retain[] = { + CAP_CHOWN, + CAP_DAC_OVERRIDE, + CAP_DAC_READ_SEARCH, + CAP_FOWNER, + CAP_FSETID, + CAP_IPC_OWNER, + CAP_KILL, + CAP_LEASE, + CAP_LINUX_IMMUTABLE, + CAP_NET_BIND_SERVICE, + CAP_NET_BROADCAST, + CAP_NET_RAW, + CAP_SETGID, + CAP_SETFCAP, + CAP_SETPCAP, + CAP_SETUID, + CAP_SYS_ADMIN, + CAP_SYS_CHROOT, + CAP_SYS_NICE, + CAP_SYS_PTRACE, + CAP_SYS_TTY_CONFIG + }; + + unsigned long l; + + for (l = 0; l <= cap_last_cap(); l++) { + unsigned i; + + for (i = 0; i < ELEMENTSOF(retain); i++) + if (retain[i] == l) + break; + + if (i < ELEMENTSOF(retain)) + continue; + + if (prctl(PR_CAPBSET_DROP, l) < 0) { + log_error("PR_CAPBSET_DROP failed: %m"); + return -errno; + } + } + + return 0; +} + +static int is_os_tree(const char *path) { + int r; + char *p; + /* We use /bin/sh as flag file if something is an OS */ + + if (asprintf(&p, "%s/bin/sh", path) < 0) + return -ENOMEM; + + r = access(p, F_OK); + free(p); + + return r < 0 ? 0 : 1; +} + +static int process_pty(int master, sigset_t *mask) { + + char in_buffer[LINE_MAX], out_buffer[LINE_MAX]; + size_t in_buffer_full = 0, out_buffer_full = 0; + struct epoll_event stdin_ev, stdout_ev, master_ev, signal_ev; + bool stdin_readable = false, stdout_writable = false, master_readable = false, master_writable = false; + int ep = -1, signal_fd = -1, r; + + fd_nonblock(STDIN_FILENO, 1); + fd_nonblock(STDOUT_FILENO, 1); + fd_nonblock(master, 1); + + if ((signal_fd = signalfd(-1, mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) { + log_error("signalfd(): %m"); + r = -errno; + goto finish; + } + + if ((ep = epoll_create1(EPOLL_CLOEXEC)) < 0) { + log_error("Failed to create epoll: %m"); + r = -errno; + goto finish; + } + + zero(stdin_ev); + stdin_ev.events = EPOLLIN|EPOLLET; + stdin_ev.data.fd = STDIN_FILENO; + + zero(stdout_ev); + stdout_ev.events = EPOLLOUT|EPOLLET; + stdout_ev.data.fd = STDOUT_FILENO; + + zero(master_ev); + master_ev.events = EPOLLIN|EPOLLOUT|EPOLLET; + master_ev.data.fd = master; + + zero(signal_ev); + signal_ev.events = EPOLLIN; + signal_ev.data.fd = signal_fd; + + if (epoll_ctl(ep, EPOLL_CTL_ADD, STDIN_FILENO, &stdin_ev) < 0 || + epoll_ctl(ep, EPOLL_CTL_ADD, STDOUT_FILENO, &stdout_ev) < 0 || + epoll_ctl(ep, EPOLL_CTL_ADD, master, &master_ev) < 0 || + epoll_ctl(ep, EPOLL_CTL_ADD, signal_fd, &signal_ev) < 0) { + log_error("Failed to regiser fds in epoll: %m"); + r = -errno; + goto finish; + } + + for (;;) { + struct epoll_event ev[16]; + ssize_t k; + int i, nfds; + + if ((nfds = epoll_wait(ep, ev, ELEMENTSOF(ev), -1)) < 0) { + + if (errno == EINTR || errno == EAGAIN) + continue; + + log_error("epoll_wait(): %m"); + r = -errno; + goto finish; + } + + assert(nfds >= 1); + + for (i = 0; i < nfds; i++) { + if (ev[i].data.fd == STDIN_FILENO) { + + if (ev[i].events & (EPOLLIN|EPOLLHUP)) + stdin_readable = true; + + } else if (ev[i].data.fd == STDOUT_FILENO) { + + if (ev[i].events & (EPOLLOUT|EPOLLHUP)) + stdout_writable = true; + + } else if (ev[i].data.fd == master) { + + if (ev[i].events & (EPOLLIN|EPOLLHUP)) + master_readable = true; + + if (ev[i].events & (EPOLLOUT|EPOLLHUP)) + master_writable = true; + + } else if (ev[i].data.fd == signal_fd) { + struct signalfd_siginfo sfsi; + ssize_t n; + + if ((n = read(signal_fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) { + + if (n >= 0) { + log_error("Failed to read from signalfd: invalid block size"); + r = -EIO; + goto finish; + } + + if (errno != EINTR && errno != EAGAIN) { + log_error("Failed to read from signalfd: %m"); + r = -errno; + goto finish; + } + } else { + + if (sfsi.ssi_signo == SIGWINCH) { + struct winsize ws; + + /* The window size changed, let's forward that. */ + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0) + ioctl(master, TIOCSWINSZ, &ws); + } else { + r = 0; + goto finish; + } + } + } + } + + while ((stdin_readable && in_buffer_full <= 0) || + (master_writable && in_buffer_full > 0) || + (master_readable && out_buffer_full <= 0) || + (stdout_writable && out_buffer_full > 0)) { + + if (stdin_readable && in_buffer_full < LINE_MAX) { + + if ((k = read(STDIN_FILENO, in_buffer + in_buffer_full, LINE_MAX - in_buffer_full)) < 0) { + + if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO) + stdin_readable = false; + else { + log_error("read(): %m"); + r = -errno; + goto finish; + } + } else + in_buffer_full += (size_t) k; + } + + if (master_writable && in_buffer_full > 0) { + + if ((k = write(master, in_buffer, in_buffer_full)) < 0) { + + if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO) + master_writable = false; + else { + log_error("write(): %m"); + r = -errno; + goto finish; + } + + } else { + assert(in_buffer_full >= (size_t) k); + memmove(in_buffer, in_buffer + k, in_buffer_full - k); + in_buffer_full -= k; + } + } + + if (master_readable && out_buffer_full < LINE_MAX) { + + if ((k = read(master, out_buffer + out_buffer_full, LINE_MAX - out_buffer_full)) < 0) { + + if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO) + master_readable = false; + else { + log_error("read(): %m"); + r = -errno; + goto finish; + } + } else + out_buffer_full += (size_t) k; + } + + if (stdout_writable && out_buffer_full > 0) { + + if ((k = write(STDOUT_FILENO, out_buffer, out_buffer_full)) < 0) { + + if (errno == EAGAIN || errno == EPIPE || errno == ECONNRESET || errno == EIO) + stdout_writable = false; + else { + log_error("write(): %m"); + r = -errno; + goto finish; + } + + } else { + assert(out_buffer_full >= (size_t) k); + memmove(out_buffer, out_buffer + k, out_buffer_full - k); + out_buffer_full -= k; + } + } + } + } + +finish: + if (ep >= 0) + close_nointr_nofail(ep); + + if (signal_fd >= 0) + close_nointr_nofail(signal_fd); + + return r; +} + +int main(int argc, char *argv[]) { + pid_t pid = 0; + int r = EXIT_FAILURE, k; + char *oldcg = NULL, *newcg = NULL; + int master = -1; + const char *console = NULL; + struct termios saved_attr, raw_attr; + sigset_t mask; + bool saved_attr_valid = false; + struct winsize ws; + + log_parse_environment(); + log_open(); + + if ((r = parse_argv(argc, argv)) <= 0) + goto finish; + + if (arg_directory) { + char *p; + + p = path_make_absolute_cwd(arg_directory); + free(arg_directory); + arg_directory = p; + } else + arg_directory = get_current_dir_name(); + + if (!arg_directory) { + log_error("Failed to determine path"); + goto finish; + } + + path_kill_slashes(arg_directory); + + if (geteuid() != 0) { + log_error("Need to be root."); + goto finish; + } + + if (sd_booted() <= 0) { + log_error("Not running on a systemd system."); + goto finish; + } + + if (path_equal(arg_directory, "/")) { + log_error("Spawning container on root directory not supported."); + goto finish; + } + + if (is_os_tree(arg_directory) <= 0) { + log_error("Directory %s doesn't look like an OS root directory. Refusing.", arg_directory); + goto finish; + } + + if ((k = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 0, &oldcg)) < 0) { + log_error("Failed to determine current cgroup: %s", strerror(-k)); + goto finish; + } + + if (asprintf(&newcg, "%s/nspawn-%lu", oldcg, (unsigned long) getpid()) < 0) { + log_error("Failed to allocate cgroup path."); + goto finish; + } + + if ((k = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, newcg, 0)) < 0) { + log_error("Failed to create cgroup: %s", strerror(-k)); + goto finish; + } + + if ((master = posix_openpt(O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY)) < 0) { + log_error("Failed to acquire pseudo tty: %m"); + goto finish; + } + + if (!(console = ptsname(master))) { + log_error("Failed to determine tty name: %m"); + goto finish; + } + + log_info("Spawning namespace container on %s (console is %s).", arg_directory, console); + + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0) + ioctl(master, TIOCSWINSZ, &ws); + + if (unlockpt(master) < 0) { + log_error("Failed to unlock tty: %m"); + goto finish; + } + + if (tcgetattr(STDIN_FILENO, &saved_attr) < 0) { + log_error("Failed to get terminal attributes: %m"); + goto finish; + } + + saved_attr_valid = true; + + raw_attr = saved_attr; + cfmakeraw(&raw_attr); + raw_attr.c_lflag &= ~ECHO; + + if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr) < 0) { + log_error("Failed to set terminal attributes: %m"); + goto finish; + } + + assert_se(sigemptyset(&mask) == 0); + sigset_add_many(&mask, SIGCHLD, SIGWINCH, SIGTERM, SIGINT, -1); + assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0); + + if ((pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS|(arg_private_network ? CLONE_NEWNET : 0), NULL)) < 0) { + log_error("clone() failed: %m"); + goto finish; + } + + if (pid == 0) { + /* child */ + + const char *hn; + const char *home = NULL; + uid_t uid = (uid_t) -1; + gid_t gid = (gid_t) -1; + const char *envp[] = { + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + "container=systemd-nspawn", /* LXC sets container=lxc, so follow the scheme here */ + NULL, /* TERM */ + NULL, /* HOME */ + NULL, /* USER */ + NULL, /* LOGNAME */ + NULL + }; + + envp[2] = strv_find_prefix(environ, "TERM="); + + close_nointr_nofail(master); + + close_nointr(STDIN_FILENO); + close_nointr(STDOUT_FILENO); + close_nointr(STDERR_FILENO); + + close_all_fds(NULL, 0); + + reset_all_signal_handlers(); + + assert_se(sigemptyset(&mask) == 0); + assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); + + if (setsid() < 0) + goto child_fail; + + if (prctl(PR_SET_PDEATHSIG, SIGKILL) < 0) + goto child_fail; + + /* Mark / as private, in case somebody marked it shared */ + if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) + goto child_fail; + + if (mount_all(arg_directory) < 0) + goto child_fail; + + if (copy_devnodes(arg_directory, console) < 0) + goto child_fail; + + if (chdir(arg_directory) < 0) { + log_error("chdir(%s) failed: %m", arg_directory); + goto child_fail; + } + + if (open_terminal("dev/console", O_RDWR) != STDIN_FILENO || + dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO || + dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) + goto child_fail; + + if (mount(arg_directory, "/", "bind", MS_BIND|MS_MOVE, NULL) < 0) { + log_error("mount(MS_MOVE) failed: %m"); + goto child_fail; + } + + if (chroot(".") < 0) { + log_error("chroot() failed: %m"); + goto child_fail; + } + + if (chdir("/") < 0) { + log_error("chdir() failed: %m"); + goto child_fail; + } + + umask(0022); + + loopback_setup(); + + if (drop_capabilities() < 0) + goto child_fail; + + if (arg_user) { + + if (get_user_creds((const char**)&arg_user, &uid, &gid, &home) < 0) { + log_error("get_user_creds() failed: %m"); + goto child_fail; + } + + if (mkdir_parents(home, 0775) < 0) { + log_error("mkdir_parents() failed: %m"); + goto child_fail; + } + + if (safe_mkdir(home, 0775, uid, gid) < 0) { + log_error("safe_mkdir() failed: %m"); + goto child_fail; + } + + if (initgroups((const char*)arg_user, gid) < 0) { + log_error("initgroups() failed: %m"); + goto child_fail; + } + + if (setresgid(gid, gid, gid) < 0) { + log_error("setregid() failed: %m"); + goto child_fail; + } + + if (setresuid(uid, uid, uid) < 0) { + log_error("setreuid() failed: %m"); + goto child_fail; + } + } + + if ((asprintf((char**)(envp + 3), "HOME=%s", home? home: "/root") < 0) || + (asprintf((char**)(envp + 4), "USER=%s", arg_user? arg_user : "root") < 0) || + (asprintf((char**)(envp + 5), "LOGNAME=%s", arg_user? arg_user : "root") < 0)) { + log_error("Out of memory"); + goto child_fail; + } + + if ((hn = file_name_from_path(arg_directory))) + sethostname(hn, strlen(hn)); + + if (argc > optind) + execvpe(argv[optind], argv + optind, (char**) envp); + else { + chdir(home ? home : "/root"); + execle("/bin/bash", "-bash", NULL, (char**) envp); + } + + log_error("execv() failed: %m"); + + child_fail: + _exit(EXIT_FAILURE); + } + + if (process_pty(master, &mask) < 0) + goto finish; + + if (saved_attr_valid) { + tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr); + saved_attr_valid = false; + } + + r = wait_for_terminate_and_warn(argc > optind ? argv[optind] : "bash", pid); + + if (r < 0) + r = EXIT_FAILURE; + +finish: + if (saved_attr_valid) + tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr); + + if (master >= 0) + close_nointr_nofail(master); + + if (oldcg) + cg_attach(SYSTEMD_CGROUP_CONTROLLER, oldcg, 0); + + if (newcg) + cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, newcg, true); + + free(arg_directory); + free(oldcg); + free(newcg); + + return r; +} diff --git a/src/org.freedesktop.systemd1.conf b/src/org.freedesktop.systemd1.conf new file mode 100644 index 0000000..201afe6 --- /dev/null +++ b/src/org.freedesktop.systemd1.conf @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/org.freedesktop.systemd1.policy.in.in b/src/org.freedesktop.systemd1.policy.in.in new file mode 100644 index 0000000..1771314 --- /dev/null +++ b/src/org.freedesktop.systemd1.policy.in.in @@ -0,0 +1,41 @@ + + + + + + + + The systemd Project + http://www.freedesktop.org/wiki/Software/systemd + + + <_description>Send passphrase back to system + <_message>Authentication is required to send the entered passphrase back to the system. + + no + no + auth_admin_keep + + @rootlibexecdir@/systemd-reply-password + + + + <_description>Privileged system and service manager access + <_message>Authentication is required to access the system and service manager. + + no + no + auth_admin_keep + + @bindir@/systemd-stdio-bridge + + + diff --git a/src/org.freedesktop.systemd1.service b/src/org.freedesktop.systemd1.service new file mode 100644 index 0000000..7e1dfd4 --- /dev/null +++ b/src/org.freedesktop.systemd1.service @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# systemd 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. + +[D-BUS Service] +Name=org.freedesktop.systemd1 +Exec=/bin/false +User=root diff --git a/src/pager.c b/src/pager.c new file mode 100644 index 0000000..3fc8182 --- /dev/null +++ b/src/pager.c @@ -0,0 +1,134 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include + +#include "pager.h" +#include "util.h" +#include "macro.h" + +static pid_t pager_pid = 0; + +_noreturn_ static void pager_fallback(void) { + ssize_t n; + do { + n = splice(STDIN_FILENO, NULL, STDOUT_FILENO, NULL, 64*1024, 0); + } while (n > 0); + if (n < 0) { + log_error("Internal pager failed: %m"); + _exit(EXIT_FAILURE); + } + _exit(EXIT_SUCCESS); +} + +void pager_open(void) { + int fd[2]; + const char *pager; + pid_t parent_pid; + + if (pager_pid > 0) + return; + + if ((pager = getenv("SYSTEMD_PAGER")) || (pager = getenv("PAGER"))) + if (!*pager || streq(pager, "cat")) + return; + + if (isatty(STDOUT_FILENO) <= 0) + return; + + /* Determine and cache number of columns before we spawn the + * pager so that we get the value from the actual tty */ + columns(); + + if (pipe(fd) < 0) { + log_error("Failed to create pager pipe: %m"); + return; + } + + parent_pid = getpid(); + + pager_pid = fork(); + if (pager_pid < 0) { + log_error("Failed to fork pager: %m"); + close_pipe(fd); + return; + } + + /* In the child start the pager */ + if (pager_pid == 0) { + + dup2(fd[0], STDIN_FILENO); + close_pipe(fd); + + setenv("LESS", "FRSX", 0); + + /* Make sure the pager goes away when the parent dies */ + if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) + _exit(EXIT_FAILURE); + + /* Check whether our parent died before we were able + * to set the death signal */ + if (getppid() != parent_pid) + _exit(EXIT_SUCCESS); + + if (pager) { + execlp(pager, pager, NULL); + execl("/bin/sh", "sh", "-c", pager, NULL); + } + + /* Debian's alternatives command for pagers is + * called 'pager'. Note that we do not call + * sensible-pagers here, since that is just a + * shell script that implements a logic that + * is similar to this one anyway, but is + * Debian-specific. */ + execlp("pager", "pager", NULL); + + execlp("less", "less", NULL); + execlp("more", "more", NULL); + + pager_fallback(); + /* not reached */ + } + + /* Return in the parent */ + if (dup2(fd[1], STDOUT_FILENO) < 0) + log_error("Failed to duplicate pager pipe: %m"); + + close_pipe(fd); +} + +void pager_close(void) { + + if (pager_pid <= 0) + return; + + /* Inform pager that we are done */ + fclose(stdout); + kill(pager_pid, SIGCONT); + wait_for_terminate(pager_pid, NULL); + pager_pid = 0; +} diff --git a/src/pager.h b/src/pager.h new file mode 100644 index 0000000..b5b4998 --- /dev/null +++ b/src/pager.h @@ -0,0 +1,28 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foopagerhfoo +#define foopagerhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +void pager_open(void); +void pager_close(void); + +#endif diff --git a/src/path-lookup.c b/src/path-lookup.c new file mode 100644 index 0000000..93fdf63 --- /dev/null +++ b/src/path-lookup.c @@ -0,0 +1,347 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "util.h" +#include "strv.h" + +#include "path-lookup.h" + +int user_config_home(char **config_home) { + const char *e; + + if ((e = getenv("XDG_CONFIG_HOME"))) { + if (asprintf(config_home, "%s/systemd/user", e) < 0) + return -ENOMEM; + + return 1; + } else { + const char *home; + + if ((home = getenv("HOME"))) { + if (asprintf(config_home, "%s/.config/systemd/user", home) < 0) + return -ENOMEM; + + return 1; + } + } + + return 0; +} + +static char** user_dirs(void) { + const char * const config_unit_paths[] = { + "/run/systemd/user", + USER_CONFIG_UNIT_PATH, + "/etc/systemd/user", + NULL + }; + + const char * const data_unit_paths[] = { + "/usr/local/lib/systemd/user", + "/usr/local/share/systemd/user", + USER_DATA_UNIT_PATH, + "/usr/lib/systemd/user", + "/usr/share/systemd/user", + NULL + }; + + const char *home, *e; + char *config_home = NULL, *data_home = NULL; + char **config_dirs = NULL, **data_dirs = NULL; + char **r = NULL, **t; + + /* Implement the mechanisms defined in + * + * http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html + * + * We look in both the config and the data dirs because we + * want to encourage that distributors ship their unit files + * as data, and allow overriding as configuration. + */ + + if (user_config_home(&config_home) < 0) + goto fail; + + home = getenv("HOME"); + + if ((e = getenv("XDG_CONFIG_DIRS"))) + if (!(config_dirs = strv_split(e, ":"))) + goto fail; + + /* We don't treat /etc/xdg/systemd here as the spec + * suggests because we assume that that is a link to + * /etc/systemd/ anyway. */ + + if ((e = getenv("XDG_DATA_HOME"))) { + if (asprintf(&data_home, "%s/systemd/user", e) < 0) + goto fail; + + } else if (home) { + if (asprintf(&data_home, "%s/.local/share/systemd/user", home) < 0) + goto fail; + + /* There is really no need for two unit dirs in $HOME, + * except to be fully compliant with the XDG spec. We + * now try to link the two dirs, so that we can + * minimize disk seeks a little. Further down we'll + * then filter out this link, if it is actually is + * one. */ + + mkdir_parents(data_home, 0777); + (void) symlink("../../../.config/systemd/user", data_home); + } + + if ((e = getenv("XDG_DATA_DIRS"))) + data_dirs = strv_split(e, ":"); + else + data_dirs = strv_new("/usr/local/share", + "/usr/share", + NULL); + + if (!data_dirs) + goto fail; + + /* Now merge everything we found. */ + if (config_home) { + if (!(t = strv_append(r, config_home))) + goto fail; + strv_free(r); + r = t; + } + + if (!strv_isempty(config_dirs)) { + if (!(t = strv_merge_concat(r, config_dirs, "/systemd/user"))) + goto finish; + strv_free(r); + r = t; + } + + if (!(t = strv_merge(r, (char**) config_unit_paths))) + goto fail; + strv_free(r); + r = t; + + if (data_home) { + if (!(t = strv_append(r, data_home))) + goto fail; + strv_free(r); + r = t; + } + + if (!strv_isempty(data_dirs)) { + if (!(t = strv_merge_concat(r, data_dirs, "/systemd/user"))) + goto fail; + strv_free(r); + r = t; + } + + if (!(t = strv_merge(r, (char**) data_unit_paths))) + goto fail; + strv_free(r); + r = t; + + if (!strv_path_make_absolute_cwd(r)) + goto fail; + +finish: + free(config_home); + strv_free(config_dirs); + free(data_home); + strv_free(data_dirs); + + return r; + +fail: + strv_free(r); + r = NULL; + goto finish; +} + +int lookup_paths_init(LookupPaths *p, ManagerRunningAs running_as, bool personal) { + const char *e; + char *t; + + assert(p); + + /* First priority is whatever has been passed to us via env + * vars */ + if ((e = getenv("SYSTEMD_UNIT_PATH"))) + if (!(p->unit_path = split_path_and_make_absolute(e))) + return -ENOMEM; + + if (strv_isempty(p->unit_path)) { + + /* Nothing is set, so let's figure something out. */ + strv_free(p->unit_path); + + if (running_as == MANAGER_USER) { + + if (personal) + p->unit_path = user_dirs(); + else + p->unit_path = strv_new( + /* If you modify this you also want to modify + * systemduserunitpath= in systemd.pc.in, and + * the arrays in user_dirs() above! */ + "/run/systemd/user", + USER_CONFIG_UNIT_PATH, + "/etc/systemd/user", + "/usr/local/lib/systemd/user", + "/usr/local/share/systemd/user", + USER_DATA_UNIT_PATH, + "/usr/lib/systemd/user", + "/usr/share/systemd/user", + NULL); + + if (!p->unit_path) + return -ENOMEM; + + } else + if (!(p->unit_path = strv_new( + /* If you modify this you also want to modify + * systemdsystemunitpath= in systemd.pc.in! */ + "/run/systemd/system", + SYSTEM_CONFIG_UNIT_PATH, + "/etc/systemd/system", + "/usr/local/lib/systemd/system", + "/usr/lib/systemd/system", + SYSTEM_DATA_UNIT_PATH, +#ifdef HAVE_SPLIT_USR + "/lib/systemd/system", +#endif + NULL))) + return -ENOMEM; + } + + if (p->unit_path) + if (!strv_path_canonicalize(p->unit_path)) + return -ENOMEM; + + strv_uniq(p->unit_path); + strv_path_remove_empty(p->unit_path); + + if (!strv_isempty(p->unit_path)) { + + if (!(t = strv_join(p->unit_path, "\n\t"))) + return -ENOMEM; + log_debug("Looking for unit files in:\n\t%s", t); + free(t); + } else { + log_debug("Ignoring unit files."); + strv_free(p->unit_path); + p->unit_path = NULL; + } + + if (running_as == MANAGER_SYSTEM) { +#ifdef HAVE_SYSV_COMPAT + /* /etc/init.d/ compatibility does not matter to users */ + + if ((e = getenv("SYSTEMD_SYSVINIT_PATH"))) + if (!(p->sysvinit_path = split_path_and_make_absolute(e))) + return -ENOMEM; + + if (strv_isempty(p->sysvinit_path)) { + strv_free(p->sysvinit_path); + + if (!(p->sysvinit_path = strv_new( + SYSTEM_SYSVINIT_PATH, /* /etc/init.d/ */ + NULL))) + return -ENOMEM; + } + + if ((e = getenv("SYSTEMD_SYSVRCND_PATH"))) + if (!(p->sysvrcnd_path = split_path_and_make_absolute(e))) + return -ENOMEM; + + if (strv_isempty(p->sysvrcnd_path)) { + strv_free(p->sysvrcnd_path); + + if (!(p->sysvrcnd_path = strv_new( + SYSTEM_SYSVRCND_PATH, /* /etc/rcN.d/ */ + NULL))) + return -ENOMEM; + } + + if (p->sysvinit_path) + if (!strv_path_canonicalize(p->sysvinit_path)) + return -ENOMEM; + + if (p->sysvrcnd_path) + if (!strv_path_canonicalize(p->sysvrcnd_path)) + return -ENOMEM; + + strv_uniq(p->sysvinit_path); + strv_uniq(p->sysvrcnd_path); + + strv_path_remove_empty(p->sysvinit_path); + strv_path_remove_empty(p->sysvrcnd_path); + + if (!strv_isempty(p->sysvinit_path)) { + + if (!(t = strv_join(p->sysvinit_path, "\n\t"))) + return -ENOMEM; + + log_debug("Looking for SysV init scripts in:\n\t%s", t); + free(t); + } else { + log_debug("Ignoring SysV init scripts."); + strv_free(p->sysvinit_path); + p->sysvinit_path = NULL; + } + + if (!strv_isempty(p->sysvrcnd_path)) { + + if (!(t = strv_join(p->sysvrcnd_path, "\n\t"))) + return -ENOMEM; + + log_debug("Looking for SysV rcN.d links in:\n\t%s", t); + free(t); + } else { + log_debug("Ignoring SysV rcN.d links."); + strv_free(p->sysvrcnd_path); + p->sysvrcnd_path = NULL; + } +#else + log_debug("Disabled SysV init scripts and rcN.d links support"); +#endif + } + + return 0; +} + +void lookup_paths_free(LookupPaths *p) { + assert(p); + + strv_free(p->unit_path); + p->unit_path = NULL; + +#ifdef HAVE_SYSV_COMPAT + strv_free(p->sysvinit_path); + strv_free(p->sysvrcnd_path); + p->sysvinit_path = p->sysvrcnd_path = NULL; +#endif +} diff --git a/src/path-lookup.h b/src/path-lookup.h new file mode 100644 index 0000000..fc2887d --- /dev/null +++ b/src/path-lookup.h @@ -0,0 +1,40 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foopathlookuphfoo +#define foopathlookuphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct LookupPaths { + char **unit_path; +#ifdef HAVE_SYSV_COMPAT + char **sysvinit_path; + char **sysvrcnd_path; +#endif +} LookupPaths; + +#include "manager.h" + +int user_config_home(char **config_home); + +int lookup_paths_init(LookupPaths *p, ManagerRunningAs running_as, bool personal); +void lookup_paths_free(LookupPaths *p); + +#endif diff --git a/src/path.c b/src/path.c new file mode 100644 index 0000000..e97cd09 --- /dev/null +++ b/src/path.c @@ -0,0 +1,770 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "unit.h" +#include "unit-name.h" +#include "path.h" +#include "dbus-path.h" +#include "special.h" +#include "bus-errors.h" + +static const UnitActiveState state_translation_table[_PATH_STATE_MAX] = { + [PATH_DEAD] = UNIT_INACTIVE, + [PATH_WAITING] = UNIT_ACTIVE, + [PATH_RUNNING] = UNIT_ACTIVE, + [PATH_FAILED] = UNIT_FAILED +}; + +int path_spec_watch(PathSpec *s, Unit *u) { + + static const int flags_table[_PATH_TYPE_MAX] = { + [PATH_EXISTS] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB, + [PATH_EXISTS_GLOB] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB, + [PATH_CHANGED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO, + [PATH_MODIFIED] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CLOSE_WRITE|IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO|IN_MODIFY, + [PATH_DIRECTORY_NOT_EMPTY] = IN_DELETE_SELF|IN_MOVE_SELF|IN_ATTRIB|IN_CREATE|IN_MOVED_TO + }; + + bool exists = false; + char *k, *slash; + int r; + + assert(u); + assert(s); + + path_spec_unwatch(s, u); + + if (!(k = strdup(s->path))) + return -ENOMEM; + + if ((s->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC)) < 0) { + r = -errno; + goto fail; + } + + if (unit_watch_fd(u, s->inotify_fd, EPOLLIN, &s->watch) < 0) { + r = -errno; + goto fail; + } + + if ((s->primary_wd = inotify_add_watch(s->inotify_fd, k, flags_table[s->type])) >= 0) + exists = true; + + do { + int flags; + + /* This assumes the path was passed through path_kill_slashes()! */ + if (!(slash = strrchr(k, '/'))) + break; + + /* Trim the path at the last slash. Keep the slash if it's the root dir. */ + slash[slash == k] = 0; + + flags = IN_MOVE_SELF; + if (!exists) + flags |= IN_DELETE_SELF | IN_ATTRIB | IN_CREATE | IN_MOVED_TO; + + if (inotify_add_watch(s->inotify_fd, k, flags) >= 0) + exists = true; + } while (slash != k); + + return 0; + +fail: + free(k); + + path_spec_unwatch(s, u); + return r; +} + +void path_spec_unwatch(PathSpec *s, Unit *u) { + + if (s->inotify_fd < 0) + return; + + unit_unwatch_fd(u, &s->watch); + + close_nointr_nofail(s->inotify_fd); + s->inotify_fd = -1; +} + +int path_spec_fd_event(PathSpec *s, uint32_t events) { + uint8_t *buf = NULL; + struct inotify_event *e; + ssize_t k; + int l; + int r = 0; + + if (events != EPOLLIN) { + log_error("Got Invalid poll event on inotify."); + r = -EINVAL; + goto out; + } + + if (ioctl(s->inotify_fd, FIONREAD, &l) < 0) { + log_error("FIONREAD failed: %m"); + r = -errno; + goto out; + } + + assert(l > 0); + + if (!(buf = malloc(l))) { + log_error("Failed to allocate buffer: %m"); + r = -errno; + goto out; + } + + if ((k = read(s->inotify_fd, buf, l)) < 0) { + log_error("Failed to read inotify event: %m"); + r = -errno; + goto out; + } + + e = (struct inotify_event*) buf; + + while (k > 0) { + size_t step; + + if ((s->type == PATH_CHANGED || s->type == PATH_MODIFIED) && + s->primary_wd == e->wd) + r = 1; + + step = sizeof(struct inotify_event) + e->len; + assert(step <= (size_t) k); + + e = (struct inotify_event*) ((uint8_t*) e + step); + k -= step; + } +out: + free(buf); + return r; +} + +static bool path_spec_check_good(PathSpec *s, bool initial) { + bool good = false; + + switch (s->type) { + + case PATH_EXISTS: + good = access(s->path, F_OK) >= 0; + break; + + case PATH_EXISTS_GLOB: + good = glob_exists(s->path) > 0; + break; + + case PATH_DIRECTORY_NOT_EMPTY: { + int k; + + k = dir_is_empty(s->path); + good = !(k == -ENOENT || k > 0); + break; + } + + case PATH_CHANGED: + case PATH_MODIFIED: { + bool b; + + b = access(s->path, F_OK) >= 0; + good = !initial && b != s->previous_exists; + s->previous_exists = b; + break; + } + + default: + ; + } + + return good; +} + +static bool path_spec_startswith(PathSpec *s, const char *what) { + return path_startswith(s->path, what); +} + +static void path_spec_mkdir(PathSpec *s, mode_t mode) { + int r; + + if (s->type == PATH_EXISTS || s->type == PATH_EXISTS_GLOB) + return; + + if ((r = mkdir_p(s->path, mode)) < 0) + log_warning("mkdir(%s) failed: %s", s->path, strerror(-r)); +} + +static void path_spec_dump(PathSpec *s, FILE *f, const char *prefix) { + fprintf(f, + "%s%s: %s\n", + prefix, + path_type_to_string(s->type), + s->path); +} + +void path_spec_done(PathSpec *s) { + assert(s); + assert(s->inotify_fd == -1); + + free(s->path); +} + +static void path_init(Unit *u) { + Path *p = PATH(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + p->directory_mode = 0755; +} + +static void path_done(Unit *u) { + Path *p = PATH(u); + PathSpec *s; + + assert(p); + + unit_ref_unset(&p->unit); + + while ((s = p->specs)) { + path_spec_unwatch(s, u); + LIST_REMOVE(PathSpec, spec, p->specs, s); + path_spec_done(s); + free(s); + } +} + +int path_add_one_mount_link(Path *p, Mount *m) { + PathSpec *s; + int r; + + assert(p); + assert(m); + + if (UNIT(p)->load_state != UNIT_LOADED || + UNIT(m)->load_state != UNIT_LOADED) + return 0; + + LIST_FOREACH(spec, s, p->specs) { + + if (!path_spec_startswith(s, m->where)) + continue; + + if ((r = unit_add_two_dependencies(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0) + return r; + } + + return 0; +} + +static int path_add_mount_links(Path *p) { + Unit *other; + int r; + + assert(p); + + LIST_FOREACH(units_by_type, other, UNIT(p)->manager->units_by_type[UNIT_MOUNT]) + if ((r = path_add_one_mount_link(p, MOUNT(other))) < 0) + return r; + + return 0; +} + +static int path_verify(Path *p) { + assert(p); + + if (UNIT(p)->load_state != UNIT_LOADED) + return 0; + + if (!p->specs) { + log_error("%s lacks path setting. Refusing.", UNIT(p)->id); + return -EINVAL; + } + + return 0; +} + +static int path_add_default_dependencies(Path *p) { + int r; + + assert(p); + + if (UNIT(p)->manager->running_as == MANAGER_SYSTEM) { + if ((r = unit_add_dependency_by_name(UNIT(p), UNIT_BEFORE, SPECIAL_BASIC_TARGET, NULL, true)) < 0) + return r; + + if ((r = unit_add_two_dependencies_by_name(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true)) < 0) + return r; + } + + return unit_add_two_dependencies_by_name(UNIT(p), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); +} + +static int path_load(Unit *u) { + Path *p = PATH(u); + int r; + + assert(u); + assert(u->load_state == UNIT_STUB); + + if ((r = unit_load_fragment_and_dropin(u)) < 0) + return r; + + if (u->load_state == UNIT_LOADED) { + + if (!UNIT_DEREF(p->unit)) { + Unit *x; + + r = unit_load_related_unit(u, ".service", &x); + if (r < 0) + return r; + + unit_ref_set(&p->unit, x); + } + + r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(p->unit), true); + if (r < 0) + return r; + + if ((r = path_add_mount_links(p)) < 0) + return r; + + if (UNIT(p)->default_dependencies) + if ((r = path_add_default_dependencies(p)) < 0) + return r; + } + + return path_verify(p); +} + +static void path_dump(Unit *u, FILE *f, const char *prefix) { + Path *p = PATH(u); + PathSpec *s; + + assert(p); + assert(f); + + fprintf(f, + "%sPath State: %s\n" + "%sResult: %s\n" + "%sUnit: %s\n" + "%sMakeDirectory: %s\n" + "%sDirectoryMode: %04o\n", + prefix, path_state_to_string(p->state), + prefix, path_result_to_string(p->result), + prefix, UNIT_DEREF(p->unit)->id, + prefix, yes_no(p->make_directory), + prefix, p->directory_mode); + + LIST_FOREACH(spec, s, p->specs) + path_spec_dump(s, f, prefix); +} + +static void path_unwatch(Path *p) { + PathSpec *s; + + assert(p); + + LIST_FOREACH(spec, s, p->specs) + path_spec_unwatch(s, UNIT(p)); +} + +static int path_watch(Path *p) { + int r; + PathSpec *s; + + assert(p); + + LIST_FOREACH(spec, s, p->specs) + if ((r = path_spec_watch(s, UNIT(p))) < 0) + return r; + + return 0; +} + +static void path_set_state(Path *p, PathState state) { + PathState old_state; + assert(p); + + old_state = p->state; + p->state = state; + + if (state != PATH_WAITING && + (state != PATH_RUNNING || p->inotify_triggered)) + path_unwatch(p); + + if (state != old_state) + log_debug("%s changed %s -> %s", + UNIT(p)->id, + path_state_to_string(old_state), + path_state_to_string(state)); + + unit_notify(UNIT(p), state_translation_table[old_state], state_translation_table[state], true); +} + +static void path_enter_waiting(Path *p, bool initial, bool recheck); + +static int path_coldplug(Unit *u) { + Path *p = PATH(u); + + assert(p); + assert(p->state == PATH_DEAD); + + if (p->deserialized_state != p->state) { + + if (p->deserialized_state == PATH_WAITING || + p->deserialized_state == PATH_RUNNING) + path_enter_waiting(p, true, true); + else + path_set_state(p, p->deserialized_state); + } + + return 0; +} + +static void path_enter_dead(Path *p, PathResult f) { + assert(p); + + if (f != PATH_SUCCESS) + p->result = f; + + path_set_state(p, p->result != PATH_SUCCESS ? PATH_FAILED : PATH_DEAD); +} + +static void path_enter_running(Path *p) { + int r; + DBusError error; + + assert(p); + dbus_error_init(&error); + + /* Don't start job if we are supposed to go down */ + if (UNIT(p)->job && UNIT(p)->job->type == JOB_STOP) + return; + + if ((r = manager_add_job(UNIT(p)->manager, JOB_START, UNIT_DEREF(p->unit), JOB_REPLACE, true, &error, NULL)) < 0) + goto fail; + + p->inotify_triggered = false; + + if ((r = path_watch(p)) < 0) + goto fail; + + path_set_state(p, PATH_RUNNING); + return; + +fail: + log_warning("%s failed to queue unit startup job: %s", UNIT(p)->id, bus_error(&error, r)); + path_enter_dead(p, PATH_FAILURE_RESOURCES); + + dbus_error_free(&error); +} + +static bool path_check_good(Path *p, bool initial) { + PathSpec *s; + bool good = false; + + assert(p); + + LIST_FOREACH(spec, s, p->specs) { + good = path_spec_check_good(s, initial); + + if (good) + break; + } + + return good; +} + +static void path_enter_waiting(Path *p, bool initial, bool recheck) { + int r; + + if (recheck) + if (path_check_good(p, initial)) { + log_debug("%s got triggered.", UNIT(p)->id); + path_enter_running(p); + return; + } + + if ((r = path_watch(p)) < 0) + goto fail; + + /* Hmm, so now we have created inotify watches, but the file + * might have appeared/been removed by now, so we must + * recheck */ + + if (recheck) + if (path_check_good(p, false)) { + log_debug("%s got triggered.", UNIT(p)->id); + path_enter_running(p); + return; + } + + path_set_state(p, PATH_WAITING); + return; + +fail: + log_warning("%s failed to enter waiting state: %s", UNIT(p)->id, strerror(-r)); + path_enter_dead(p, PATH_FAILURE_RESOURCES); +} + +static void path_mkdir(Path *p) { + PathSpec *s; + + assert(p); + + if (!p->make_directory) + return; + + LIST_FOREACH(spec, s, p->specs) + path_spec_mkdir(s, p->directory_mode); +} + +static int path_start(Unit *u) { + Path *p = PATH(u); + + assert(p); + assert(p->state == PATH_DEAD || p->state == PATH_FAILED); + + if (UNIT_DEREF(p->unit)->load_state != UNIT_LOADED) + return -ENOENT; + + path_mkdir(p); + + p->result = PATH_SUCCESS; + path_enter_waiting(p, true, true); + + return 0; +} + +static int path_stop(Unit *u) { + Path *p = PATH(u); + + assert(p); + assert(p->state == PATH_WAITING || p->state == PATH_RUNNING); + + path_enter_dead(p, PATH_SUCCESS); + return 0; +} + +static int path_serialize(Unit *u, FILE *f, FDSet *fds) { + Path *p = PATH(u); + + assert(u); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", path_state_to_string(p->state)); + unit_serialize_item(u, f, "result", path_result_to_string(p->result)); + + return 0; +} + +static int path_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Path *p = PATH(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + PathState state; + + if ((state = path_state_from_string(value)) < 0) + log_debug("Failed to parse state value %s", value); + else + p->deserialized_state = state; + + } else if (streq(key, "result")) { + PathResult f; + + f = path_result_from_string(value); + if (f < 0) + log_debug("Failed to parse result value %s", value); + else if (f != PATH_SUCCESS) + p->result = f; + + } else + log_debug("Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState path_active_state(Unit *u) { + assert(u); + + return state_translation_table[PATH(u)->state]; +} + +static const char *path_sub_state_to_string(Unit *u) { + assert(u); + + return path_state_to_string(PATH(u)->state); +} + +static void path_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { + Path *p = PATH(u); + PathSpec *s; + int changed; + + assert(p); + assert(fd >= 0); + + if (p->state != PATH_WAITING && + p->state != PATH_RUNNING) + return; + + /* log_debug("inotify wakeup on %s.", u->id); */ + + LIST_FOREACH(spec, s, p->specs) + if (path_spec_owns_inotify_fd(s, fd)) + break; + + if (!s) { + log_error("Got event on unknown fd."); + goto fail; + } + + changed = path_spec_fd_event(s, events); + if (changed < 0) + goto fail; + + /* If we are already running, then remember that one event was + * dispatched so that we restart the service only if something + * actually changed on disk */ + p->inotify_triggered = true; + + if (changed) + path_enter_running(p); + else + path_enter_waiting(p, false, true); + + return; + +fail: + path_enter_dead(p, PATH_FAILURE_RESOURCES); +} + +void path_unit_notify(Unit *u, UnitActiveState new_state) { + Iterator i; + Unit *k; + + if (u->type == UNIT_PATH) + return; + + SET_FOREACH(k, u->dependencies[UNIT_TRIGGERED_BY], i) { + Path *p; + + if (k->type != UNIT_PATH) + continue; + + if (k->load_state != UNIT_LOADED) + continue; + + p = PATH(k); + + if (p->state == PATH_RUNNING && new_state == UNIT_INACTIVE) { + log_debug("%s got notified about unit deactivation.", UNIT(p)->id); + + /* Hmm, so inotify was triggered since the + * last activation, so I guess we need to + * recheck what is going on. */ + path_enter_waiting(p, false, p->inotify_triggered); + } + } +} + +static void path_reset_failed(Unit *u) { + Path *p = PATH(u); + + assert(p); + + if (p->state == PATH_FAILED) + path_set_state(p, PATH_DEAD); + + p->result = PATH_SUCCESS; +} + +static const char* const path_state_table[_PATH_STATE_MAX] = { + [PATH_DEAD] = "dead", + [PATH_WAITING] = "waiting", + [PATH_RUNNING] = "running", + [PATH_FAILED] = "failed" +}; + +DEFINE_STRING_TABLE_LOOKUP(path_state, PathState); + +static const char* const path_type_table[_PATH_TYPE_MAX] = { + [PATH_EXISTS] = "PathExists", + [PATH_EXISTS_GLOB] = "PathExistsGlob", + [PATH_CHANGED] = "PathChanged", + [PATH_MODIFIED] = "PathModified", + [PATH_DIRECTORY_NOT_EMPTY] = "DirectoryNotEmpty" +}; + +DEFINE_STRING_TABLE_LOOKUP(path_type, PathType); + +static const char* const path_result_table[_PATH_RESULT_MAX] = { + [PATH_SUCCESS] = "success", + [PATH_FAILURE_RESOURCES] = "resources" +}; + +DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult); + +const UnitVTable path_vtable = { + .suffix = ".path", + .object_size = sizeof(Path), + .sections = + "Unit\0" + "Path\0" + "Install\0", + + .init = path_init, + .done = path_done, + .load = path_load, + + .coldplug = path_coldplug, + + .dump = path_dump, + + .start = path_start, + .stop = path_stop, + + .serialize = path_serialize, + .deserialize_item = path_deserialize_item, + + .active_state = path_active_state, + .sub_state_to_string = path_sub_state_to_string, + + .fd_event = path_fd_event, + + .reset_failed = path_reset_failed, + + .bus_interface = "org.freedesktop.systemd1.Path", + .bus_message_handler = bus_path_message_handler, + .bus_invalidating_properties = bus_path_invalidating_properties +}; diff --git a/src/path.h b/src/path.h new file mode 100644 index 0000000..efb6b5e --- /dev/null +++ b/src/path.h @@ -0,0 +1,113 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foopathhfoo +#define foopathhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct Path Path; + +#include "unit.h" +#include "mount.h" + +typedef enum PathState { + PATH_DEAD, + PATH_WAITING, + PATH_RUNNING, + PATH_FAILED, + _PATH_STATE_MAX, + _PATH_STATE_INVALID = -1 +} PathState; + +typedef enum PathType { + PATH_EXISTS, + PATH_EXISTS_GLOB, + PATH_DIRECTORY_NOT_EMPTY, + PATH_CHANGED, + PATH_MODIFIED, + _PATH_TYPE_MAX, + _PATH_TYPE_INVALID = -1 +} PathType; + +typedef struct PathSpec { + char *path; + + Watch watch; + + LIST_FIELDS(struct PathSpec, spec); + + PathType type; + int inotify_fd; + int primary_wd; + + bool previous_exists; +} PathSpec; + +int path_spec_watch(PathSpec *s, Unit *u); +void path_spec_unwatch(PathSpec *s, Unit *u); +int path_spec_fd_event(PathSpec *s, uint32_t events); +void path_spec_done(PathSpec *s); + +static inline bool path_spec_owns_inotify_fd(PathSpec *s, int fd) { + return s->inotify_fd == fd; +} + +typedef enum PathResult { + PATH_SUCCESS, + PATH_FAILURE_RESOURCES, + _PATH_RESULT_MAX, + _PATH_RESULT_INVALID = -1 +} PathResult; + +struct Path { + Unit meta; + + LIST_HEAD(PathSpec, specs); + + UnitRef unit; + + PathState state, deserialized_state; + + bool inotify_triggered; + + bool make_directory; + mode_t directory_mode; + + PathResult result; +}; + +void path_unit_notify(Unit *u, UnitActiveState new_state); + +/* Called from the mount code figure out if a mount is a dependency of + * any of the paths of this path object */ +int path_add_one_mount_link(Path *p, Mount *m); + +extern const UnitVTable path_vtable; + +const char* path_state_to_string(PathState i); +PathState path_state_from_string(const char *s); + +const char* path_type_to_string(PathType i); +PathType path_type_from_string(const char *s); + +const char* path_result_to_string(PathResult i); +PathResult path_result_from_string(const char *s); + +#endif diff --git a/src/polkit.c b/src/polkit.c new file mode 100644 index 0000000..3acbdc6 --- /dev/null +++ b/src/polkit.c @@ -0,0 +1,205 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include + +#include "util.h" +#include "dbus-common.h" +#include "polkit.h" + +/* This mimics dbus_bus_get_unix_user() */ +static pid_t get_unix_process_id( + DBusConnection *connection, + const char *name, + DBusError *error) { + + DBusMessage *m = NULL, *reply = NULL; + uint32_t pid = 0; + + m = dbus_message_new_method_call( + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetConnectionUnixProcessID"); + if (!m) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL); + goto finish; + } + + if (!dbus_message_append_args( + m, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) { + dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL); + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(connection, m, -1, error); + if (!reply) + goto finish; + + if (dbus_set_error_from_message(error, reply)) + goto finish; + + if (!dbus_message_get_args( + reply, error, + DBUS_TYPE_UINT32, &pid, + DBUS_TYPE_INVALID)) + goto finish; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + return (pid_t) pid; +} + +int verify_polkit( + DBusConnection *c, + DBusMessage *request, + const char *action, + bool interactive, + bool *_challenge, + DBusError *error) { + + DBusMessage *m = NULL, *reply = NULL; + const char *unix_process = "unix-process", *pid = "pid", *starttime = "start-time", *cancel_id = ""; + const char *sender; + uint32_t flags = interactive ? 1 : 0; + pid_t pid_raw; + uint32_t pid_u32; + unsigned long long starttime_raw; + uint64_t starttime_u64; + DBusMessageIter iter_msg, iter_struct, iter_array, iter_dict, iter_variant; + int r; + dbus_bool_t authorized = FALSE, challenge = FALSE; + + assert(c); + assert(request); + + sender = dbus_message_get_sender(request); + if (!sender) + return -EINVAL; + + pid_raw = get_unix_process_id(c, sender, error); + if (pid_raw == 0) + return -EINVAL; + + r = get_starttime_of_pid(pid_raw, &starttime_raw); + if (r < 0) + return r; + + m = dbus_message_new_method_call( + "org.freedesktop.PolicyKit1", + "/org/freedesktop/PolicyKit1/Authority", + "org.freedesktop.PolicyKit1.Authority", + "CheckAuthorization"); + if (!m) + return -ENOMEM; + + dbus_message_iter_init_append(m, &iter_msg); + + pid_u32 = (uint32_t) pid_raw; + starttime_u64 = (uint64_t) starttime_raw; + + if (!dbus_message_iter_open_container(&iter_msg, DBUS_TYPE_STRUCT, NULL, &iter_struct) || + !dbus_message_iter_append_basic(&iter_struct, DBUS_TYPE_STRING, &unix_process) || + !dbus_message_iter_open_container(&iter_struct, DBUS_TYPE_ARRAY, "{sv}", &iter_array) || + !dbus_message_iter_open_container(&iter_array, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict) || + !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &pid) || + !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "u", &iter_variant) || + !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_UINT32, &pid_u32) || + !dbus_message_iter_close_container(&iter_dict, &iter_variant) || + !dbus_message_iter_close_container(&iter_array, &iter_dict) || + !dbus_message_iter_open_container(&iter_array, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict) || + !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &starttime) || + !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "t", &iter_variant) || + !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_UINT64, &starttime_u64) || + !dbus_message_iter_close_container(&iter_dict, &iter_variant) || + !dbus_message_iter_close_container(&iter_array, &iter_dict) || + !dbus_message_iter_close_container(&iter_struct, &iter_array) || + !dbus_message_iter_close_container(&iter_msg, &iter_struct) || + !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_STRING, &action) || + !dbus_message_iter_open_container(&iter_msg, DBUS_TYPE_ARRAY, "{ss}", &iter_array) || + !dbus_message_iter_close_container(&iter_msg, &iter_array) || + !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_UINT32, &flags) || + !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_STRING, &cancel_id)) { + r = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(c, m, -1, error); + if (!reply) { + r = -EIO; + goto finish; + } + + if (dbus_set_error_from_message(error, reply)) { + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter_msg) || + dbus_message_iter_get_arg_type(&iter_msg) != DBUS_TYPE_STRUCT) { + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter_msg, &iter_struct); + + if (dbus_message_iter_get_arg_type(&iter_struct) != DBUS_TYPE_BOOLEAN) { + r = -EIO; + goto finish; + } + + dbus_message_iter_get_basic(&iter_struct, &authorized); + + if (!dbus_message_iter_next(&iter_struct) || + dbus_message_iter_get_arg_type(&iter_struct) != DBUS_TYPE_BOOLEAN) { + r = -EIO; + goto finish; + } + + dbus_message_iter_get_basic(&iter_struct, &challenge); + + if (authorized) + r = 1; + else if (_challenge) { + *_challenge = !!challenge; + r = 0; + } else + r = -EPERM; + +finish: + + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + return r; +} diff --git a/src/polkit.h b/src/polkit.h new file mode 100644 index 0000000..0d08194 --- /dev/null +++ b/src/polkit.h @@ -0,0 +1,36 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foopolkithfoo +#define foopolkithfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +int verify_polkit( + DBusConnection *c, + DBusMessage *request, + const char *action, + bool interactive, + bool *challenge, + DBusError *error); + +#endif diff --git a/src/quotacheck.c b/src/quotacheck.c new file mode 100644 index 0000000..b6648b8 --- /dev/null +++ b/src/quotacheck.c @@ -0,0 +1,120 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "util.h" +#include "virt.h" + +static bool arg_skip = false; +static bool arg_force = false; + +static int parse_proc_cmdline(void) { + char *line, *w, *state; + int r; + size_t l; + + if (detect_container(NULL) > 0) + return 0; + + if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) { + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + return 0; + } + + FOREACH_WORD_QUOTED(w, l, line, state) { + + if (strneq(w, "quotacheck.mode=auto", l)) + arg_force = arg_skip = false; + else if (strneq(w, "quotacheck.mode=force", l)) + arg_force = true; + else if (strneq(w, "quotacheck.mode=skip", l)) + arg_skip = true; + else if (startswith(w, "quotacheck.mode")) + log_warning("Invalid quotacheck.mode= parameter. Ignoring."); +#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA) + else if (strneq(w, "forcequotacheck", l)) + arg_force = true; +#endif + } + + free(line); + return 0; +} + +static void test_files(void) { +#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA) + /* This exists only on Fedora, Mandriva or Mageia */ + if (access("/forcequotacheck", F_OK) >= 0) + arg_force = true; +#endif +} + +int main(int argc, char *argv[]) { + static const char * const cmdline[] = { + "/sbin/quotacheck", + "-anug", + NULL + }; + + int r = EXIT_FAILURE; + pid_t pid; + + if (argc > 1) { + log_error("This program takes no arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + parse_proc_cmdline(); + test_files(); + + if (!arg_force) { + if (arg_skip) + return 0; + + if (access("/run/systemd/quotacheck", F_OK) < 0) + return 0; + } + + if ((pid = fork()) < 0) { + log_error("fork(): %m"); + goto finish; + } else if (pid == 0) { + /* Child */ + execv(cmdline[0], (char**) cmdline); + _exit(1); /* Operational error */ + } + + r = wait_for_terminate_and_warn("quotacheck", pid) == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + +finish: + return r; +} diff --git a/src/random-seed.c b/src/random-seed.c new file mode 100644 index 0000000..8b43bac --- /dev/null +++ b/src/random-seed.c @@ -0,0 +1,147 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" + +#define POOL_SIZE_MIN 512 + +int main(int argc, char *argv[]) { + int seed_fd = -1, random_fd = -1; + int ret = EXIT_FAILURE; + void* buf; + size_t buf_size = 0; + ssize_t r; + FILE *f; + + if (argc != 2) { + log_error("This program requires one argument."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + /* Read pool size, if possible */ + if ((f = fopen("/proc/sys/kernel/random/poolsize", "re"))) { + if (fscanf(f, "%zu", &buf_size) > 0) { + /* poolsize is in bits on 2.6, but we want bytes */ + buf_size /= 8; + } + + fclose(f); + } + + if (buf_size <= POOL_SIZE_MIN) + buf_size = POOL_SIZE_MIN; + + if (!(buf = malloc(buf_size))) { + log_error("Failed to allocate buffer."); + goto finish; + } + + if (mkdir_parents(RANDOM_SEED, 0755) < 0) { + log_error("Failed to create directories parents of %s: %m", RANDOM_SEED); + goto finish; + } + + /* When we load the seed we read it and write it to the device + * and then immediately update the saved seed with new data, + * to make sure the next boot gets seeded differently. */ + + if (streq(argv[1], "load")) { + + if ((seed_fd = open(RANDOM_SEED, O_RDWR|O_CLOEXEC|O_NOCTTY|O_CREAT, 0600)) < 0) { + if ((seed_fd = open(RANDOM_SEED, O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0) { + log_error("Failed to open random seed: %m"); + goto finish; + } + } + + if ((random_fd = open("/dev/urandom", O_RDWR|O_CLOEXEC|O_NOCTTY, 0600)) < 0) { + if ((random_fd = open("/dev/urandom", O_WRONLY|O_CLOEXEC|O_NOCTTY, 0600)) < 0) { + log_error("Failed to open /dev/urandom: %m"); + goto finish; + } + } + + if ((r = loop_read(seed_fd, buf, buf_size, false)) <= 0) { + + if (r != 0) + log_error("Failed to read seed file: %m"); + } else { + lseek(seed_fd, 0, SEEK_SET); + + if ((r = loop_write(random_fd, buf, (size_t) r, false)) <= 0) + log_error("Failed to write seed to /dev/random: %s", r < 0 ? strerror(errno) : "short write"); + } + + } else if (streq(argv[1], "save")) { + + if ((seed_fd = open(RANDOM_SEED, O_WRONLY|O_CLOEXEC|O_NOCTTY|O_CREAT, 0600)) < 0) { + log_error("Failed to open random seed: %m"); + goto finish; + } + + if ((random_fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0) { + log_error("Failed to open /dev/urandom: %m"); + goto finish; + } + } else { + log_error("Unknown verb %s.", argv[1]); + goto finish; + } + + /* This is just a safety measure. Given that we are root and + * most likely created the file ourselves the mode and owner + * should be correct anyway. */ + fchmod(seed_fd, 0600); + fchown(seed_fd, 0, 0); + + if ((r = loop_read(random_fd, buf, buf_size, false)) <= 0) + log_error("Failed to read new seed from /dev/urandom: %s", r < 0 ? strerror(errno) : "EOF"); + else { + if ((r = loop_write(seed_fd, buf, (size_t) r, false)) <= 0) + log_error("Failed to write new random seed file: %s", r < 0 ? strerror(errno) : "short write"); + } + + ret = EXIT_SUCCESS; + +finish: + if (random_fd >= 0) + close_nointr_nofail(random_fd); + + if (seed_fd >= 0) + close_nointr_nofail(seed_fd); + + free(buf); + + return ret; +} diff --git a/src/ratelimit.c b/src/ratelimit.c new file mode 100644 index 0000000..93157c7 --- /dev/null +++ b/src/ratelimit.c @@ -0,0 +1,57 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "ratelimit.h" +#include "log.h" + +/* Modelled after Linux' lib/ratelimit.c by Dave Young + * , which is licensed GPLv2. */ + +bool ratelimit_test(RateLimit *r) { + usec_t ts; + + assert(r); + + if (r->interval <= 0 || r->burst <= 0) + return true; + + ts = now(CLOCK_MONOTONIC); + + if (r->begin <= 0 || + r->begin + r->interval < ts) { + r->begin = ts; + + /* Reset counter */ + r->num = 0; + goto good; + } + + if (r->num <= r->burst) + goto good; + + return false; + +good: + r->num++; + return true; +} diff --git a/src/ratelimit.h b/src/ratelimit.h new file mode 100644 index 0000000..a6443e7 --- /dev/null +++ b/src/ratelimit.h @@ -0,0 +1,53 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooratelimithfoo +#define fooratelimithfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "util.h" + +typedef struct RateLimit { + usec_t interval; + usec_t begin; + unsigned burst; + unsigned num; +} RateLimit; + +#define RATELIMIT_DEFINE(_name, _interval, _burst) \ + RateLimit _name = { \ + .interval = (_interval), \ + .burst = (_burst), \ + .num = 0, \ + .begin = 0 \ + } + +#define RATELIMIT_INIT(v, _interval, _burst) \ + do { \ + RateLimit *_r = &(v); \ + _r->interval = (_interval); \ + _r->burst = (_burst); \ + _r->num = 0; \ + _r->begin = 0; \ + } while (false) + +bool ratelimit_test(RateLimit *r); + +#endif diff --git a/src/rc-local-generator.c b/src/rc-local-generator.c new file mode 100644 index 0000000..56785cf --- /dev/null +++ b/src/rc-local-generator.c @@ -0,0 +1,107 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + Copyright 2011 Michal Schmidt + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "log.h" +#include "util.h" + +#if defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA) +#define SCRIPT_PATH "/etc/rc.d/rc.local" +#elif defined(TARGET_SUSE) +#define SCRIPT_PATH "/etc/init.d/boot.local" +#endif + +const char *arg_dest = "/tmp"; + +static int add_symlink(const char *service) { + char *from = NULL, *to = NULL; + int r; + + assert(service); + + asprintf(&from, SYSTEM_DATA_UNIT_PATH "/%s", service); + asprintf(&to, "%s/multi-user.target.wants/%s", arg_dest, service); + + if (!from || !to) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + mkdir_parents(to, 0755); + + r = symlink(from, to); + if (r < 0) { + if (errno == EEXIST) + r = 0; + else { + log_error("Failed to create symlink from %s to %s: %m", from, to); + r = -errno; + } + } + +finish: + + free(from); + free(to); + + return r; +} + +static bool file_is_executable(const char *f) { + struct stat st; + + if (stat(f, &st) < 0) + return false; + + return S_ISREG(st.st_mode) && (st.st_mode & 0111); +} + +int main(int argc, char *argv[]) { + + int r = EXIT_SUCCESS; + + if (argc > 2) { + log_error("This program takes one or no arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + if (argc > 1) + arg_dest = argv[1]; + + if (file_is_executable(SCRIPT_PATH)) { + log_debug("Automatically adding rc-local.service."); + + if (add_symlink("rc-local.service") < 0) + r = EXIT_FAILURE; + + } + + return r; +} diff --git a/src/readahead/readahead-collect.c b/src/readahead/readahead-collect.c new file mode 100644 index 0000000..7e6c243 --- /dev/null +++ b/src/readahead/readahead-collect.c @@ -0,0 +1,693 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "missing.h" +#include "util.h" +#include "set.h" +#include "ioprio.h" +#include "readahead-common.h" +#include "virt.h" + +/* fixme: + * + * - detect ssd on btrfs/lvm... + * - read ahead directories + * - gzip? + * - remount rw? + * - handle files where nothing is in mincore + * - does ioprio_set work with fadvise()? + */ + +static unsigned arg_files_max = 16*1024; +static off_t arg_file_size_max = READAHEAD_FILE_SIZE_MAX; +static usec_t arg_timeout = 2*USEC_PER_MINUTE; + +static ReadaheadShared *shared = NULL; + +/* Avoid collisions with the NULL pointer */ +#define SECTOR_TO_PTR(s) ULONG_TO_PTR((s)+1) +#define PTR_TO_SECTOR(p) (PTR_TO_ULONG(p)-1) + +static int btrfs_defrag(int fd) { + struct btrfs_ioctl_vol_args data; + + zero(data); + data.fd = fd; + + return ioctl(fd, BTRFS_IOC_DEFRAG, &data); +} + +static int pack_file(FILE *pack, const char *fn, bool on_btrfs) { + struct stat st; + void *start = MAP_FAILED; + uint8_t *vec; + uint32_t b, c; + size_t l, pages; + bool mapped; + int r = 0, fd = -1, k; + + assert(pack); + assert(fn); + + if ((fd = open(fn, O_RDONLY|O_CLOEXEC|O_NOATIME|O_NOCTTY|O_NOFOLLOW)) < 0) { + + if (errno == ENOENT) + return 0; + + if (errno == EPERM || errno == EACCES) + return 0; + + log_warning("open(%s) failed: %m", fn); + r = -errno; + goto finish; + } + + if ((k = file_verify(fd, fn, arg_file_size_max, &st)) <= 0) { + r = k; + goto finish; + } + + if (on_btrfs) + btrfs_defrag(fd); + + l = PAGE_ALIGN(st.st_size); + if ((start = mmap(NULL, l, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { + log_warning("mmap(%s) failed: %m", fn); + r = -errno; + goto finish; + } + + pages = l / page_size(); + + vec = alloca(pages); + memset(vec, 0, pages); + if (mincore(start, l, vec) < 0) { + log_warning("mincore(%s) failed: %m", fn); + r = -errno; + goto finish; + } + + fputs(fn, pack); + fputc('\n', pack); + + mapped = false; + for (c = 0; c < pages; c++) { + bool new_mapped = !!(vec[c] & 1); + + if (!mapped && new_mapped) + b = c; + else if (mapped && !new_mapped) { + fwrite(&b, sizeof(b), 1, pack); + fwrite(&c, sizeof(c), 1, pack); + + log_debug("%s: page %u to %u", fn, b, c); + } + + mapped = new_mapped; + } + + /* We don't write any range data if we should read the entire file */ + if (mapped && b > 0) { + fwrite(&b, sizeof(b), 1, pack); + fwrite(&c, sizeof(c), 1, pack); + + log_debug("%s: page %u to %u", fn, b, c); + } + + /* End marker */ + b = 0; + fwrite(&b, sizeof(b), 1, pack); + fwrite(&b, sizeof(b), 1, pack); + +finish: + if (start != MAP_FAILED) + munmap(start, l); + + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +static unsigned long fd_first_block(int fd) { + struct { + struct fiemap fiemap; + struct fiemap_extent extent; + } data; + + zero(data); + data.fiemap.fm_length = ~0ULL; + data.fiemap.fm_extent_count = 1; + + if (ioctl(fd, FS_IOC_FIEMAP, &data) < 0) + return 0; + + if (data.fiemap.fm_mapped_extents <= 0) + return 0; + + if (data.fiemap.fm_extents[0].fe_flags & FIEMAP_EXTENT_UNKNOWN) + return 0; + + return (unsigned long) data.fiemap.fm_extents[0].fe_physical; +} + +struct item { + const char *path; + unsigned long block; +}; + +static int qsort_compare(const void *a, const void *b) { + const struct item *i, *j; + + i = a; + j = b; + + if (i->block < j->block) + return -1; + if (i->block > j->block) + return 1; + + return strcmp(i->path, j->path); +} + +static int collect(const char *root) { + enum { + FD_FANOTIFY, /* Get the actual fs events */ + FD_SIGNAL, + FD_INOTIFY, /* We get notifications to quit early via this fd */ + _FD_MAX + }; + struct pollfd pollfd[_FD_MAX]; + int fanotify_fd = -1, signal_fd = -1, inotify_fd = -1, r = 0; + pid_t my_pid; + Hashmap *files = NULL; + Iterator i; + char *p, *q; + sigset_t mask; + FILE *pack = NULL; + char *pack_fn_new = NULL, *pack_fn = NULL; + bool on_ssd, on_btrfs; + struct statfs sfs; + usec_t not_after; + + assert(root); + + write_one_line_file("/proc/self/oom_score_adj", "1000"); + + if (ioprio_set(IOPRIO_WHO_PROCESS, getpid(), IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0)) < 0) + log_warning("Failed to set IDLE IO priority class: %m"); + + assert_se(sigemptyset(&mask) == 0); + sigset_add_many(&mask, SIGINT, SIGTERM, -1); + assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); + + if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) { + log_error("signalfd(): %m"); + r = -errno; + goto finish; + } + + if (!(files = hashmap_new(string_hash_func, string_compare_func))) { + log_error("Failed to allocate set."); + r = -ENOMEM; + goto finish; + } + + if ((fanotify_fd = fanotify_init(FAN_CLOEXEC|FAN_NONBLOCK, O_RDONLY|O_LARGEFILE|O_CLOEXEC|O_NOATIME)) < 0) { + log_error("Failed to create fanotify object: %m"); + r = -errno; + goto finish; + } + + if (fanotify_mark(fanotify_fd, FAN_MARK_ADD|FAN_MARK_MOUNT, FAN_OPEN, AT_FDCWD, root) < 0) { + log_error("Failed to mark %s: %m", root); + r = -errno; + goto finish; + } + + if ((inotify_fd = open_inotify()) < 0) { + r = inotify_fd; + goto finish; + } + + not_after = now(CLOCK_MONOTONIC) + arg_timeout; + + my_pid = getpid(); + + zero(pollfd); + pollfd[FD_FANOTIFY].fd = fanotify_fd; + pollfd[FD_FANOTIFY].events = POLLIN; + pollfd[FD_SIGNAL].fd = signal_fd; + pollfd[FD_SIGNAL].events = POLLIN; + pollfd[FD_INOTIFY].fd = inotify_fd; + pollfd[FD_INOTIFY].events = POLLIN; + + sd_notify(0, + "READY=1\n" + "STATUS=Collecting readahead data"); + + log_debug("Collecting..."); + + if (access("/run/systemd/readahead/cancel", F_OK) >= 0) { + log_debug("Collection canceled"); + r = -ECANCELED; + goto finish; + } + + if (access("/run/systemd/readahead/done", F_OK) >= 0) { + log_debug("Got termination request"); + goto done; + } + + for (;;) { + union { + struct fanotify_event_metadata metadata; + char buffer[4096]; + } data; + ssize_t n; + struct fanotify_event_metadata *m; + usec_t t; + int h; + + if (hashmap_size(files) > arg_files_max) { + log_debug("Reached maximum number of read ahead files, ending collection."); + break; + } + + t = now(CLOCK_MONOTONIC); + if (t >= not_after) { + log_debug("Reached maximum collection time, ending collection."); + break; + } + + if ((h = poll(pollfd, _FD_MAX, (int) ((not_after - t) / USEC_PER_MSEC))) < 0) { + + if (errno == EINTR) + continue; + + log_error("poll(): %m"); + r = -errno; + goto finish; + } + + if (h == 0) { + log_debug("Reached maximum collection time, ending collection."); + break; + } + + if (pollfd[FD_SIGNAL].revents) { + log_debug("Got signal."); + break; + } + + if (pollfd[FD_INOTIFY].revents) { + uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX]; + struct inotify_event *e; + + if ((n = read(inotify_fd, &inotify_buffer, sizeof(inotify_buffer))) < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + + log_error("Failed to read inotify event: %m"); + r = -errno; + goto finish; + } + + e = (struct inotify_event*) inotify_buffer; + while (n > 0) { + size_t step; + + if ((e->mask & IN_CREATE) && streq(e->name, "cancel")) { + log_debug("Collection canceled"); + r = -ECANCELED; + goto finish; + } + + if ((e->mask & IN_CREATE) && streq(e->name, "done")) { + log_debug("Got termination request"); + goto done; + } + + step = sizeof(struct inotify_event) + e->len; + assert(step <= (size_t) n); + + e = (struct inotify_event*) ((uint8_t*) e + step); + n -= step; + } + } + + if ((n = read(fanotify_fd, &data, sizeof(data))) < 0) { + + if (errno == EINTR || errno == EAGAIN) + continue; + + /* fanotify sometimes returns EACCES on read() + * where it shouldn't. For now let's just + * ignore it here (which is safe), but + * eventually this should be + * dropped when the kernel is fixed. + * + * https://bugzilla.redhat.com/show_bug.cgi?id=707577 */ + if (errno == EACCES) + continue; + + log_error("Failed to read event: %m"); + r = -errno; + goto finish; + } + + for (m = &data.metadata; FAN_EVENT_OK(m, n); m = FAN_EVENT_NEXT(m, n)) { + char fn[PATH_MAX]; + int k; + + if (m->fd < 0) + goto next_iteration; + + if (m->pid == my_pid) + goto next_iteration; + + __sync_synchronize(); + if (m->pid == shared->replay) + goto next_iteration; + + snprintf(fn, sizeof(fn), "/proc/self/fd/%i", m->fd); + char_array_0(fn); + + if ((k = readlink_malloc(fn, &p)) >= 0) { + if (startswith(p, "/tmp") || + endswith(p, " (deleted)") || + hashmap_get(files, p)) + /* Not interesting, or + * already read */ + free(p); + else { + unsigned long ul; + + ul = fd_first_block(m->fd); + + if ((k = hashmap_put(files, p, SECTOR_TO_PTR(ul))) < 0) { + log_warning("set_put() failed: %s", strerror(-k)); + free(p); + } + } + + } else + log_warning("readlink(%s) failed: %s", fn, strerror(-k)); + + next_iteration: + if (m->fd) + close_nointr_nofail(m->fd); + } + } + +done: + if (fanotify_fd >= 0) { + close_nointr_nofail(fanotify_fd); + fanotify_fd = -1; + } + + log_debug("Writing Pack File..."); + + on_ssd = fs_on_ssd(root) > 0; + log_debug("On SSD: %s", yes_no(on_ssd)); + + on_btrfs = statfs(root, &sfs) >= 0 && (long) sfs.f_type == (long) BTRFS_SUPER_MAGIC; + log_debug("On btrfs: %s", yes_no(on_btrfs)); + + asprintf(&pack_fn, "%s/.readahead", root); + asprintf(&pack_fn_new, "%s/.readahead.new", root); + + if (!pack_fn || !pack_fn_new) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + if (!(pack = fopen(pack_fn_new, "we"))) { + log_error("Failed to open pack file: %m"); + r = -errno; + goto finish; + } + + fputs(CANONICAL_HOST "\n", pack); + putc(on_ssd ? 'S' : 'R', pack); + + if (on_ssd || on_btrfs) { + + /* On SSD or on btrfs, just write things out in the + * order the files were accessed. */ + + HASHMAP_FOREACH_KEY(q, p, files, i) + pack_file(pack, p, on_btrfs); + } else { + struct item *ordered, *j; + unsigned k, n; + + /* On rotating media, order things by the block + * numbers */ + + log_debug("Ordering..."); + + n = hashmap_size(files); + if (!(ordered = new(struct item, n))) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + j = ordered; + HASHMAP_FOREACH_KEY(q, p, files, i) { + j->path = p; + j->block = PTR_TO_SECTOR(q); + j++; + } + + assert(ordered + n == j); + + qsort(ordered, n, sizeof(struct item), qsort_compare); + + for (k = 0; k < n; k++) + pack_file(pack, ordered[k].path, on_btrfs); + + free(ordered); + } + + log_debug("Finalizing..."); + + fflush(pack); + + if (ferror(pack)) { + log_error("Failed to write pack file."); + r = -EIO; + goto finish; + } + + if (rename(pack_fn_new, pack_fn) < 0) { + log_error("Failed to rename readahead file: %m"); + r = -errno; + goto finish; + } + + fclose(pack); + pack = NULL; + + log_debug("Done."); + +finish: + if (fanotify_fd >= 0) + close_nointr_nofail(fanotify_fd); + + if (signal_fd >= 0) + close_nointr_nofail(signal_fd); + + if (inotify_fd >= 0) + close_nointr_nofail(inotify_fd); + + if (pack) { + fclose(pack); + unlink(pack_fn_new); + } + + free(pack_fn_new); + free(pack_fn); + + while ((p = hashmap_steal_first_key(files))) + free(p); + + hashmap_free(files); + + return r; +} + +static int help(void) { + + printf("%s [OPTIONS...] [DIRECTORY]\n\n" + "Collect read-ahead data on early boot.\n\n" + " -h --help Show this help\n" + " --max-files=INT Maximum number of files to read ahead\n" + " --max-file-size=BYTES Maximum size of files to read ahead\n" + " --timeout=USEC Maximum time to spend collecting data\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_FILES_MAX = 0x100, + ARG_FILE_SIZE_MAX, + ARG_TIMEOUT + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "files-max", required_argument, NULL, ARG_FILES_MAX }, + { "file-size-max", required_argument, NULL, ARG_FILE_SIZE_MAX }, + { "timeout", required_argument, NULL, ARG_TIMEOUT }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_FILES_MAX: + if (safe_atou(optarg, &arg_files_max) < 0 || arg_files_max <= 0) { + log_error("Failed to parse maximum number of files %s.", optarg); + return -EINVAL; + } + break; + + case ARG_FILE_SIZE_MAX: { + unsigned long long ull; + + if (safe_atollu(optarg, &ull) < 0 || ull <= 0) { + log_error("Failed to parse maximum file size %s.", optarg); + return -EINVAL; + } + + arg_file_size_max = (off_t) ull; + break; + } + + case ARG_TIMEOUT: + if (parse_usec(optarg, &arg_timeout) < 0 || arg_timeout <= 0) { + log_error("Failed to parse timeout %s.", optarg); + return -EINVAL; + } + + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind != argc && + optind != argc-1) { + help(); + return -EINVAL; + } + + return 1; +} + +int main(int argc, char *argv[]) { + int r; + const char *root; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if ((r = parse_argv(argc, argv)) <= 0) + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + + root = optind < argc ? argv[optind] : "/"; + + if (fs_on_read_only(root) > 0) { + log_info("Disabling readahead collector due to read-only media."); + return 0; + } + + if (!enough_ram()) { + log_info("Disabling readahead collector due to low memory."); + return 0; + } + + if (detect_virtualization(NULL) > 0) { + log_info("Disabling readahead collector due to execution in virtualized environment."); + return 0; + } + + if (!(shared = shared_get())) + return 1; + + shared->collect = getpid(); + __sync_synchronize(); + + if (collect(root) < 0) + return 1; + + return 0; +} diff --git a/src/readahead/readahead-common.c b/src/readahead/readahead-common.c new file mode 100644 index 0000000..67214ec --- /dev/null +++ b/src/readahead/readahead-common.c @@ -0,0 +1,269 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "readahead-common.h" +#include "util.h" + +int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st) { + assert(fd >= 0); + assert(fn); + assert(st); + + if (fstat(fd, st) < 0) { + log_warning("fstat(%s) failed: %m", fn); + return -errno; + } + + if (!S_ISREG(st->st_mode)) { + log_debug("Not preloading special file %s", fn); + return 0; + } + + if (st->st_size <= 0 || st->st_size > file_size_max) { + log_debug("Not preloading file %s with size out of bounds %llu", fn, (unsigned long long) st->st_size); + return 0; + } + + return 1; +} + +int fs_on_ssd(const char *p) { + struct stat st; + struct udev *udev = NULL; + struct udev_device *udev_device = NULL, *look_at = NULL; + bool b = false; + const char *devtype, *rotational, *model, *id; + + assert(p); + + if (stat(p, &st) < 0) + return -errno; + + if (major(st.st_dev) == 0) + return false; + + if (!(udev = udev_new())) + return -ENOMEM; + + if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev))) + goto finish; + + if ((devtype = udev_device_get_property_value(udev_device, "DEVTYPE")) && + streq(devtype, "partition")) + look_at = udev_device_get_parent(udev_device); + else + look_at = udev_device; + + if (!look_at) + goto finish; + + /* First, try high-level property */ + if ((id = udev_device_get_property_value(look_at, "ID_SSD"))) { + b = streq(id, "1"); + goto finish; + } + + /* Second, try kernel attribute */ + if ((rotational = udev_device_get_sysattr_value(look_at, "queue/rotational"))) + if ((b = streq(rotational, "0"))) + goto finish; + + /* Finally, fallback to heuristics */ + if (!(look_at = udev_device_get_parent(look_at))) + goto finish; + + if ((model = udev_device_get_sysattr_value(look_at, "model"))) + b = !!strstr(model, "SSD"); + +finish: + if (udev_device) + udev_device_unref(udev_device); + + if (udev) + udev_unref(udev); + + return b; +} + +int fs_on_read_only(const char *p) { + struct stat st; + struct udev *udev = NULL; + struct udev_device *udev_device = NULL; + bool b = false; + const char *read_only; + + assert(p); + + if (stat(p, &st) < 0) + return -errno; + + if (major(st.st_dev) == 0) + return false; + + if (!(udev = udev_new())) + return -ENOMEM; + + if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev))) + goto finish; + + if ((read_only = udev_device_get_sysattr_value(udev_device, "ro"))) + if ((b = streq(read_only, "1"))) + goto finish; + +finish: + if (udev_device) + udev_device_unref(udev_device); + + if (udev) + udev_unref(udev); + + return b; +} + +bool enough_ram(void) { + struct sysinfo si; + + assert_se(sysinfo(&si) >= 0); + + /* Enable readahead only with at least 128MB memory */ + return si.totalram > 127 * 1024*1024 / si.mem_unit; +} + +int open_inotify(void) { + int fd; + + if ((fd = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) { + log_error("Failed to create inotify handle: %m"); + return -errno; + } + + mkdir("/run/systemd", 0755); + mkdir("/run/systemd/readahead", 0755); + + if (inotify_add_watch(fd, "/run/systemd/readahead", IN_CREATE) < 0) { + log_error("Failed to watch /run/systemd/readahead: %m"); + close_nointr_nofail(fd); + return -errno; + } + + return fd; +} + +ReadaheadShared *shared_get(void) { + int fd; + ReadaheadShared *m = NULL; + + mkdir("/run/systemd", 0755); + mkdir("/run/systemd/readahead", 0755); + + if ((fd = open("/run/systemd/readahead/shared", O_CREAT|O_RDWR|O_CLOEXEC, 0644)) < 0) { + log_error("Failed to create shared memory segment: %m"); + goto finish; + } + + if (ftruncate(fd, sizeof(ReadaheadShared)) < 0) { + log_error("Failed to truncate shared memory segment: %m"); + goto finish; + } + + if ((m = mmap(NULL, sizeof(ReadaheadShared), PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { + log_error("Failed to mmap shared memory segment: %m"); + m = NULL; + goto finish; + } + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + return m; +} + +#define BUMP_REQUEST_NR (16*1024) + +int bump_request_nr(const char *p) { + struct stat st; + uint64_t u; + char *ap = NULL, *line = NULL; + int r; + dev_t d; + + assert(p); + + if (stat(p, &st) < 0) + return -errno; + + if (major(st.st_dev) == 0) + return 0; + + d = st.st_dev; + block_get_whole_disk(d, &d); + + if (asprintf(&ap, "/sys/dev/block/%u:%u/queue/nr_requests", major(d), minor(d)) < 0) { + r= -ENOMEM; + goto finish; + } + + r = read_one_line_file(ap, &line); + if (r < 0) { + if (r == -ENOENT) + r = 0; + goto finish; + } + + r = safe_atou64(line, &u); + if (r >= 0 && u >= BUMP_REQUEST_NR) { + r = 0; + goto finish; + } + + free(line); + line = NULL; + + if (asprintf(&line, "%lu", (unsigned long) BUMP_REQUEST_NR) < 0) { + r = -ENOMEM; + goto finish; + } + + r = write_one_line_file(ap, line); + if (r < 0) + goto finish; + + log_info("Bumped block_nr parameter of %u:%u to %lu. This is a temporary hack and should be removed one day.", major(d), minor(d), (unsigned long) BUMP_REQUEST_NR); + r = 1; + +finish: + free(ap); + free(line); + + return r; +} diff --git a/src/readahead/readahead-common.h b/src/readahead/readahead-common.h new file mode 100644 index 0000000..9547ad2 --- /dev/null +++ b/src/readahead/readahead-common.h @@ -0,0 +1,50 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooreadaheadcommonhfoo +#define fooreadaheadcommonhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "macro.h" + +#define READAHEAD_FILE_SIZE_MAX (10*1024*1024) + +int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st); + +int fs_on_ssd(const char *p); +int fs_on_read_only(const char *p); + +bool enough_ram(void); + +int open_inotify(void); + +typedef struct ReadaheadShared { + pid_t collect; + pid_t replay; +} _packed_ ReadaheadShared; + +ReadaheadShared *shared_get(void); + +int bump_request_nr(const char *p); + +#endif diff --git a/src/readahead/readahead-replay.c b/src/readahead/readahead-replay.c new file mode 100644 index 0000000..0c739c8 --- /dev/null +++ b/src/readahead/readahead-replay.c @@ -0,0 +1,378 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "missing.h" +#include "util.h" +#include "set.h" +#include "ioprio.h" +#include "readahead-common.h" +#include "virt.h" + +static off_t arg_file_size_max = READAHEAD_FILE_SIZE_MAX; + +static ReadaheadShared *shared = NULL; + +static int unpack_file(FILE *pack) { + char fn[PATH_MAX]; + int r = 0, fd = -1; + bool any = false; + struct stat st; + + assert(pack); + + if (!fgets(fn, sizeof(fn), pack)) + return 0; + + char_array_0(fn); + truncate_nl(fn); + + if ((fd = open(fn, O_RDONLY|O_CLOEXEC|O_NOATIME|O_NOCTTY|O_NOFOLLOW)) < 0) { + + if (errno != ENOENT && errno != EPERM && errno != EACCES) + log_warning("open(%s) failed: %m", fn); + + } else if (file_verify(fd, fn, arg_file_size_max, &st) <= 0) { + close_nointr_nofail(fd); + fd = -1; + } + + for (;;) { + uint32_t b, c; + + if (fread(&b, sizeof(b), 1, pack) != 1 || + fread(&c, sizeof(c), 1, pack) != 1) { + log_error("Premature end of pack file."); + r = -EIO; + goto finish; + } + + if (b == 0 && c == 0) + break; + + if (c <= b) { + log_error("Invalid pack file."); + r = -EIO; + goto finish; + } + + log_debug("%s: page %u to %u", fn, b, c); + + any = true; + + if (fd >= 0) + if (posix_fadvise(fd, b * page_size(), (c - b) * page_size(), POSIX_FADV_WILLNEED) < 0) { + log_warning("posix_fadvise() failed: %m"); + goto finish; + } + } + + if (!any && fd >= 0) { + /* if no range is encoded in the pack file this is + * intended to mean that the whole file shall be + * read */ + + if (posix_fadvise(fd, 0, st.st_size, POSIX_FADV_WILLNEED) < 0) { + log_warning("posix_fadvise() failed: %m"); + goto finish; + } + } + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +static int replay(const char *root) { + FILE *pack = NULL; + char line[LINE_MAX]; + int r = 0; + char *pack_fn = NULL; + int c; + bool on_ssd, ready = false; + int prio; + int inotify_fd = -1; + + assert(root); + + write_one_line_file("/proc/self/oom_score_adj", "1000"); + bump_request_nr(root); + + if (asprintf(&pack_fn, "%s/.readahead", root) < 0) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + if ((!(pack = fopen(pack_fn, "re")))) { + if (errno == ENOENT) + log_debug("No pack file found."); + else { + log_error("Failed to open pack file: %m"); + r = -errno; + } + + goto finish; + } + + posix_fadvise(fileno(pack), 0, 0, POSIX_FADV_WILLNEED); + + if ((inotify_fd = open_inotify()) < 0) { + r = inotify_fd; + goto finish; + } + + if (!(fgets(line, sizeof(line), pack))) { + log_error("Premature end of pack file."); + r = -EIO; + goto finish; + } + + char_array_0(line); + + if (!streq(line, CANONICAL_HOST "\n")) { + log_debug("Pack file host type mismatch."); + goto finish; + } + + if ((c = getc(pack)) == EOF) { + log_debug("Premature end of pack file."); + r = -EIO; + goto finish; + } + + /* We do not retest SSD here, so that we can start replaying + * before udev is up.*/ + on_ssd = c == 'S'; + log_debug("On SSD: %s", yes_no(on_ssd)); + + if (on_ssd) + prio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0); + else + /* We are not using RT here, since we'd starve IO that + we didn't record (which is for example blkid, since + its disk accesses go directly to the block device and + are thus not visible in fallocate) to death. However, + we do ask for an IO prio that is slightly higher than + the default (which is BE. 4) */ + prio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 2); + + if (ioprio_set(IOPRIO_WHO_PROCESS, getpid(), prio) < 0) + log_warning("Failed to set IDLE IO priority class: %m"); + + sd_notify(0, "STATUS=Replaying readahead data"); + + log_debug("Replaying..."); + + if (access("/run/systemd/readahead/noreplay", F_OK) >= 0) { + log_debug("Got termination request"); + goto done; + } + + while (!feof(pack) && !ferror(pack)) { + uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX]; + int k; + ssize_t n; + + if ((n = read(inotify_fd, &inotify_buffer, sizeof(inotify_buffer))) < 0) { + if (errno != EINTR && errno != EAGAIN) { + log_error("Failed to read inotify event: %m"); + r = -errno; + goto finish; + } + } else { + struct inotify_event *e = (struct inotify_event*) inotify_buffer; + + while (n > 0) { + size_t step; + + if ((e->mask & IN_CREATE) && streq(e->name, "noreplay")) { + log_debug("Got termination request"); + goto done; + } + + step = sizeof(struct inotify_event) + e->len; + assert(step <= (size_t) n); + + e = (struct inotify_event*) ((uint8_t*) e + step); + n -= step; + } + } + + if ((k = unpack_file(pack)) < 0) { + r = k; + goto finish; + } + + if (!ready) { + /* We delay the ready notification until we + * queued at least one read */ + sd_notify(0, "READY=1"); + ready = true; + } + } + +done: + if (!ready) + sd_notify(0, "READY=1"); + + if (ferror(pack)) { + log_error("Failed to read pack file."); + r = -EIO; + goto finish; + } + + log_debug("Done."); + +finish: + if (pack) + fclose(pack); + + if (inotify_fd >= 0) + close_nointr_nofail(inotify_fd); + + free(pack_fn); + + return r; +} + + +static int help(void) { + + printf("%s [OPTIONS...] [DIRECTORY]\n\n" + "Replay collected read-ahead data on early boot.\n\n" + " -h --help Show this help\n" + " --max-file-size=BYTES Maximum size of files to read ahead\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_FILE_SIZE_MAX + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "file-size-max", required_argument, NULL, ARG_FILE_SIZE_MAX }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_FILE_SIZE_MAX: { + unsigned long long ull; + + if (safe_atollu(optarg, &ull) < 0 || ull <= 0) { + log_error("Failed to parse maximum file size %s.", optarg); + return -EINVAL; + } + + arg_file_size_max = (off_t) ull; + break; + } + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind != argc && + optind != argc-1) { + help(); + return -EINVAL; + } + + return 1; +} + +int main(int argc, char*argv[]) { + int r; + const char *root; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if ((r = parse_argv(argc, argv)) <= 0) + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + + root = optind < argc ? argv[optind] : "/"; + + if (!enough_ram()) { + log_info("Disabling readahead replay due to low memory."); + return 0; + } + + if (detect_virtualization(NULL) > 0) { + log_info("Disabling readahead replay due to execution in virtualized environment."); + return 0; + } + + if (!(shared = shared_get())) + return 1; + + shared->replay = getpid(); + __sync_synchronize(); + + if (replay(root) < 0) + return 1; + + return 0; +} diff --git a/src/readahead/sd-readahead.c b/src/readahead/sd-readahead.c new file mode 100644 index 0000000..a334066 --- /dev/null +++ b/src/readahead/sd-readahead.c @@ -0,0 +1,88 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + Copyright 2010 Lennart Poettering + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include + +#include "sd-readahead.h" + +#if (__GNUC__ >= 4) +#ifdef SD_EXPORT_SYMBOLS +/* Export symbols */ +#define _sd_export_ __attribute__ ((visibility("default"))) +#else +/* Don't export the symbols */ +#define _sd_export_ __attribute__ ((visibility("hidden"))) +#endif +#else +#define _sd_export_ +#endif + +static int touch(const char *path) { + +#if !defined(DISABLE_SYSTEMD) && defined(__linux__) + int fd; + + mkdir("/run/systemd", 0755); + mkdir("/run/systemd/readahead", 0755); + + if ((fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0666)) < 0) + return -errno; + + for (;;) { + if (close(fd) >= 0) + break; + + if (errno != -EINTR) + return -errno; + } + +#endif + return 0; +} + +_sd_export_ int sd_readahead(const char *action) { + + if (!action) + return -EINVAL; + + if (strcmp(action, "cancel") == 0) + return touch("/run/systemd/readahead/cancel"); + else if (strcmp(action, "done") == 0) + return touch("/run/systemd/readahead/done"); + else if (strcmp(action, "noreplay") == 0) + return touch("/run/systemd/readahead/noreplay"); + + return -EINVAL; +} diff --git a/src/remount-api-vfs.c b/src/remount-api-vfs.c new file mode 100644 index 0000000..3e146eb --- /dev/null +++ b/src/remount-api-vfs.c @@ -0,0 +1,161 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "set.h" +#include "mount-setup.h" +#include "exit-status.h" + +/* Goes through /etc/fstab and remounts all API file systems, applying + * options that are in /etc/fstab that systemd might not have + * respected */ + +int main(int argc, char *argv[]) { + int ret = EXIT_FAILURE; + FILE *f = NULL; + struct mntent* me; + Hashmap *pids = NULL; + + if (argc > 1) { + log_error("This program takes no argument."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + f = setmntent("/etc/fstab", "r"); + if (!f) { + log_error("Failed to open /etc/fstab: %m"); + goto finish; + } + + pids = hashmap_new(trivial_hash_func, trivial_compare_func); + if (!pids) { + log_error("Failed to allocate set"); + goto finish; + } + + ret = EXIT_SUCCESS; + + while ((me = getmntent(f))) { + pid_t pid; + int k; + char *s; + + if (!mount_point_is_api(me->mnt_dir)) + continue; + + log_debug("Remounting %s", me->mnt_dir); + + pid = fork(); + if (pid < 0) { + log_error("Failed to fork: %m"); + ret = EXIT_FAILURE; + continue; + } + + if (pid == 0) { + const char *arguments[5]; + /* Child */ + + arguments[0] = "/bin/mount"; + arguments[1] = me->mnt_dir; + arguments[2] = "-o"; + arguments[3] = "remount"; + arguments[4] = NULL; + + execv("/bin/mount", (char **) arguments); + + log_error("Failed to execute /bin/mount: %m"); + _exit(EXIT_FAILURE); + } + + /* Parent */ + + s = strdup(me->mnt_dir); + if (!s) { + log_error("Out of memory."); + ret = EXIT_FAILURE; + continue; + } + + + k = hashmap_put(pids, UINT_TO_PTR(pid), s); + if (k < 0) { + log_error("Failed to add PID to set: %s", strerror(-k)); + ret = EXIT_FAILURE; + continue; + } + } + + while (!hashmap_isempty(pids)) { + siginfo_t si; + char *s; + + zero(si); + if (waitid(P_ALL, 0, &si, WEXITED) < 0) { + + if (errno == EINTR) + continue; + + log_error("waitid() failed: %m"); + ret = EXIT_FAILURE; + break; + } + + s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)); + if (s) { + if (!is_clean_exit(si.si_code, si.si_status)) { + if (si.si_code == CLD_EXITED) + log_error("/bin/mount for %s exited with exit status %i.", s, si.si_status); + else + log_error("/bin/mount for %s terminated by signal %s.", s, signal_to_string(si.si_status)); + + ret = EXIT_FAILURE; + } + + free(s); + } + } + +finish: + + if (pids) + hashmap_free_free(pids); + + if (f) + endmntent(f); + + return ret; +} diff --git a/src/reply-password.c b/src/reply-password.c new file mode 100644 index 0000000..3a96049 --- /dev/null +++ b/src/reply-password.c @@ -0,0 +1,109 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "macro.h" +#include "util.h" + +static int send_on_socket(int fd, const char *socket_name, const void *packet, size_t size) { + union { + struct sockaddr sa; + struct sockaddr_un un; + } sa; + + assert(fd >= 0); + assert(socket_name); + assert(packet); + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path)); + + if (sendto(fd, packet, size, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0) { + log_error("Failed to send: %m"); + return -1; + } + + return 0; +} + +int main(int argc, char *argv[]) { + int fd = -1, r = EXIT_FAILURE; + char packet[LINE_MAX]; + size_t length; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + if (argc != 3) { + log_error("Wrong number of arguments."); + goto finish; + } + + if (streq(argv[1], "1")) { + + packet[0] = '+'; + if (!fgets(packet+1, sizeof(packet)-1, stdin)) { + log_error("Failed to read password: %m"); + goto finish; + } + + truncate_nl(packet+1); + length = 1 + strlen(packet+1) + 1; + } else if (streq(argv[1], "0")) { + packet[0] = '-'; + length = 1; + } else { + log_error("Invalid first argument %s", argv[1]); + goto finish; + } + + if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) { + log_error("socket() failed: %m"); + goto finish; + } + + if (send_on_socket(fd, argv[2], packet, length) < 0) + goto finish; + + r = EXIT_SUCCESS; + +finish: + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} diff --git a/src/sd-daemon.c b/src/sd-daemon.c new file mode 100644 index 0000000..763e079 --- /dev/null +++ b/src/sd-daemon.c @@ -0,0 +1,530 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + Copyright 2010 Lennart Poettering + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#ifdef __BIONIC__ +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__linux__) +#include +#endif + +#include "sd-daemon.h" + +#if (__GNUC__ >= 4) +#ifdef SD_EXPORT_SYMBOLS +/* Export symbols */ +#define _sd_export_ __attribute__ ((visibility("default"))) +#else +/* Don't export the symbols */ +#define _sd_export_ __attribute__ ((visibility("hidden"))) +#endif +#else +#define _sd_export_ +#endif + +_sd_export_ int sd_listen_fds(int unset_environment) { + +#if defined(DISABLE_SYSTEMD) || !defined(__linux__) + return 0; +#else + int r, fd; + const char *e; + char *p = NULL; + unsigned long l; + + if (!(e = getenv("LISTEN_PID"))) { + r = 0; + goto finish; + } + + errno = 0; + l = strtoul(e, &p, 10); + + if (errno != 0) { + r = -errno; + goto finish; + } + + if (!p || *p || l <= 0) { + r = -EINVAL; + goto finish; + } + + /* Is this for us? */ + if (getpid() != (pid_t) l) { + r = 0; + goto finish; + } + + if (!(e = getenv("LISTEN_FDS"))) { + r = 0; + goto finish; + } + + errno = 0; + l = strtoul(e, &p, 10); + + if (errno != 0) { + r = -errno; + goto finish; + } + + if (!p || *p) { + r = -EINVAL; + goto finish; + } + + for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) l; fd ++) { + int flags; + + if ((flags = fcntl(fd, F_GETFD)) < 0) { + r = -errno; + goto finish; + } + + if (flags & FD_CLOEXEC) + continue; + + if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) { + r = -errno; + goto finish; + } + } + + r = (int) l; + +finish: + if (unset_environment) { + unsetenv("LISTEN_PID"); + unsetenv("LISTEN_FDS"); + } + + return r; +#endif +} + +_sd_export_ int sd_is_fifo(int fd, const char *path) { + struct stat st_fd; + + if (fd < 0) + return -EINVAL; + + memset(&st_fd, 0, sizeof(st_fd)); + if (fstat(fd, &st_fd) < 0) + return -errno; + + if (!S_ISFIFO(st_fd.st_mode)) + return 0; + + if (path) { + struct stat st_path; + + memset(&st_path, 0, sizeof(st_path)); + if (stat(path, &st_path) < 0) { + + if (errno == ENOENT || errno == ENOTDIR) + return 0; + + return -errno; + } + + return + st_path.st_dev == st_fd.st_dev && + st_path.st_ino == st_fd.st_ino; + } + + return 1; +} + +_sd_export_ int sd_is_special(int fd, const char *path) { + struct stat st_fd; + + if (fd < 0) + return -EINVAL; + + if (fstat(fd, &st_fd) < 0) + return -errno; + + if (!S_ISREG(st_fd.st_mode) && !S_ISCHR(st_fd.st_mode)) + return 0; + + if (path) { + struct stat st_path; + + if (stat(path, &st_path) < 0) { + + if (errno == ENOENT || errno == ENOTDIR) + return 0; + + return -errno; + } + + if (S_ISREG(st_fd.st_mode) && S_ISREG(st_path.st_mode)) + return + st_path.st_dev == st_fd.st_dev && + st_path.st_ino == st_fd.st_ino; + else if (S_ISCHR(st_fd.st_mode) && S_ISCHR(st_path.st_mode)) + return st_path.st_rdev == st_fd.st_rdev; + else + return 0; + } + + return 1; +} + +static int sd_is_socket_internal(int fd, int type, int listening) { + struct stat st_fd; + + if (fd < 0 || type < 0) + return -EINVAL; + + if (fstat(fd, &st_fd) < 0) + return -errno; + + if (!S_ISSOCK(st_fd.st_mode)) + return 0; + + if (type != 0) { + int other_type = 0; + socklen_t l = sizeof(other_type); + + if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &other_type, &l) < 0) + return -errno; + + if (l != sizeof(other_type)) + return -EINVAL; + + if (other_type != type) + return 0; + } + + if (listening >= 0) { + int accepting = 0; + socklen_t l = sizeof(accepting); + + if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &accepting, &l) < 0) + return -errno; + + if (l != sizeof(accepting)) + return -EINVAL; + + if (!accepting != !listening) + return 0; + } + + return 1; +} + +union sockaddr_union { + struct sockaddr sa; + struct sockaddr_in in4; + struct sockaddr_in6 in6; + struct sockaddr_un un; + struct sockaddr_storage storage; +}; + +_sd_export_ int sd_is_socket(int fd, int family, int type, int listening) { + int r; + + if (family < 0) + return -EINVAL; + + if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) + return r; + + if (family > 0) { + union sockaddr_union sockaddr; + socklen_t l; + + memset(&sockaddr, 0, sizeof(sockaddr)); + l = sizeof(sockaddr); + + if (getsockname(fd, &sockaddr.sa, &l) < 0) + return -errno; + + if (l < sizeof(sa_family_t)) + return -EINVAL; + + return sockaddr.sa.sa_family == family; + } + + return 1; +} + +_sd_export_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) { + union sockaddr_union sockaddr; + socklen_t l; + int r; + + if (family != 0 && family != AF_INET && family != AF_INET6) + return -EINVAL; + + if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) + return r; + + memset(&sockaddr, 0, sizeof(sockaddr)); + l = sizeof(sockaddr); + + if (getsockname(fd, &sockaddr.sa, &l) < 0) + return -errno; + + if (l < sizeof(sa_family_t)) + return -EINVAL; + + if (sockaddr.sa.sa_family != AF_INET && + sockaddr.sa.sa_family != AF_INET6) + return 0; + + if (family > 0) + if (sockaddr.sa.sa_family != family) + return 0; + + if (port > 0) { + if (sockaddr.sa.sa_family == AF_INET) { + if (l < sizeof(struct sockaddr_in)) + return -EINVAL; + + return htons(port) == sockaddr.in4.sin_port; + } else { + if (l < sizeof(struct sockaddr_in6)) + return -EINVAL; + + return htons(port) == sockaddr.in6.sin6_port; + } + } + + return 1; +} + +_sd_export_ int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) { + union sockaddr_union sockaddr; + socklen_t l; + int r; + + if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) + return r; + + memset(&sockaddr, 0, sizeof(sockaddr)); + l = sizeof(sockaddr); + + if (getsockname(fd, &sockaddr.sa, &l) < 0) + return -errno; + + if (l < sizeof(sa_family_t)) + return -EINVAL; + + if (sockaddr.sa.sa_family != AF_UNIX) + return 0; + + if (path) { + if (length <= 0) + length = strlen(path); + + if (length <= 0) + /* Unnamed socket */ + return l == offsetof(struct sockaddr_un, sun_path); + + if (path[0]) + /* Normal path socket */ + return + (l >= offsetof(struct sockaddr_un, sun_path) + length + 1) && + memcmp(path, sockaddr.un.sun_path, length+1) == 0; + else + /* Abstract namespace socket */ + return + (l == offsetof(struct sockaddr_un, sun_path) + length) && + memcmp(path, sockaddr.un.sun_path, length) == 0; + } + + return 1; +} + +_sd_export_ int sd_is_mq(int fd, const char *path) { +#if !defined(__linux__) + return 0; +#else + struct mq_attr attr; + + if (fd < 0) + return -EINVAL; + + if (mq_getattr(fd, &attr) < 0) + return -errno; + + if (path) { + char fpath[PATH_MAX]; + struct stat a, b; + + if (path[0] != '/') + return -EINVAL; + + if (fstat(fd, &a) < 0) + return -errno; + + strncpy(stpcpy(fpath, "/dev/mqueue"), path, sizeof(fpath) - 12); + fpath[sizeof(fpath)-1] = 0; + + if (stat(fpath, &b) < 0) + return -errno; + + if (a.st_dev != b.st_dev || + a.st_ino != b.st_ino) + return 0; + } + + return 1; +#endif +} + +_sd_export_ int sd_notify(int unset_environment, const char *state) { +#if defined(DISABLE_SYSTEMD) || !defined(__linux__) || !defined(SOCK_CLOEXEC) + return 0; +#else + int fd = -1, r; + struct msghdr msghdr; + struct iovec iovec; + union sockaddr_union sockaddr; + const char *e; + + if (!state) { + r = -EINVAL; + goto finish; + } + + if (!(e = getenv("NOTIFY_SOCKET"))) + return 0; + + /* Must be an abstract socket, or an absolute path */ + if ((e[0] != '@' && e[0] != '/') || e[1] == 0) { + r = -EINVAL; + goto finish; + } + + if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) { + r = -errno; + goto finish; + } + + memset(&sockaddr, 0, sizeof(sockaddr)); + sockaddr.sa.sa_family = AF_UNIX; + strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path)); + + if (sockaddr.un.sun_path[0] == '@') + sockaddr.un.sun_path[0] = 0; + + memset(&iovec, 0, sizeof(iovec)); + iovec.iov_base = (char*) state; + iovec.iov_len = strlen(state); + + memset(&msghdr, 0, sizeof(msghdr)); + msghdr.msg_name = &sockaddr; + msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e); + + if (msghdr.msg_namelen > sizeof(struct sockaddr_un)) + msghdr.msg_namelen = sizeof(struct sockaddr_un); + + msghdr.msg_iov = &iovec; + msghdr.msg_iovlen = 1; + + if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) { + r = -errno; + goto finish; + } + + r = 1; + +finish: + if (unset_environment) + unsetenv("NOTIFY_SOCKET"); + + if (fd >= 0) + close(fd); + + return r; +#endif +} + +_sd_export_ int sd_notifyf(int unset_environment, const char *format, ...) { +#if defined(DISABLE_SYSTEMD) || !defined(__linux__) + return 0; +#else + va_list ap; + char *p = NULL; + int r; + + va_start(ap, format); + r = vasprintf(&p, format, ap); + va_end(ap); + + if (r < 0 || !p) + return -ENOMEM; + + r = sd_notify(unset_environment, p); + free(p); + + return r; +#endif +} + +_sd_export_ int sd_booted(void) { +#if defined(DISABLE_SYSTEMD) || !defined(__linux__) + return 0; +#else + + struct stat a, b; + + /* We simply test whether the systemd cgroup hierarchy is + * mounted */ + + if (lstat("/sys/fs/cgroup", &a) < 0) + return 0; + + if (lstat("/sys/fs/cgroup/systemd", &b) < 0) + return 0; + + return a.st_dev != b.st_dev; +#endif +} diff --git a/src/sd-id128.c b/src/sd-id128.c new file mode 100644 index 0000000..b4184e1 --- /dev/null +++ b/src/sd-id128.c @@ -0,0 +1,221 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "sd-id128.h" + +#include "util.h" +#include "macro.h" + +_public_ char *sd_id128_to_string(sd_id128_t id, char s[33]) { + unsigned n; + + if (!s) + return NULL; + + for (n = 0; n < 16; n++) { + s[n*2] = hexchar(id.bytes[n] >> 4); + s[n*2+1] = hexchar(id.bytes[n] & 0xF); + } + + s[32] = 0; + + return s; +} + +_public_ int sd_id128_from_string(const char s[33], sd_id128_t *ret) { + unsigned n; + sd_id128_t t; + + if (!s) + return -EINVAL; + if (!ret) + return -EINVAL; + + for (n = 0; n < 16; n++) { + int a, b; + + a = unhexchar(s[n*2]); + if (a < 0) + return -EINVAL; + + b = unhexchar(s[n*2+1]); + if (b < 0) + return -EINVAL; + + t.bytes[n] = (a << 4) | b; + } + + if (s[32] != 0) + return -EINVAL; + + *ret = t; + return 0; +} + +static sd_id128_t make_v4_uuid(sd_id128_t id) { + /* Stolen from generate_random_uuid() of drivers/char/random.c + * in the kernel sources */ + + /* Set UUID version to 4 --- truly random generation */ + id.bytes[6] = (id.bytes[6] & 0x0F) | 0x40; + + /* Set the UUID variant to DCE */ + id.bytes[8] = (id.bytes[8] & 0x3F) | 0x80; + + return id; +} + +_public_ int sd_id128_get_machine(sd_id128_t *ret) { + static __thread sd_id128_t saved_machine_id; + static __thread bool saved_machine_id_valid = false; + int fd; + char buf[32]; + ssize_t k; + unsigned j; + sd_id128_t t; + + if (!ret) + return -EINVAL; + + if (saved_machine_id_valid) { + *ret = saved_machine_id; + return 0; + } + + fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + return -errno; + + k = loop_read(fd, buf, 32, false); + close_nointr_nofail(fd); + + if (k < 0) + return (int) k; + + if (k < 32) + return -EIO; + + for (j = 0; j < 16; j++) { + int a, b; + + a = unhexchar(buf[j*2]); + b = unhexchar(buf[j*2+1]); + + if (a < 0 || b < 0) + return -EIO; + + t.bytes[j] = a << 4 | b; + } + + saved_machine_id = t; + saved_machine_id_valid = true; + + *ret = t; + return 0; +} + +_public_ int sd_id128_get_boot(sd_id128_t *ret) { + static __thread sd_id128_t saved_boot_id; + static __thread bool saved_boot_id_valid = false; + int fd; + char buf[36]; + ssize_t k; + unsigned j; + sd_id128_t t; + char *p; + + if (!ret) + return -EINVAL; + + if (saved_boot_id_valid) { + *ret = saved_boot_id; + return 0; + } + + fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + return -errno; + + k = loop_read(fd, buf, 36, false); + close_nointr_nofail(fd); + + if (k < 0) + return (int) k; + + if (k < 36) + return -EIO; + + for (j = 0, p = buf; j < 16; j++) { + int a, b; + + if (*p == '-') + p++; + + a = unhexchar(p[0]); + b = unhexchar(p[1]); + + if (a < 0 || b < 0) + return -EIO; + + t.bytes[j] = a << 4 | b; + + p += 2; + } + + saved_boot_id = t; + saved_boot_id_valid = true; + + *ret = t; + return 0; +} + +_public_ int sd_id128_randomize(sd_id128_t *ret) { + int fd; + ssize_t k; + sd_id128_t t; + + if (!ret) + return -EINVAL; + + fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + return -errno; + + k = loop_read(fd, &t, 16, false); + close_nointr_nofail(fd); + + if (k < 0) + return (int) k; + + if (k < 16) + return -EIO; + + /* Turn this into a valid v4 UUID, to be nice. Note that we + * only guarantee this for newly generated UUIDs, not for + * pre-existing ones.*/ + + *ret = make_v4_uuid(t); + return 0; +} diff --git a/src/securebits.h b/src/securebits.h new file mode 100644 index 0000000..ba0bba5 --- /dev/null +++ b/src/securebits.h @@ -0,0 +1,45 @@ +#ifndef _LINUX_SECUREBITS_H +#define _LINUX_SECUREBITS_H 1 + +/* This is minimal version of Linux' linux/securebits.h header file, + * which is licensed GPL2 */ + +#define SECUREBITS_DEFAULT 0x00000000 + +/* When set UID 0 has no special privileges. When unset, we support + inheritance of root-permissions and suid-root executable under + compatibility mode. We raise the effective and inheritable bitmasks + *of the executable file* if the effective uid of the new process is + 0. If the real uid is 0, we raise the effective (legacy) bit of the + executable file. */ +#define SECURE_NOROOT 0 +#define SECURE_NOROOT_LOCKED 1 /* make bit-0 immutable */ + +/* When set, setuid to/from uid 0 does not trigger capability-"fixup". + When unset, to provide compatibility with old programs relying on + set*uid to gain/lose privilege, transitions to/from uid 0 cause + capabilities to be gained/lost. */ +#define SECURE_NO_SETUID_FIXUP 2 +#define SECURE_NO_SETUID_FIXUP_LOCKED 3 /* make bit-2 immutable */ + +/* When set, a process can retain its capabilities even after + transitioning to a non-root user (the set-uid fixup suppressed by + bit 2). Bit-4 is cleared when a process calls exec(); setting both + bit 4 and 5 will create a barrier through exec that no exec()'d + child can use this feature again. */ +#define SECURE_KEEP_CAPS 4 +#define SECURE_KEEP_CAPS_LOCKED 5 /* make bit-4 immutable */ + +/* Each securesetting is implemented using two bits. One bit specifies + whether the setting is on or off. The other bit specify whether the + setting is locked or not. A setting which is locked cannot be + changed from user-level. */ +#define issecure_mask(X) (1 << (X)) +#define issecure(X) (issecure_mask(X) & current_cred_xxx(securebits)) + +#define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \ + issecure_mask(SECURE_NO_SETUID_FIXUP) | \ + issecure_mask(SECURE_KEEP_CAPS)) +#define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1) + +#endif /* !_LINUX_SECUREBITS_H */ diff --git a/src/selinux-setup.c b/src/selinux-setup.c new file mode 100644 index 0000000..a7e1fa4 --- /dev/null +++ b/src/selinux-setup.c @@ -0,0 +1,112 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#ifdef HAVE_SELINUX +#include +#endif + +#include "selinux-setup.h" +#include "mount-setup.h" +#include "macro.h" +#include "util.h" +#include "log.h" +#include "label.h" + +int selinux_setup(bool *loaded_policy) { + +#ifdef HAVE_SELINUX + int enforce = 0; + usec_t before_load, after_load; + security_context_t con; + int r; + + assert(loaded_policy); + + /* Make sure getcon() works, which needs /proc and /sys */ + mount_setup_early(); + + /* Already initialized by somebody else? */ + r = getcon_raw(&con); + if (r == 0) { + bool initialized; + + initialized = !streq(con, "kernel"); + freecon(con); + + if (initialized) + return 0; + } + + /* Make sure we have no fds open while loading the policy and + * transitioning */ + log_close(); + + /* Now load the policy */ + before_load = now(CLOCK_MONOTONIC); + r = selinux_init_load_policy(&enforce); + + if (r == 0) { + char timespan[FORMAT_TIMESPAN_MAX]; + char *label; + + label_retest_selinux(); + + /* Transition to the new context */ + r = label_get_create_label_from_exe(SYSTEMD_BINARY_PATH, &label); + if (r < 0 || label == NULL) { + log_open(); + log_error("Failed to compute init label, ignoring."); + } else { + r = setcon(label); + + log_open(); + if (r < 0) + log_error("Failed to transition into init label '%s', ignoring.", label); + + label_free(label); + } + + after_load = now(CLOCK_MONOTONIC); + + log_info("Successfully loaded SELinux policy in %s.", + format_timespan(timespan, sizeof(timespan), after_load - before_load)); + + *loaded_policy = true; + + } else { + log_open(); + + if (enforce > 0) { + log_error("Failed to load SELinux policy. Freezing."); + return -EIO; + } else + log_debug("Unable to load SELinux policy. Ignoring."); + } +#endif + + return 0; +} diff --git a/src/selinux-setup.h b/src/selinux-setup.h new file mode 100644 index 0000000..6b8fe00 --- /dev/null +++ b/src/selinux-setup.h @@ -0,0 +1,29 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooselinuxsetuphfoo +#define fooselinuxsetuphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +int selinux_setup(bool *loaded_policy); + +#endif diff --git a/src/service.c b/src/service.c new file mode 100644 index 0000000..ec2725a --- /dev/null +++ b/src/service.c @@ -0,0 +1,3783 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "manager.h" +#include "unit.h" +#include "service.h" +#include "load-fragment.h" +#include "load-dropin.h" +#include "log.h" +#include "strv.h" +#include "unit-name.h" +#include "dbus-service.h" +#include "special.h" +#include "bus-errors.h" +#include "exit-status.h" +#include "def.h" +#include "util.h" + +#ifdef HAVE_SYSV_COMPAT + +#define DEFAULT_SYSV_TIMEOUT_USEC (5*USEC_PER_MINUTE) + +typedef enum RunlevelType { + RUNLEVEL_UP, + RUNLEVEL_DOWN, + RUNLEVEL_SYSINIT +} RunlevelType; + +static const struct { + const char *path; + const char *target; + const RunlevelType type; +} rcnd_table[] = { + /* Standard SysV runlevels for start-up */ + { "rc1.d", SPECIAL_RESCUE_TARGET, RUNLEVEL_UP }, + { "rc2.d", SPECIAL_RUNLEVEL2_TARGET, RUNLEVEL_UP }, + { "rc3.d", SPECIAL_RUNLEVEL3_TARGET, RUNLEVEL_UP }, + { "rc4.d", SPECIAL_RUNLEVEL4_TARGET, RUNLEVEL_UP }, + { "rc5.d", SPECIAL_RUNLEVEL5_TARGET, RUNLEVEL_UP }, + +#ifdef TARGET_SUSE + /* SUSE style boot.d */ + { "boot.d", SPECIAL_SYSINIT_TARGET, RUNLEVEL_SYSINIT }, +#endif + +#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM) + /* Debian style rcS.d */ + { "rcS.d", SPECIAL_SYSINIT_TARGET, RUNLEVEL_SYSINIT }, +#endif + + /* Standard SysV runlevels for shutdown */ + { "rc0.d", SPECIAL_POWEROFF_TARGET, RUNLEVEL_DOWN }, + { "rc6.d", SPECIAL_REBOOT_TARGET, RUNLEVEL_DOWN } + + /* Note that the order here matters, as we read the + directories in this order, and we want to make sure that + sysv_start_priority is known when we first load the + unit. And that value we only know from S links. Hence + UP/SYSINIT must be read before DOWN */ +}; + +#define RUNLEVELS_UP "12345" +/* #define RUNLEVELS_DOWN "06" */ +#define RUNLEVELS_BOOT "bBsS" +#endif + +static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = { + [SERVICE_DEAD] = UNIT_INACTIVE, + [SERVICE_START_PRE] = UNIT_ACTIVATING, + [SERVICE_START] = UNIT_ACTIVATING, + [SERVICE_START_POST] = UNIT_ACTIVATING, + [SERVICE_RUNNING] = UNIT_ACTIVE, + [SERVICE_EXITED] = UNIT_ACTIVE, + [SERVICE_RELOAD] = UNIT_RELOADING, + [SERVICE_STOP] = UNIT_DEACTIVATING, + [SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING, + [SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING, + [SERVICE_STOP_POST] = UNIT_DEACTIVATING, + [SERVICE_FINAL_SIGTERM] = UNIT_DEACTIVATING, + [SERVICE_FINAL_SIGKILL] = UNIT_DEACTIVATING, + [SERVICE_FAILED] = UNIT_FAILED, + [SERVICE_AUTO_RESTART] = UNIT_ACTIVATING +}; + +static void service_init(Unit *u) { + Service *s = SERVICE(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + s->timeout_usec = DEFAULT_TIMEOUT_USEC; + s->restart_usec = DEFAULT_RESTART_USEC; + + s->watchdog_watch.type = WATCH_INVALID; + + s->timer_watch.type = WATCH_INVALID; +#ifdef HAVE_SYSV_COMPAT + s->sysv_start_priority = -1; + s->sysv_start_priority_from_rcnd = -1; +#endif + s->socket_fd = -1; + s->guess_main_pid = true; + + exec_context_init(&s->exec_context); + + RATELIMIT_INIT(s->start_limit, 10*USEC_PER_SEC, 5); + + s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID; +} + +static void service_unwatch_control_pid(Service *s) { + assert(s); + + if (s->control_pid <= 0) + return; + + unit_unwatch_pid(UNIT(s), s->control_pid); + s->control_pid = 0; +} + +static void service_unwatch_main_pid(Service *s) { + assert(s); + + if (s->main_pid <= 0) + return; + + unit_unwatch_pid(UNIT(s), s->main_pid); + s->main_pid = 0; +} + +static void service_unwatch_pid_file(Service *s) { + if (!s->pid_file_pathspec) + return; + + log_debug("Stopping watch for %s's PID file %s", UNIT(s)->id, s->pid_file_pathspec->path); + path_spec_unwatch(s->pid_file_pathspec, UNIT(s)); + path_spec_done(s->pid_file_pathspec); + free(s->pid_file_pathspec); + s->pid_file_pathspec = NULL; +} + +static int service_set_main_pid(Service *s, pid_t pid) { + pid_t ppid; + + assert(s); + + if (pid <= 1) + return -EINVAL; + + if (pid == getpid()) + return -EINVAL; + + s->main_pid = pid; + s->main_pid_known = true; + + if (get_parent_of_pid(pid, &ppid) >= 0 && ppid != getpid()) { + log_warning("%s: Supervising process %lu which is not our child. We'll most likely not notice when it exits.", + UNIT(s)->id, (unsigned long) pid); + + s->main_pid_alien = true; + } else + s->main_pid_alien = false; + + exec_status_start(&s->main_exec_status, pid); + + return 0; +} + +static void service_close_socket_fd(Service *s) { + assert(s); + + if (s->socket_fd < 0) + return; + + close_nointr_nofail(s->socket_fd); + s->socket_fd = -1; +} + +static void service_connection_unref(Service *s) { + assert(s); + + if (!UNIT_DEREF(s->accept_socket)) + return; + + socket_connection_unref(SOCKET(UNIT_DEREF(s->accept_socket))); + unit_ref_unset(&s->accept_socket); +} + +static void service_stop_watchdog(Service *s) { + assert(s); + + unit_unwatch_timer(UNIT(s), &s->watchdog_watch); + s->watchdog_timestamp.realtime = 0; + s->watchdog_timestamp.monotonic = 0; +} + +static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart); + +static void service_handle_watchdog(Service *s) { + usec_t offset; + int r; + + assert(s); + + if (s->watchdog_usec == 0) + return; + + offset = now(CLOCK_MONOTONIC) - s->watchdog_timestamp.monotonic; + if (offset >= s->watchdog_usec) { + log_error("%s watchdog timeout!", UNIT(s)->id); + service_enter_dead(s, SERVICE_FAILURE_WATCHDOG, true); + return; + } + + r = unit_watch_timer(UNIT(s), s->watchdog_usec - offset, &s->watchdog_watch); + if (r < 0) + log_warning("%s failed to install watchdog timer: %s", UNIT(s)->id, strerror(-r)); +} + +static void service_reset_watchdog(Service *s) { + assert(s); + + dual_timestamp_get(&s->watchdog_timestamp); + service_handle_watchdog(s); +} + +static void service_done(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + free(s->pid_file); + s->pid_file = NULL; + +#ifdef HAVE_SYSV_COMPAT + free(s->sysv_path); + s->sysv_path = NULL; + + free(s->sysv_runlevels); + s->sysv_runlevels = NULL; +#endif + + free(s->status_text); + s->status_text = NULL; + + exec_context_done(&s->exec_context); + exec_command_free_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX); + s->control_command = NULL; + s->main_command = NULL; + + /* This will leak a process, but at least no memory or any of + * our resources */ + service_unwatch_main_pid(s); + service_unwatch_control_pid(s); + service_unwatch_pid_file(s); + + if (s->bus_name) { + unit_unwatch_bus_name(u, s->bus_name); + free(s->bus_name); + s->bus_name = NULL; + } + + service_close_socket_fd(s); + service_connection_unref(s); + + unit_ref_unset(&s->accept_socket); + + service_stop_watchdog(s); + + unit_unwatch_timer(u, &s->timer_watch); +} + +#ifdef HAVE_SYSV_COMPAT +static char *sysv_translate_name(const char *name) { + char *r; + + if (!(r = new(char, strlen(name) + sizeof(".service")))) + return NULL; + +#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM) + if (endswith(name, ".sh")) + /* Drop Debian-style .sh suffix */ + strcpy(stpcpy(r, name) - 3, ".service"); +#endif +#ifdef TARGET_SUSE + if (startswith(name, "boot.")) + /* Drop SuSE-style boot. prefix */ + strcpy(stpcpy(r, name + 5), ".service"); +#endif +#ifdef TARGET_FRUGALWARE + if (startswith(name, "rc.")) + /* Drop Frugalware-style rc. prefix */ + strcpy(stpcpy(r, name + 3), ".service"); +#endif + else + /* Normal init scripts */ + strcpy(stpcpy(r, name), ".service"); + + return r; +} + +static int sysv_translate_facility(const char *name, const char *filename, char **_r) { + + /* We silently ignore the $ prefix here. According to the LSB + * spec it simply indicates whether something is a + * standardized name or a distribution-specific one. Since we + * just follow what already exists and do not introduce new + * uses or names we don't care who introduced a new name. */ + + static const char * const table[] = { + /* LSB defined facilities */ + "local_fs", SPECIAL_LOCAL_FS_TARGET, +#if defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA) +#else + /* Due to unfortunate name selection in Mandriva, + * $network is provided by network-up which is ordered + * after network which actually starts interfaces. + * To break the loop, just ignore it */ + "network", SPECIAL_NETWORK_TARGET, +#endif + "named", SPECIAL_NSS_LOOKUP_TARGET, + "portmap", SPECIAL_RPCBIND_TARGET, + "remote_fs", SPECIAL_REMOTE_FS_TARGET, + "syslog", SPECIAL_SYSLOG_TARGET, + "time", SPECIAL_TIME_SYNC_TARGET, + + /* common extensions */ + "mail-transfer-agent", SPECIAL_MAIL_TRANSFER_AGENT_TARGET, + "x-display-manager", SPECIAL_DISPLAY_MANAGER_SERVICE, + "null", NULL, + +#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM) + "mail-transport-agent", SPECIAL_MAIL_TRANSFER_AGENT_TARGET, +#endif + +#ifdef TARGET_FEDORA + "MTA", SPECIAL_MAIL_TRANSFER_AGENT_TARGET, + "smtpdaemon", SPECIAL_MAIL_TRANSFER_AGENT_TARGET, + "httpd", SPECIAL_HTTP_DAEMON_TARGET, +#endif + +#ifdef TARGET_SUSE + "smtp", SPECIAL_MAIL_TRANSFER_AGENT_TARGET, +#endif + }; + + unsigned i; + char *r; + const char *n; + + assert(name); + assert(_r); + + n = *name == '$' ? name + 1 : name; + + for (i = 0; i < ELEMENTSOF(table); i += 2) { + + if (!streq(table[i], n)) + continue; + + if (!table[i+1]) + return 0; + + if (!(r = strdup(table[i+1]))) + return -ENOMEM; + + goto finish; + } + + /* If we don't know this name, fallback heuristics to figure + * out whether something is a target or a service alias. */ + + if (*name == '$') { + if (!unit_prefix_is_valid(n)) + return -EINVAL; + + /* Facilities starting with $ are most likely targets */ + r = unit_name_build(n, NULL, ".target"); + } else if (filename && streq(name, filename)) + /* Names equaling the file name of the services are redundant */ + return 0; + else + /* Everything else we assume to be normal service names */ + r = sysv_translate_name(n); + + if (!r) + return -ENOMEM; + +finish: + *_r = r; + + return 1; +} + +static int sysv_fix_order(Service *s) { + Unit *other; + int r; + + assert(s); + + if (s->sysv_start_priority < 0) + return 0; + + /* For each pair of services where at least one lacks a LSB + * header, we use the start priority value to order things. */ + + LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_SERVICE]) { + Service *t; + UnitDependency d; + bool special_s, special_t; + + t = SERVICE(other); + + if (s == t) + continue; + + if (UNIT(t)->load_state != UNIT_LOADED) + continue; + + if (t->sysv_start_priority < 0) + continue; + + /* If both units have modern headers we don't care + * about the priorities */ + if ((UNIT(s)->fragment_path || s->sysv_has_lsb) && + (UNIT(t)->fragment_path || t->sysv_has_lsb)) + continue; + + special_s = s->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, s->sysv_runlevels); + special_t = t->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, t->sysv_runlevels); + + if (special_t && !special_s) + d = UNIT_AFTER; + else if (special_s && !special_t) + d = UNIT_BEFORE; + else if (t->sysv_start_priority < s->sysv_start_priority) + d = UNIT_AFTER; + else if (t->sysv_start_priority > s->sysv_start_priority) + d = UNIT_BEFORE; + else + continue; + + /* FIXME: Maybe we should compare the name here lexicographically? */ + + if ((r = unit_add_dependency(UNIT(s), d, UNIT(t), true)) < 0) + return r; + } + + return 0; +} + +static ExecCommand *exec_command_new(const char *path, const char *arg1) { + ExecCommand *c; + + if (!(c = new0(ExecCommand, 1))) + return NULL; + + if (!(c->path = strdup(path))) { + free(c); + return NULL; + } + + if (!(c->argv = strv_new(path, arg1, NULL))) { + free(c->path); + free(c); + return NULL; + } + + return c; +} + +static int sysv_exec_commands(Service *s) { + ExecCommand *c; + + assert(s); + assert(s->sysv_path); + + if (!(c = exec_command_new(s->sysv_path, "start"))) + return -ENOMEM; + exec_command_append_list(s->exec_command+SERVICE_EXEC_START, c); + + if (!(c = exec_command_new(s->sysv_path, "stop"))) + return -ENOMEM; + exec_command_append_list(s->exec_command+SERVICE_EXEC_STOP, c); + + if (!(c = exec_command_new(s->sysv_path, "reload"))) + return -ENOMEM; + exec_command_append_list(s->exec_command+SERVICE_EXEC_RELOAD, c); + + return 0; +} + +static int service_load_sysv_path(Service *s, const char *path) { + FILE *f; + Unit *u; + unsigned line = 0; + int r; + enum { + NORMAL, + DESCRIPTION, + LSB, + LSB_DESCRIPTION + } state = NORMAL; + char *short_description = NULL, *long_description = NULL, *chkconfig_description = NULL, *description; + struct stat st; + + assert(s); + assert(path); + + u = UNIT(s); + + if (!(f = fopen(path, "re"))) { + r = errno == ENOENT ? 0 : -errno; + goto finish; + } + + zero(st); + if (fstat(fileno(f), &st) < 0) { + r = -errno; + goto finish; + } + + free(s->sysv_path); + if (!(s->sysv_path = strdup(path))) { + r = -ENOMEM; + goto finish; + } + + s->sysv_mtime = timespec_load(&st.st_mtim); + + if (null_or_empty(&st)) { + u->load_state = UNIT_MASKED; + r = 0; + goto finish; + } + + while (!feof(f)) { + char l[LINE_MAX], *t; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + r = -errno; + log_error("Failed to read configuration file '%s': %s", path, strerror(-r)); + goto finish; + } + + line++; + + t = strstrip(l); + if (*t != '#') + continue; + + if (state == NORMAL && streq(t, "### BEGIN INIT INFO")) { + state = LSB; + s->sysv_has_lsb = true; + continue; + } + + if ((state == LSB_DESCRIPTION || state == LSB) && streq(t, "### END INIT INFO")) { + state = NORMAL; + continue; + } + + t++; + t += strspn(t, WHITESPACE); + + if (state == NORMAL) { + + /* Try to parse Red Hat style chkconfig headers */ + + if (startswith_no_case(t, "chkconfig:")) { + int start_priority; + char runlevels[16], *k; + + state = NORMAL; + + if (sscanf(t+10, "%15s %i %*i", + runlevels, + &start_priority) != 2) { + + log_warning("[%s:%u] Failed to parse chkconfig line. Ignoring.", path, line); + continue; + } + + /* A start priority gathered from the + * symlink farms is preferred over the + * data from the LSB header. */ + if (start_priority < 0 || start_priority > 99) + log_warning("[%s:%u] Start priority out of range. Ignoring.", path, line); + else + s->sysv_start_priority = start_priority; + + char_array_0(runlevels); + k = delete_chars(runlevels, WHITESPACE "-"); + + if (k[0]) { + char *d; + + if (!(d = strdup(k))) { + r = -ENOMEM; + goto finish; + } + + free(s->sysv_runlevels); + s->sysv_runlevels = d; + } + + } else if (startswith_no_case(t, "description:")) { + + size_t k = strlen(t); + char *d; + const char *j; + + if (t[k-1] == '\\') { + state = DESCRIPTION; + t[k-1] = 0; + } + + if ((j = strstrip(t+12)) && *j) { + if (!(d = strdup(j))) { + r = -ENOMEM; + goto finish; + } + } else + d = NULL; + + free(chkconfig_description); + chkconfig_description = d; + + } else if (startswith_no_case(t, "pidfile:")) { + + char *fn; + + state = NORMAL; + + fn = strstrip(t+8); + if (!path_is_absolute(fn)) { + log_warning("[%s:%u] PID file not absolute. Ignoring.", path, line); + continue; + } + + if (!(fn = strdup(fn))) { + r = -ENOMEM; + goto finish; + } + + free(s->pid_file); + s->pid_file = fn; + } + + } else if (state == DESCRIPTION) { + + /* Try to parse Red Hat style description + * continuation */ + + size_t k = strlen(t); + char *j; + + if (t[k-1] == '\\') + t[k-1] = 0; + else + state = NORMAL; + + if ((j = strstrip(t)) && *j) { + char *d = NULL; + + if (chkconfig_description) + d = join(chkconfig_description, " ", j, NULL); + else + d = strdup(j); + + if (!d) { + r = -ENOMEM; + goto finish; + } + + free(chkconfig_description); + chkconfig_description = d; + } + + } else if (state == LSB || state == LSB_DESCRIPTION) { + + if (startswith_no_case(t, "Provides:")) { + char *i, *w; + size_t z; + + state = LSB; + + FOREACH_WORD_QUOTED(w, z, t+9, i) { + char *n, *m; + + if (!(n = strndup(w, z))) { + r = -ENOMEM; + goto finish; + } + + r = sysv_translate_facility(n, file_name_from_path(path), &m); + free(n); + + if (r < 0) + goto finish; + + if (r == 0) + continue; + + if (unit_name_to_type(m) == UNIT_SERVICE) + r = unit_add_name(u, m); + else + /* NB: SysV targets + * which are provided + * by a service are + * pulled in by the + * services, as an + * indication that the + * generic service is + * now available. This + * is strictly + * one-way. The + * targets do NOT pull + * in the SysV + * services! */ + r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, UNIT_WANTS, m, NULL, true); + + if (r < 0) + log_error("[%s:%u] Failed to add LSB Provides name %s, ignoring: %s", path, line, m, strerror(-r)); + + free(m); + } + + } else if (startswith_no_case(t, "Required-Start:") || + startswith_no_case(t, "Should-Start:") || + startswith_no_case(t, "X-Start-Before:") || + startswith_no_case(t, "X-Start-After:")) { + char *i, *w; + size_t z; + + state = LSB; + + FOREACH_WORD_QUOTED(w, z, strchr(t, ':')+1, i) { + char *n, *m; + + if (!(n = strndup(w, z))) { + r = -ENOMEM; + goto finish; + } + + r = sysv_translate_facility(n, file_name_from_path(path), &m); + + if (r < 0) { + log_error("[%s:%u] Failed to translate LSB dependency %s, ignoring: %s", path, line, n, strerror(-r)); + free(n); + continue; + } + + free(n); + + if (r == 0) + continue; + + r = unit_add_dependency_by_name(u, startswith_no_case(t, "X-Start-Before:") ? UNIT_BEFORE : UNIT_AFTER, m, NULL, true); + + if (r < 0) + log_error("[%s:%u] Failed to add dependency on %s, ignoring: %s", path, line, m, strerror(-r)); + + free(m); + } + } else if (startswith_no_case(t, "Default-Start:")) { + char *k, *d; + + state = LSB; + + k = delete_chars(t+14, WHITESPACE "-"); + + if (k[0] != 0) { + if (!(d = strdup(k))) { + r = -ENOMEM; + goto finish; + } + + free(s->sysv_runlevels); + s->sysv_runlevels = d; + } + + } else if (startswith_no_case(t, "Description:")) { + char *d, *j; + + state = LSB_DESCRIPTION; + + if ((j = strstrip(t+12)) && *j) { + if (!(d = strdup(j))) { + r = -ENOMEM; + goto finish; + } + } else + d = NULL; + + free(long_description); + long_description = d; + + } else if (startswith_no_case(t, "Short-Description:")) { + char *d, *j; + + state = LSB; + + if ((j = strstrip(t+18)) && *j) { + if (!(d = strdup(j))) { + r = -ENOMEM; + goto finish; + } + } else + d = NULL; + + free(short_description); + short_description = d; + + } else if (state == LSB_DESCRIPTION) { + + if (startswith(l, "#\t") || startswith(l, "# ")) { + char *j; + + if ((j = strstrip(t)) && *j) { + char *d = NULL; + + if (long_description) + d = join(long_description, " ", t, NULL); + else + d = strdup(j); + + if (!d) { + r = -ENOMEM; + goto finish; + } + + free(long_description); + long_description = d; + } + + } else + state = LSB; + } + } + } + + if ((r = sysv_exec_commands(s)) < 0) + goto finish; + if (s->sysv_runlevels && + chars_intersect(RUNLEVELS_BOOT, s->sysv_runlevels) && + chars_intersect(RUNLEVELS_UP, s->sysv_runlevels)) { + /* Service has both boot and "up" runlevels + configured. Kill the "up" ones. */ + delete_chars(s->sysv_runlevels, RUNLEVELS_UP); + } + + if (s->sysv_runlevels && !chars_intersect(RUNLEVELS_UP, s->sysv_runlevels)) { + /* If there a runlevels configured for this service + * but none of the standard ones, then we assume this + * is some special kind of service (which might be + * needed for early boot) and don't create any links + * to it. */ + + UNIT(s)->default_dependencies = false; + + /* Don't timeout special services during boot (like fsck) */ + s->timeout_usec = 0; + } else + s->timeout_usec = DEFAULT_SYSV_TIMEOUT_USEC; + + /* Special setting for all SysV services */ + s->type = SERVICE_FORKING; + s->remain_after_exit = !s->pid_file; + s->guess_main_pid = false; + s->restart = SERVICE_RESTART_NO; + s->exec_context.ignore_sigpipe = false; + + if (UNIT(s)->manager->sysv_console) + s->exec_context.std_output = EXEC_OUTPUT_JOURNAL_AND_CONSOLE; + + s->exec_context.kill_mode = KILL_PROCESS; + + /* We use the long description only if + * no short description is set. */ + + if (short_description) + description = short_description; + else if (chkconfig_description) + description = chkconfig_description; + else if (long_description) + description = long_description; + else + description = NULL; + + if (description) { + char *d; + + if (!(d = strappend(s->sysv_has_lsb ? "LSB: " : "SYSV: ", description))) { + r = -ENOMEM; + goto finish; + } + + u->description = d; + } + + /* The priority that has been set in /etc/rcN.d/ hierarchies + * takes precedence over what is stored as default in the LSB + * header */ + if (s->sysv_start_priority_from_rcnd >= 0) + s->sysv_start_priority = s->sysv_start_priority_from_rcnd; + + u->load_state = UNIT_LOADED; + r = 0; + +finish: + + if (f) + fclose(f); + + free(short_description); + free(long_description); + free(chkconfig_description); + + return r; +} + +static int service_load_sysv_name(Service *s, const char *name) { + char **p; + + assert(s); + assert(name); + + /* For SysV services we strip the boot.*, rc.* and *.sh + * prefixes/suffixes. */ +#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM) + if (endswith(name, ".sh.service")) + return -ENOENT; +#endif + +#ifdef TARGET_SUSE + if (startswith(name, "boot.")) + return -ENOENT; +#endif + +#ifdef TARGET_FRUGALWARE + if (startswith(name, "rc.")) + return -ENOENT; +#endif + + STRV_FOREACH(p, UNIT(s)->manager->lookup_paths.sysvinit_path) { + char *path; + int r; + + path = join(*p, "/", name, NULL); + if (!path) + return -ENOMEM; + + assert(endswith(path, ".service")); + path[strlen(path)-8] = 0; + + r = service_load_sysv_path(s, path); + +#if defined(TARGET_DEBIAN) || defined(TARGET_UBUNTU) || defined(TARGET_ANGSTROM) + if (r >= 0 && UNIT(s)->load_state == UNIT_STUB) { + /* Try Debian style *.sh source'able init scripts */ + strcat(path, ".sh"); + r = service_load_sysv_path(s, path); + } +#endif + free(path); + +#ifdef TARGET_SUSE + if (r >= 0 && UNIT(s)->load_state == UNIT_STUB) { + /* Try SUSE style boot.* init scripts */ + + path = join(*p, "/boot.", name, NULL); + if (!path) + return -ENOMEM; + + /* Drop .service suffix */ + path[strlen(path)-8] = 0; + r = service_load_sysv_path(s, path); + free(path); + } +#endif + +#ifdef TARGET_FRUGALWARE + if (r >= 0 && UNIT(s)->load_state == UNIT_STUB) { + /* Try Frugalware style rc.* init scripts */ + + path = join(*p, "/rc.", name, NULL); + if (!path) + return -ENOMEM; + + /* Drop .service suffix */ + path[strlen(path)-8] = 0; + r = service_load_sysv_path(s, path); + free(path); + } +#endif + + if (r < 0) + return r; + + if ((UNIT(s)->load_state != UNIT_STUB)) + break; + } + + return 0; +} + +static int service_load_sysv(Service *s) { + const char *t; + Iterator i; + int r; + + assert(s); + + /* Load service data from SysV init scripts, preferably with + * LSB headers ... */ + + if (strv_isempty(UNIT(s)->manager->lookup_paths.sysvinit_path)) + return 0; + + if ((t = UNIT(s)->id)) + if ((r = service_load_sysv_name(s, t)) < 0) + return r; + + if (UNIT(s)->load_state == UNIT_STUB) + SET_FOREACH(t, UNIT(s)->names, i) { + if (t == UNIT(s)->id) + continue; + + if ((r = service_load_sysv_name(s, t)) < 0) + return r; + + if (UNIT(s)->load_state != UNIT_STUB) + break; + } + + return 0; +} +#endif + +static int fsck_fix_order(Service *s) { + Unit *other; + int r; + + assert(s); + + if (s->fsck_passno <= 0) + return 0; + + /* For each pair of services where both have an fsck priority + * we order things based on it. */ + + LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_SERVICE]) { + Service *t; + UnitDependency d; + + t = SERVICE(other); + + if (s == t) + continue; + + if (UNIT(t)->load_state != UNIT_LOADED) + continue; + + if (t->fsck_passno <= 0) + continue; + + if (t->fsck_passno < s->fsck_passno) + d = UNIT_AFTER; + else if (t->fsck_passno > s->fsck_passno) + d = UNIT_BEFORE; + else + continue; + + if ((r = unit_add_dependency(UNIT(s), d, UNIT(t), true)) < 0) + return r; + } + + return 0; +} + +static int service_verify(Service *s) { + assert(s); + + if (UNIT(s)->load_state != UNIT_LOADED) + return 0; + + if (!s->exec_command[SERVICE_EXEC_START]) { + log_error("%s lacks ExecStart setting. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->type != SERVICE_ONESHOT && + s->exec_command[SERVICE_EXEC_START]->command_next) { + log_error("%s has more than one ExecStart setting, which is only allowed for Type=oneshot services. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->type == SERVICE_ONESHOT && + s->exec_command[SERVICE_EXEC_RELOAD]) { + log_error("%s has an ExecReload setting, which is not allowed for Type=oneshot services. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->type == SERVICE_DBUS && !s->bus_name) { + log_error("%s is of type D-Bus but no D-Bus service name has been specified. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->exec_context.pam_name && s->exec_context.kill_mode != KILL_CONTROL_GROUP) { + log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + return 0; +} + +static int service_add_default_dependencies(Service *s) { + int r; + + assert(s); + + /* Add a number of automatic dependencies useful for the + * majority of services. */ + + /* First, pull in base system */ + if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) { + + if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true)) < 0) + return r; + + } else if (UNIT(s)->manager->running_as == MANAGER_USER) { + + if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SOCKETS_TARGET, NULL, true)) < 0) + return r; + } + + /* Second, activate normal shutdown */ + return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); +} + +static void service_fix_output(Service *s) { + assert(s); + + /* If nothing has been explicitly configured, patch default + * output in. If input is socket/tty we avoid this however, + * since in that case we want output to default to the same + * place as we read input from. */ + + if (s->exec_context.std_error == EXEC_OUTPUT_INHERIT && + s->exec_context.std_output == EXEC_OUTPUT_INHERIT && + s->exec_context.std_input == EXEC_INPUT_NULL) + s->exec_context.std_error = UNIT(s)->manager->default_std_error; + + if (s->exec_context.std_output == EXEC_OUTPUT_INHERIT && + s->exec_context.std_input == EXEC_INPUT_NULL) + s->exec_context.std_output = UNIT(s)->manager->default_std_output; +} + +static int service_load(Unit *u) { + int r; + Service *s = SERVICE(u); + + assert(s); + + /* Load a .service file */ + if ((r = unit_load_fragment(u)) < 0) + return r; + +#ifdef HAVE_SYSV_COMPAT + /* Load a classic init script as a fallback, if we couldn't find anything */ + if (u->load_state == UNIT_STUB) + if ((r = service_load_sysv(s)) < 0) + return r; +#endif + + /* Still nothing found? Then let's give up */ + if (u->load_state == UNIT_STUB) + return -ENOENT; + + /* We were able to load something, then let's add in the + * dropin directories. */ + if ((r = unit_load_dropin(unit_follow_merge(u))) < 0) + return r; + + /* This is a new unit? Then let's add in some extras */ + if (u->load_state == UNIT_LOADED) { + service_fix_output(s); + + if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0) + return r; + + if ((r = unit_add_default_cgroups(u)) < 0) + return r; + +#ifdef HAVE_SYSV_COMPAT + if ((r = sysv_fix_order(s)) < 0) + return r; +#endif + + if ((r = fsck_fix_order(s)) < 0) + return r; + + if (s->bus_name) + if ((r = unit_watch_bus_name(u, s->bus_name)) < 0) + return r; + + if (s->type == SERVICE_NOTIFY && s->notify_access == NOTIFY_NONE) + s->notify_access = NOTIFY_MAIN; + + if (s->watchdog_usec > 0 && s->notify_access == NOTIFY_NONE) + s->notify_access = NOTIFY_MAIN; + + if (s->type == SERVICE_DBUS || s->bus_name) + if ((r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true)) < 0) + return r; + + if (UNIT(s)->default_dependencies) + if ((r = service_add_default_dependencies(s)) < 0) + return r; + } + + return service_verify(s); +} + +static void service_dump(Unit *u, FILE *f, const char *prefix) { + + ServiceExecCommand c; + Service *s = SERVICE(u); + const char *prefix2; + char *p2; + + assert(s); + + p2 = strappend(prefix, "\t"); + prefix2 = p2 ? p2 : prefix; + + fprintf(f, + "%sService State: %s\n" + "%sResult: %s\n" + "%sReload Result: %s\n" + "%sPermissionsStartOnly: %s\n" + "%sRootDirectoryStartOnly: %s\n" + "%sRemainAfterExit: %s\n" + "%sGuessMainPID: %s\n" + "%sType: %s\n" + "%sRestart: %s\n" + "%sNotifyAccess: %s\n", + prefix, service_state_to_string(s->state), + prefix, service_result_to_string(s->result), + prefix, service_result_to_string(s->reload_result), + prefix, yes_no(s->permissions_start_only), + prefix, yes_no(s->root_directory_start_only), + prefix, yes_no(s->remain_after_exit), + prefix, yes_no(s->guess_main_pid), + prefix, service_type_to_string(s->type), + prefix, service_restart_to_string(s->restart), + prefix, notify_access_to_string(s->notify_access)); + + if (s->control_pid > 0) + fprintf(f, + "%sControl PID: %lu\n", + prefix, (unsigned long) s->control_pid); + + if (s->main_pid > 0) + fprintf(f, + "%sMain PID: %lu\n" + "%sMain PID Known: %s\n" + "%sMain PID Alien: %s\n", + prefix, (unsigned long) s->main_pid, + prefix, yes_no(s->main_pid_known), + prefix, yes_no(s->main_pid_alien)); + + if (s->pid_file) + fprintf(f, + "%sPIDFile: %s\n", + prefix, s->pid_file); + + if (s->bus_name) + fprintf(f, + "%sBusName: %s\n" + "%sBus Name Good: %s\n", + prefix, s->bus_name, + prefix, yes_no(s->bus_name_good)); + + exec_context_dump(&s->exec_context, f, prefix); + + for (c = 0; c < _SERVICE_EXEC_COMMAND_MAX; c++) { + + if (!s->exec_command[c]) + continue; + + fprintf(f, "%s-> %s:\n", + prefix, service_exec_command_to_string(c)); + + exec_command_dump_list(s->exec_command[c], f, prefix2); + } + +#ifdef HAVE_SYSV_COMPAT + if (s->sysv_path) + fprintf(f, + "%sSysV Init Script Path: %s\n" + "%sSysV Init Script has LSB Header: %s\n" + "%sSysVEnabled: %s\n", + prefix, s->sysv_path, + prefix, yes_no(s->sysv_has_lsb), + prefix, yes_no(s->sysv_enabled)); + + if (s->sysv_start_priority >= 0) + fprintf(f, + "%sSysVStartPriority: %i\n", + prefix, s->sysv_start_priority); + + if (s->sysv_runlevels) + fprintf(f, "%sSysVRunLevels: %s\n", + prefix, s->sysv_runlevels); +#endif + + if (s->fsck_passno > 0) + fprintf(f, + "%sFsckPassNo: %i\n", + prefix, s->fsck_passno); + + if (s->status_text) + fprintf(f, "%sStatus Text: %s\n", + prefix, s->status_text); + + free(p2); +} + +static int service_load_pid_file(Service *s, bool may_warn) { + char *k; + int r; + pid_t pid; + + assert(s); + + if (!s->pid_file) + return -ENOENT; + + if ((r = read_one_line_file(s->pid_file, &k)) < 0) { + if (may_warn) + log_info("PID file %s not readable (yet?) after %s.", + s->pid_file, service_state_to_string(s->state)); + return r; + } + + r = parse_pid(k, &pid); + free(k); + + if (r < 0) + return r; + + if (kill(pid, 0) < 0 && errno != EPERM) { + if (may_warn) + log_info("PID %lu read from file %s does not exist.", + (unsigned long) pid, s->pid_file); + return -ESRCH; + } + + if (s->main_pid_known) { + if (pid == s->main_pid) + return 0; + + log_debug("Main PID changing: %lu -> %lu", + (unsigned long) s->main_pid, (unsigned long) pid); + service_unwatch_main_pid(s); + s->main_pid_known = false; + } else + log_debug("Main PID loaded: %lu", (unsigned long) pid); + + if ((r = service_set_main_pid(s, pid)) < 0) + return r; + + if ((r = unit_watch_pid(UNIT(s), pid)) < 0) + /* FIXME: we need to do something here */ + return r; + + return 0; +} + +static int service_search_main_pid(Service *s) { + pid_t pid; + int r; + + assert(s); + + /* If we know it anyway, don't ever fallback to unreliable + * heuristics */ + if (s->main_pid_known) + return 0; + + if (!s->guess_main_pid) + return 0; + + assert(s->main_pid <= 0); + + if ((pid = cgroup_bonding_search_main_pid_list(UNIT(s)->cgroup_bondings)) <= 0) + return -ENOENT; + + log_debug("Main PID guessed: %lu", (unsigned long) pid); + if ((r = service_set_main_pid(s, pid)) < 0) + return r; + + if ((r = unit_watch_pid(UNIT(s), pid)) < 0) + /* FIXME: we need to do something here */ + return r; + + return 0; +} + +static void service_notify_sockets_dead(Service *s) { + Iterator i; + Unit *u; + + assert(s); + + /* Notifies all our sockets when we die */ + + if (s->socket_fd >= 0) + return; + + SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERED_BY], i) + if (u->type == UNIT_SOCKET) + socket_notify_service_dead(SOCKET(u)); + + return; +} + +static void service_set_state(Service *s, ServiceState state) { + ServiceState old_state; + assert(s); + + old_state = s->state; + s->state = state; + + service_unwatch_pid_file(s); + + if (state != SERVICE_START_PRE && + state != SERVICE_START && + state != SERVICE_START_POST && + state != SERVICE_RELOAD && + state != SERVICE_STOP && + state != SERVICE_STOP_SIGTERM && + state != SERVICE_STOP_SIGKILL && + state != SERVICE_STOP_POST && + state != SERVICE_FINAL_SIGTERM && + state != SERVICE_FINAL_SIGKILL && + state != SERVICE_AUTO_RESTART) + unit_unwatch_timer(UNIT(s), &s->timer_watch); + + if (state != SERVICE_START && + state != SERVICE_START_POST && + state != SERVICE_RUNNING && + state != SERVICE_RELOAD && + state != SERVICE_STOP && + state != SERVICE_STOP_SIGTERM && + state != SERVICE_STOP_SIGKILL) { + service_unwatch_main_pid(s); + s->main_command = NULL; + } + + if (state != SERVICE_START_PRE && + state != SERVICE_START && + state != SERVICE_START_POST && + state != SERVICE_RELOAD && + state != SERVICE_STOP && + state != SERVICE_STOP_SIGTERM && + state != SERVICE_STOP_SIGKILL && + state != SERVICE_STOP_POST && + state != SERVICE_FINAL_SIGTERM && + state != SERVICE_FINAL_SIGKILL) { + service_unwatch_control_pid(s); + s->control_command = NULL; + s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID; + } + + if (state == SERVICE_DEAD || + state == SERVICE_STOP || + state == SERVICE_STOP_SIGTERM || + state == SERVICE_STOP_SIGKILL || + state == SERVICE_STOP_POST || + state == SERVICE_FINAL_SIGTERM || + state == SERVICE_FINAL_SIGKILL || + state == SERVICE_FAILED || + state == SERVICE_AUTO_RESTART) + service_notify_sockets_dead(s); + + if (state != SERVICE_START_PRE && + state != SERVICE_START && + state != SERVICE_START_POST && + state != SERVICE_RUNNING && + state != SERVICE_RELOAD && + state != SERVICE_STOP && + state != SERVICE_STOP_SIGTERM && + state != SERVICE_STOP_SIGKILL && + state != SERVICE_STOP_POST && + state != SERVICE_FINAL_SIGTERM && + state != SERVICE_FINAL_SIGKILL && + !(state == SERVICE_DEAD && UNIT(s)->job)) { + service_close_socket_fd(s); + service_connection_unref(s); + } + + if (state == SERVICE_STOP) + service_stop_watchdog(s); + + /* For the inactive states unit_notify() will trim the cgroup, + * but for exit we have to do that ourselves... */ + if (state == SERVICE_EXITED && UNIT(s)->manager->n_reloading <= 0) + cgroup_bonding_trim_list(UNIT(s)->cgroup_bondings, true); + + if (old_state != state) + log_debug("%s changed %s -> %s", UNIT(s)->id, service_state_to_string(old_state), service_state_to_string(state)); + + unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], s->reload_result == SERVICE_SUCCESS); + s->reload_result = SERVICE_SUCCESS; +} + +static int service_coldplug(Unit *u) { + Service *s = SERVICE(u); + int r; + + assert(s); + assert(s->state == SERVICE_DEAD); + + if (s->deserialized_state != s->state) { + + if (s->deserialized_state == SERVICE_START_PRE || + s->deserialized_state == SERVICE_START || + s->deserialized_state == SERVICE_START_POST || + s->deserialized_state == SERVICE_RELOAD || + s->deserialized_state == SERVICE_STOP || + s->deserialized_state == SERVICE_STOP_SIGTERM || + s->deserialized_state == SERVICE_STOP_SIGKILL || + s->deserialized_state == SERVICE_STOP_POST || + s->deserialized_state == SERVICE_FINAL_SIGTERM || + s->deserialized_state == SERVICE_FINAL_SIGKILL || + s->deserialized_state == SERVICE_AUTO_RESTART) { + + if (s->deserialized_state == SERVICE_AUTO_RESTART || s->timeout_usec > 0) { + usec_t k; + + k = s->deserialized_state == SERVICE_AUTO_RESTART ? s->restart_usec : s->timeout_usec; + + if ((r = unit_watch_timer(UNIT(s), k, &s->timer_watch)) < 0) + return r; + } + } + + if ((s->deserialized_state == SERVICE_START && + (s->type == SERVICE_FORKING || + s->type == SERVICE_DBUS || + s->type == SERVICE_ONESHOT || + s->type == SERVICE_NOTIFY)) || + s->deserialized_state == SERVICE_START_POST || + s->deserialized_state == SERVICE_RUNNING || + s->deserialized_state == SERVICE_RELOAD || + s->deserialized_state == SERVICE_STOP || + s->deserialized_state == SERVICE_STOP_SIGTERM || + s->deserialized_state == SERVICE_STOP_SIGKILL) + if (s->main_pid > 0) + if ((r = unit_watch_pid(UNIT(s), s->main_pid)) < 0) + return r; + + if (s->deserialized_state == SERVICE_START_PRE || + s->deserialized_state == SERVICE_START || + s->deserialized_state == SERVICE_START_POST || + s->deserialized_state == SERVICE_RELOAD || + s->deserialized_state == SERVICE_STOP || + s->deserialized_state == SERVICE_STOP_SIGTERM || + s->deserialized_state == SERVICE_STOP_SIGKILL || + s->deserialized_state == SERVICE_STOP_POST || + s->deserialized_state == SERVICE_FINAL_SIGTERM || + s->deserialized_state == SERVICE_FINAL_SIGKILL) + if (s->control_pid > 0) + if ((r = unit_watch_pid(UNIT(s), s->control_pid)) < 0) + return r; + + if (s->deserialized_state == SERVICE_START_POST || + s->deserialized_state == SERVICE_RUNNING) + service_handle_watchdog(s); + + service_set_state(s, s->deserialized_state); + } + return 0; +} + +static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) { + Iterator i; + int r; + int *rfds = NULL; + unsigned rn_fds = 0; + Unit *u; + + assert(s); + assert(fds); + assert(n_fds); + + if (s->socket_fd >= 0) + return 0; + + SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERED_BY], i) { + int *cfds; + unsigned cn_fds; + Socket *sock; + + if (u->type != UNIT_SOCKET) + continue; + + sock = SOCKET(u); + + if ((r = socket_collect_fds(sock, &cfds, &cn_fds)) < 0) + goto fail; + + if (!cfds) + continue; + + if (!rfds) { + rfds = cfds; + rn_fds = cn_fds; + } else { + int *t; + + if (!(t = new(int, rn_fds+cn_fds))) { + free(cfds); + r = -ENOMEM; + goto fail; + } + + memcpy(t, rfds, rn_fds * sizeof(int)); + memcpy(t+rn_fds, cfds, cn_fds * sizeof(int)); + free(rfds); + free(cfds); + + rfds = t; + rn_fds = rn_fds+cn_fds; + } + } + + *fds = rfds; + *n_fds = rn_fds; + + return 0; + +fail: + free(rfds); + + return r; +} + +static int service_spawn( + Service *s, + ExecCommand *c, + bool timeout, + bool pass_fds, + bool apply_permissions, + bool apply_chroot, + bool apply_tty_stdin, + bool set_notify_socket, + pid_t *_pid) { + + pid_t pid; + int r; + int *fds = NULL, *fdsbuf = NULL; + unsigned n_fds = 0, n_env = 0; + char **argv = NULL, **final_env = NULL, **our_env = NULL; + + assert(s); + assert(c); + assert(_pid); + + if (pass_fds || + s->exec_context.std_input == EXEC_INPUT_SOCKET || + s->exec_context.std_output == EXEC_OUTPUT_SOCKET || + s->exec_context.std_error == EXEC_OUTPUT_SOCKET) { + + if (s->socket_fd >= 0) { + fds = &s->socket_fd; + n_fds = 1; + } else { + if ((r = service_collect_fds(s, &fdsbuf, &n_fds)) < 0) + goto fail; + + fds = fdsbuf; + } + } + + if (timeout && s->timeout_usec) { + if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) + goto fail; + } else + unit_unwatch_timer(UNIT(s), &s->timer_watch); + + if (!(argv = unit_full_printf_strv(UNIT(s), c->argv))) { + r = -ENOMEM; + goto fail; + } + + if (!(our_env = new0(char*, 4))) { + r = -ENOMEM; + goto fail; + } + + if (set_notify_socket) + if (asprintf(our_env + n_env++, "NOTIFY_SOCKET=%s", UNIT(s)->manager->notify_socket) < 0) { + r = -ENOMEM; + goto fail; + } + + if (s->main_pid > 0) + if (asprintf(our_env + n_env++, "MAINPID=%lu", (unsigned long) s->main_pid) < 0) { + r = -ENOMEM; + goto fail; + } + + if (s->watchdog_usec > 0) + if (asprintf(our_env + n_env++, "WATCHDOG_USEC=%llu", (unsigned long long) s->watchdog_usec) < 0) { + r = -ENOMEM; + goto fail; + } + + if (!(final_env = strv_env_merge(2, + UNIT(s)->manager->environment, + our_env, + NULL))) { + r = -ENOMEM; + goto fail; + } + + r = exec_spawn(c, + argv, + &s->exec_context, + fds, n_fds, + final_env, + apply_permissions, + apply_chroot, + apply_tty_stdin, + UNIT(s)->manager->confirm_spawn, + UNIT(s)->cgroup_bondings, + UNIT(s)->cgroup_attributes, + &pid); + + if (r < 0) + goto fail; + + + if ((r = unit_watch_pid(UNIT(s), pid)) < 0) + /* FIXME: we need to do something here */ + goto fail; + + free(fdsbuf); + strv_free(argv); + strv_free(our_env); + strv_free(final_env); + + *_pid = pid; + + return 0; + +fail: + free(fdsbuf); + strv_free(argv); + strv_free(our_env); + strv_free(final_env); + + if (timeout) + unit_unwatch_timer(UNIT(s), &s->timer_watch); + + return r; +} + +static int main_pid_good(Service *s) { + assert(s); + + /* Returns 0 if the pid is dead, 1 if it is good, -1 if we + * don't know */ + + /* If we know the pid file, then lets just check if it is + * still valid */ + if (s->main_pid_known) { + + /* If it's an alien child let's check if it is still + * alive ... */ + if (s->main_pid_alien) + return kill(s->main_pid, 0) >= 0 || errno != ESRCH; + + /* .. otherwise assume we'll get a SIGCHLD for it, + * which we really should wait for to collect exit + * status and code */ + return s->main_pid > 0; + } + + /* We don't know the pid */ + return -EAGAIN; +} + +static int control_pid_good(Service *s) { + assert(s); + + return s->control_pid > 0; +} + +static int cgroup_good(Service *s) { + int r; + + assert(s); + + if ((r = cgroup_bonding_is_empty_list(UNIT(s)->cgroup_bondings)) < 0) + return r; + + return !r; +} + +static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) { + int r; + assert(s); + + if (f != SERVICE_SUCCESS) + s->result = f; + + if (allow_restart && + !s->forbid_restart && + (s->restart == SERVICE_RESTART_ALWAYS || + (s->restart == SERVICE_RESTART_ON_SUCCESS && s->result == SERVICE_SUCCESS) || + (s->restart == SERVICE_RESTART_ON_FAILURE && s->result != SERVICE_SUCCESS) || + (s->restart == SERVICE_RESTART_ON_ABORT && (s->result == SERVICE_FAILURE_SIGNAL || + s->result == SERVICE_FAILURE_CORE_DUMP)))) { + + r = unit_watch_timer(UNIT(s), s->restart_usec, &s->timer_watch); + if (r < 0) + goto fail; + + service_set_state(s, SERVICE_AUTO_RESTART); + } else + service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD); + + s->forbid_restart = false; + + return; + +fail: + log_warning("%s failed to run install restart timer: %s", UNIT(s)->id, strerror(-r)); + service_enter_dead(s, SERVICE_FAILURE_RESOURCES, false); +} + +static void service_enter_signal(Service *s, ServiceState state, ServiceResult f); + +static void service_enter_stop_post(Service *s, ServiceResult f) { + int r; + assert(s); + + if (f != SERVICE_SUCCESS) + s->result = f; + + service_unwatch_control_pid(s); + + if ((s->control_command = s->exec_command[SERVICE_EXEC_STOP_POST])) { + s->control_command_id = SERVICE_EXEC_STOP_POST; + + if ((r = service_spawn(s, + s->control_command, + true, + false, + !s->permissions_start_only, + !s->root_directory_start_only, + true, + false, + &s->control_pid)) < 0) + goto fail; + + + service_set_state(s, SERVICE_STOP_POST); + } else + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_SUCCESS); + + return; + +fail: + log_warning("%s failed to run 'stop-post' task: %s", UNIT(s)->id, strerror(-r)); + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES); +} + +static void service_enter_signal(Service *s, ServiceState state, ServiceResult f) { + int r; + Set *pid_set = NULL; + bool wait_for_exit = false; + + assert(s); + + if (f != SERVICE_SUCCESS) + s->result = f; + + if (s->exec_context.kill_mode != KILL_NONE) { + int sig = (state == SERVICE_STOP_SIGTERM || state == SERVICE_FINAL_SIGTERM) ? s->exec_context.kill_signal : SIGKILL; + + if (s->main_pid > 0) { + if (kill_and_sigcont(s->main_pid, sig) < 0 && errno != ESRCH) + log_warning("Failed to kill main process %li: %m", (long) s->main_pid); + else + wait_for_exit = !s->main_pid_alien; + } + + if (s->control_pid > 0) { + if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH) + log_warning("Failed to kill control process %li: %m", (long) s->control_pid); + else + wait_for_exit = true; + } + + if (s->exec_context.kill_mode == KILL_CONTROL_GROUP) { + + if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) { + r = -ENOMEM; + goto fail; + } + + /* Exclude the main/control pids from being killed via the cgroup */ + if (s->main_pid > 0) + if ((r = set_put(pid_set, LONG_TO_PTR(s->main_pid))) < 0) + goto fail; + + if (s->control_pid > 0) + if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) + goto fail; + + if ((r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set)) < 0) { + if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) + log_warning("Failed to kill control group: %s", strerror(-r)); + } else if (r > 0) + wait_for_exit = true; + + set_free(pid_set); + pid_set = NULL; + } + } + + if (wait_for_exit) { + if (s->timeout_usec > 0) + if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) + goto fail; + + service_set_state(s, state); + } else if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGKILL) + service_enter_stop_post(s, SERVICE_SUCCESS); + else + service_enter_dead(s, SERVICE_SUCCESS, true); + + return; + +fail: + log_warning("%s failed to kill processes: %s", UNIT(s)->id, strerror(-r)); + + if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGKILL) + service_enter_stop_post(s, SERVICE_FAILURE_RESOURCES); + else + service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true); + + if (pid_set) + set_free(pid_set); +} + +static void service_enter_stop(Service *s, ServiceResult f) { + int r; + + assert(s); + + if (f != SERVICE_SUCCESS) + s->result = f; + + service_unwatch_control_pid(s); + + if ((s->control_command = s->exec_command[SERVICE_EXEC_STOP])) { + s->control_command_id = SERVICE_EXEC_STOP; + + if ((r = service_spawn(s, + s->control_command, + true, + false, + !s->permissions_start_only, + !s->root_directory_start_only, + false, + false, + &s->control_pid)) < 0) + goto fail; + + service_set_state(s, SERVICE_STOP); + } else + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_SUCCESS); + + return; + +fail: + log_warning("%s failed to run 'stop' task: %s", UNIT(s)->id, strerror(-r)); + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES); +} + +static void service_enter_running(Service *s, ServiceResult f) { + int main_pid_ok, cgroup_ok; + assert(s); + + if (f != SERVICE_SUCCESS) + s->result = f; + + main_pid_ok = main_pid_good(s); + cgroup_ok = cgroup_good(s); + + if ((main_pid_ok > 0 || (main_pid_ok < 0 && cgroup_ok != 0)) && + (s->bus_name_good || s->type != SERVICE_DBUS)) + service_set_state(s, SERVICE_RUNNING); + else if (s->remain_after_exit) + service_set_state(s, SERVICE_EXITED); + else + service_enter_stop(s, SERVICE_SUCCESS); +} + +static void service_enter_start_post(Service *s) { + int r; + assert(s); + + service_unwatch_control_pid(s); + + if (s->watchdog_usec > 0) + service_reset_watchdog(s); + + if ((s->control_command = s->exec_command[SERVICE_EXEC_START_POST])) { + s->control_command_id = SERVICE_EXEC_START_POST; + + if ((r = service_spawn(s, + s->control_command, + true, + false, + !s->permissions_start_only, + !s->root_directory_start_only, + false, + false, + &s->control_pid)) < 0) + goto fail; + + service_set_state(s, SERVICE_START_POST); + } else + service_enter_running(s, SERVICE_SUCCESS); + + return; + +fail: + log_warning("%s failed to run 'start-post' task: %s", UNIT(s)->id, strerror(-r)); + service_enter_stop(s, SERVICE_FAILURE_RESOURCES); +} + +static void service_enter_start(Service *s) { + pid_t pid; + int r; + ExecCommand *c; + + assert(s); + + assert(s->exec_command[SERVICE_EXEC_START]); + assert(!s->exec_command[SERVICE_EXEC_START]->command_next || s->type == SERVICE_ONESHOT); + + if (s->type == SERVICE_FORKING) + service_unwatch_control_pid(s); + else + service_unwatch_main_pid(s); + + /* We want to ensure that nobody leaks processes from + * START_PRE here, so let's go on a killing spree, People + * should not spawn long running processes from START_PRE. */ + cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, NULL); + + if (s->type == SERVICE_FORKING) { + s->control_command_id = SERVICE_EXEC_START; + c = s->control_command = s->exec_command[SERVICE_EXEC_START]; + + s->main_command = NULL; + } else { + s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID; + s->control_command = NULL; + + c = s->main_command = s->exec_command[SERVICE_EXEC_START]; + } + + if ((r = service_spawn(s, + c, + s->type == SERVICE_FORKING || s->type == SERVICE_DBUS || s->type == SERVICE_NOTIFY, + true, + true, + true, + true, + s->notify_access != NOTIFY_NONE, + &pid)) < 0) + goto fail; + + if (s->type == SERVICE_SIMPLE) { + /* For simple services we immediately start + * the START_POST binaries. */ + + service_set_main_pid(s, pid); + service_enter_start_post(s); + + } else if (s->type == SERVICE_FORKING) { + + /* For forking services we wait until the start + * process exited. */ + + s->control_pid = pid; + service_set_state(s, SERVICE_START); + + } else if (s->type == SERVICE_ONESHOT || + s->type == SERVICE_DBUS || + s->type == SERVICE_NOTIFY) { + + /* For oneshot services we wait until the start + * process exited, too, but it is our main process. */ + + /* For D-Bus services we know the main pid right away, + * but wait for the bus name to appear on the + * bus. Notify services are similar. */ + + service_set_main_pid(s, pid); + service_set_state(s, SERVICE_START); + } else + assert_not_reached("Unknown service type"); + + return; + +fail: + log_warning("%s failed to run 'start' task: %s", UNIT(s)->id, strerror(-r)); + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES); +} + +static void service_enter_start_pre(Service *s) { + int r; + + assert(s); + + service_unwatch_control_pid(s); + + if ((s->control_command = s->exec_command[SERVICE_EXEC_START_PRE])) { + + /* Before we start anything, let's clear up what might + * be left from previous runs. */ + cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, NULL); + + s->control_command_id = SERVICE_EXEC_START_PRE; + + if ((r = service_spawn(s, + s->control_command, + true, + false, + !s->permissions_start_only, + !s->root_directory_start_only, + true, + false, + &s->control_pid)) < 0) + goto fail; + + service_set_state(s, SERVICE_START_PRE); + } else + service_enter_start(s); + + return; + +fail: + log_warning("%s failed to run 'start-pre' task: %s", UNIT(s)->id, strerror(-r)); + service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true); +} + +static void service_enter_restart(Service *s) { + int r; + DBusError error; + + assert(s); + dbus_error_init(&error); + + if (UNIT(s)->job) { + log_info("Job pending for unit, delaying automatic restart."); + + if ((r = unit_watch_timer(UNIT(s), s->restart_usec, &s->timer_watch)) < 0) + goto fail; + } + + service_enter_dead(s, SERVICE_SUCCESS, false); + + if ((r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(s), JOB_FAIL, false, &error, NULL)) < 0) + goto fail; + + log_debug("%s scheduled restart job.", UNIT(s)->id); + return; + +fail: + log_warning("%s failed to schedule restart job: %s", UNIT(s)->id, bus_error(&error, -r)); + service_enter_dead(s, SERVICE_FAILURE_RESOURCES, false); + + dbus_error_free(&error); +} + +static void service_enter_reload(Service *s) { + int r; + + assert(s); + + service_unwatch_control_pid(s); + + if ((s->control_command = s->exec_command[SERVICE_EXEC_RELOAD])) { + s->control_command_id = SERVICE_EXEC_RELOAD; + + if ((r = service_spawn(s, + s->control_command, + true, + false, + !s->permissions_start_only, + !s->root_directory_start_only, + false, + false, + &s->control_pid)) < 0) + goto fail; + + service_set_state(s, SERVICE_RELOAD); + } else + service_enter_running(s, SERVICE_SUCCESS); + + return; + +fail: + log_warning("%s failed to run 'reload' task: %s", UNIT(s)->id, strerror(-r)); + s->reload_result = SERVICE_FAILURE_RESOURCES; + service_enter_running(s, SERVICE_SUCCESS); +} + +static void service_run_next_control(Service *s) { + int r; + + assert(s); + assert(s->control_command); + assert(s->control_command->command_next); + + assert(s->control_command_id != SERVICE_EXEC_START); + + s->control_command = s->control_command->command_next; + service_unwatch_control_pid(s); + + if ((r = service_spawn(s, + s->control_command, + true, + false, + !s->permissions_start_only, + !s->root_directory_start_only, + s->control_command_id == SERVICE_EXEC_START_PRE || + s->control_command_id == SERVICE_EXEC_STOP_POST, + false, + &s->control_pid)) < 0) + goto fail; + + return; + +fail: + log_warning("%s failed to run next control task: %s", UNIT(s)->id, strerror(-r)); + + if (s->state == SERVICE_START_PRE) + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES); + else if (s->state == SERVICE_STOP) + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES); + else if (s->state == SERVICE_STOP_POST) + service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true); + else if (s->state == SERVICE_RELOAD) { + s->reload_result = SERVICE_FAILURE_RESOURCES; + service_enter_running(s, SERVICE_SUCCESS); + } else + service_enter_stop(s, SERVICE_FAILURE_RESOURCES); +} + +static void service_run_next_main(Service *s) { + pid_t pid; + int r; + + assert(s); + assert(s->main_command); + assert(s->main_command->command_next); + assert(s->type == SERVICE_ONESHOT); + + s->main_command = s->main_command->command_next; + service_unwatch_main_pid(s); + + if ((r = service_spawn(s, + s->main_command, + false, + true, + true, + true, + true, + s->notify_access != NOTIFY_NONE, + &pid)) < 0) + goto fail; + + service_set_main_pid(s, pid); + + return; + +fail: + log_warning("%s failed to run next main task: %s", UNIT(s)->id, strerror(-r)); + service_enter_stop(s, SERVICE_FAILURE_RESOURCES); +} + +static int service_start_limit_test(Service *s) { + assert(s); + + if (ratelimit_test(&s->start_limit)) + return 0; + + switch (s->start_limit_action) { + + case SERVICE_START_LIMIT_NONE: + log_warning("%s start request repeated too quickly, refusing to start.", UNIT(s)->id); + break; + + case SERVICE_START_LIMIT_REBOOT: { + DBusError error; + int r; + + dbus_error_init(&error); + + log_warning("%s start request repeated too quickly, rebooting.", UNIT(s)->id); + + r = manager_add_job_by_name(UNIT(s)->manager, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE, true, &error, NULL); + if (r < 0) { + log_error("Failed to reboot: %s.", bus_error(&error, r)); + dbus_error_free(&error); + } + + break; + } + + case SERVICE_START_LIMIT_REBOOT_FORCE: + log_warning("%s start request repeated too quickly, force rebooting.", UNIT(s)->id); + UNIT(s)->manager->exit_code = MANAGER_REBOOT; + break; + + case SERVICE_START_LIMIT_REBOOT_IMMEDIATE: + log_warning("%s start request repeated too quickly, rebooting immediately.", UNIT(s)->id); + reboot(RB_AUTOBOOT); + break; + + default: + log_error("start limit action=%i", s->start_limit_action); + assert_not_reached("Unknown StartLimitAction."); + } + + return -ECANCELED; +} + +static int service_start(Unit *u) { + Service *s = SERVICE(u); + int r; + + assert(s); + + /* We cannot fulfill this request right now, try again later + * please! */ + if (s->state == SERVICE_STOP || + s->state == SERVICE_STOP_SIGTERM || + s->state == SERVICE_STOP_SIGKILL || + s->state == SERVICE_STOP_POST || + s->state == SERVICE_FINAL_SIGTERM || + s->state == SERVICE_FINAL_SIGKILL) + return -EAGAIN; + + /* Already on it! */ + if (s->state == SERVICE_START_PRE || + s->state == SERVICE_START || + s->state == SERVICE_START_POST) + return 0; + + assert(s->state == SERVICE_DEAD || s->state == SERVICE_FAILED || s->state == SERVICE_AUTO_RESTART); + + /* Make sure we don't enter a busy loop of some kind. */ + r = service_start_limit_test(s); + if (r < 0) + return r; + + s->result = SERVICE_SUCCESS; + s->reload_result = SERVICE_SUCCESS; + s->main_pid_known = false; + s->main_pid_alien = false; + s->forbid_restart = false; + + service_enter_start_pre(s); + return 0; +} + +static int service_stop(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + /* This is a user request, so don't do restarts on this + * shutdown. */ + s->forbid_restart = true; + + /* Already on it */ + if (s->state == SERVICE_STOP || + s->state == SERVICE_STOP_SIGTERM || + s->state == SERVICE_STOP_SIGKILL || + s->state == SERVICE_STOP_POST || + s->state == SERVICE_FINAL_SIGTERM || + s->state == SERVICE_FINAL_SIGKILL) + return 0; + + /* Don't allow a restart */ + if (s->state == SERVICE_AUTO_RESTART) { + service_set_state(s, SERVICE_DEAD); + return 0; + } + + /* If there's already something running we go directly into + * kill mode. */ + if (s->state == SERVICE_START_PRE || + s->state == SERVICE_START || + s->state == SERVICE_START_POST || + s->state == SERVICE_RELOAD) { + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_SUCCESS); + return 0; + } + + assert(s->state == SERVICE_RUNNING || + s->state == SERVICE_EXITED); + + service_enter_stop(s, SERVICE_SUCCESS); + return 0; +} + +static int service_reload(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + assert(s->state == SERVICE_RUNNING || s->state == SERVICE_EXITED); + + service_enter_reload(s); + return 0; +} + +static bool service_can_reload(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + return !!s->exec_command[SERVICE_EXEC_RELOAD]; +} + +static int service_serialize(Unit *u, FILE *f, FDSet *fds) { + Service *s = SERVICE(u); + + assert(u); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", service_state_to_string(s->state)); + unit_serialize_item(u, f, "result", service_result_to_string(s->result)); + unit_serialize_item(u, f, "reload-result", service_result_to_string(s->reload_result)); + + if (s->control_pid > 0) + unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid); + + if (s->main_pid_known && s->main_pid > 0) + unit_serialize_item_format(u, f, "main-pid", "%lu", (unsigned long) s->main_pid); + + unit_serialize_item(u, f, "main-pid-known", yes_no(s->main_pid_known)); + + if (s->status_text) + unit_serialize_item(u, f, "status-text", s->status_text); + + /* FIXME: There's a minor uncleanliness here: if there are + * multiple commands attached here, we will start from the + * first one again */ + if (s->control_command_id >= 0) + unit_serialize_item(u, f, "control-command", service_exec_command_to_string(s->control_command_id)); + + if (s->socket_fd >= 0) { + int copy; + + if ((copy = fdset_put_dup(fds, s->socket_fd)) < 0) + return copy; + + unit_serialize_item_format(u, f, "socket-fd", "%i", copy); + } + + if (s->main_exec_status.pid > 0) { + unit_serialize_item_format(u, f, "main-exec-status-pid", "%lu", (unsigned long) s->main_exec_status.pid); + dual_timestamp_serialize(f, "main-exec-status-start", &s->main_exec_status.start_timestamp); + dual_timestamp_serialize(f, "main-exec-status-exit", &s->main_exec_status.exit_timestamp); + + if (dual_timestamp_is_set(&s->main_exec_status.exit_timestamp)) { + unit_serialize_item_format(u, f, "main-exec-status-code", "%i", s->main_exec_status.code); + unit_serialize_item_format(u, f, "main-exec-status-status", "%i", s->main_exec_status.status); + } + } + if (dual_timestamp_is_set(&s->watchdog_timestamp)) + dual_timestamp_serialize(f, "watchdog-timestamp", &s->watchdog_timestamp); + + return 0; +} + +static int service_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Service *s = SERVICE(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + ServiceState state; + + if ((state = service_state_from_string(value)) < 0) + log_debug("Failed to parse state value %s", value); + else + s->deserialized_state = state; + } else if (streq(key, "result")) { + ServiceResult f; + + f = service_result_from_string(value); + if (f < 0) + log_debug("Failed to parse result value %s", value); + else if (f != SERVICE_SUCCESS) + s->result = f; + + } else if (streq(key, "reload-result")) { + ServiceResult f; + + f = service_result_from_string(value); + if (f < 0) + log_debug("Failed to parse reload result value %s", value); + else if (f != SERVICE_SUCCESS) + s->reload_result = f; + + } else if (streq(key, "control-pid")) { + pid_t pid; + + if (parse_pid(value, &pid) < 0) + log_debug("Failed to parse control-pid value %s", value); + else + s->control_pid = pid; + } else if (streq(key, "main-pid")) { + pid_t pid; + + if (parse_pid(value, &pid) < 0) + log_debug("Failed to parse main-pid value %s", value); + else + service_set_main_pid(s, (pid_t) pid); + } else if (streq(key, "main-pid-known")) { + int b; + + if ((b = parse_boolean(value)) < 0) + log_debug("Failed to parse main-pid-known value %s", value); + else + s->main_pid_known = b; + } else if (streq(key, "status-text")) { + char *t; + + if ((t = strdup(value))) { + free(s->status_text); + s->status_text = t; + } + + } else if (streq(key, "control-command")) { + ServiceExecCommand id; + + if ((id = service_exec_command_from_string(value)) < 0) + log_debug("Failed to parse exec-command value %s", value); + else { + s->control_command_id = id; + s->control_command = s->exec_command[id]; + } + } else if (streq(key, "socket-fd")) { + int fd; + + if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd)) + log_debug("Failed to parse socket-fd value %s", value); + else { + + if (s->socket_fd >= 0) + close_nointr_nofail(s->socket_fd); + s->socket_fd = fdset_remove(fds, fd); + } + } else if (streq(key, "main-exec-status-pid")) { + pid_t pid; + + if (parse_pid(value, &pid) < 0) + log_debug("Failed to parse main-exec-status-pid value %s", value); + else + s->main_exec_status.pid = pid; + } else if (streq(key, "main-exec-status-code")) { + int i; + + if (safe_atoi(value, &i) < 0) + log_debug("Failed to parse main-exec-status-code value %s", value); + else + s->main_exec_status.code = i; + } else if (streq(key, "main-exec-status-status")) { + int i; + + if (safe_atoi(value, &i) < 0) + log_debug("Failed to parse main-exec-status-status value %s", value); + else + s->main_exec_status.status = i; + } else if (streq(key, "main-exec-status-start")) + dual_timestamp_deserialize(value, &s->main_exec_status.start_timestamp); + else if (streq(key, "main-exec-status-exit")) + dual_timestamp_deserialize(value, &s->main_exec_status.exit_timestamp); + else if (streq(key, "watchdog-timestamp")) + dual_timestamp_deserialize(value, &s->watchdog_timestamp); + else + log_debug("Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState service_active_state(Unit *u) { + assert(u); + + return state_translation_table[SERVICE(u)->state]; +} + +static const char *service_sub_state_to_string(Unit *u) { + assert(u); + + return service_state_to_string(SERVICE(u)->state); +} + +static bool service_check_gc(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + /* Never clean up services that still have a process around, + * even if the service is formally dead. */ + if (cgroup_good(s) > 0 || + main_pid_good(s) > 0 || + control_pid_good(s) > 0) + return true; + +#ifdef HAVE_SYSV_COMPAT + if (s->sysv_path) + return true; +#endif + + return false; +} + +static bool service_check_snapshot(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + return !s->got_socket_fd; +} + +static int service_retry_pid_file(Service *s) { + int r; + + assert(s->pid_file); + assert(s->state == SERVICE_START || s->state == SERVICE_START_POST); + + r = service_load_pid_file(s, false); + if (r < 0) + return r; + + service_unwatch_pid_file(s); + + service_enter_running(s, SERVICE_SUCCESS); + return 0; +} + +static int service_watch_pid_file(Service *s) { + int r; + + log_debug("Setting watch for %s's PID file %s", UNIT(s)->id, s->pid_file_pathspec->path); + r = path_spec_watch(s->pid_file_pathspec, UNIT(s)); + if (r < 0) + goto fail; + + /* the pidfile might have appeared just before we set the watch */ + service_retry_pid_file(s); + + return 0; +fail: + log_error("Failed to set a watch for %s's PID file %s: %s", + UNIT(s)->id, s->pid_file_pathspec->path, strerror(-r)); + service_unwatch_pid_file(s); + return r; +} + +static int service_demand_pid_file(Service *s) { + PathSpec *ps; + + assert(s->pid_file); + assert(!s->pid_file_pathspec); + + ps = new0(PathSpec, 1); + if (!ps) + return -ENOMEM; + + ps->path = strdup(s->pid_file); + if (!ps->path) { + free(ps); + return -ENOMEM; + } + + path_kill_slashes(ps->path); + + /* PATH_CHANGED would not be enough. There are daemons (sendmail) that + * keep their PID file open all the time. */ + ps->type = PATH_MODIFIED; + ps->inotify_fd = -1; + + s->pid_file_pathspec = ps; + + return service_watch_pid_file(s); +} + +static void service_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { + Service *s = SERVICE(u); + + assert(s); + assert(fd >= 0); + assert(s->state == SERVICE_START || s->state == SERVICE_START_POST); + assert(s->pid_file_pathspec); + assert(path_spec_owns_inotify_fd(s->pid_file_pathspec, fd)); + + log_debug("inotify event for %s", u->id); + + if (path_spec_fd_event(s->pid_file_pathspec, events) < 0) + goto fail; + + if (service_retry_pid_file(s) == 0) + return; + + if (service_watch_pid_file(s) < 0) + goto fail; + + return; +fail: + service_unwatch_pid_file(s); + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES); +} + +static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { + Service *s = SERVICE(u); + ServiceResult f; + + assert(s); + assert(pid >= 0); + + if (UNIT(s)->fragment_path ? is_clean_exit(code, status) : is_clean_exit_lsb(code, status)) + f = SERVICE_SUCCESS; + else if (code == CLD_EXITED) + f = SERVICE_FAILURE_EXIT_CODE; + else if (code == CLD_KILLED) + f = SERVICE_FAILURE_SIGNAL; + else if (code == CLD_DUMPED) + f = SERVICE_FAILURE_CORE_DUMP; + else + assert_not_reached("Unknown code"); + + if (s->main_pid == pid) { + /* Forking services may occasionally move to a new PID. + * As long as they update the PID file before exiting the old + * PID, they're fine. */ + if (service_load_pid_file(s, false) == 0) + return; + + s->main_pid = 0; + exec_status_exit(&s->main_exec_status, &s->exec_context, pid, code, status); + + /* If this is not a forking service than the main + * process got started and hence we copy the exit + * status so that it is recorded both as main and as + * control process exit status */ + if (s->main_command) { + s->main_command->exec_status = s->main_exec_status; + + if (s->main_command->ignore) + f = SERVICE_SUCCESS; + } + + log_full(f == SERVICE_SUCCESS ? LOG_DEBUG : LOG_NOTICE, + "%s: main process exited, code=%s, status=%i", u->id, sigchld_code_to_string(code), status); + + if (f != SERVICE_SUCCESS) + s->result = f; + + if (s->main_command && + s->main_command->command_next && + f == SERVICE_SUCCESS) { + + /* There is another command to * + * execute, so let's do that. */ + + log_debug("%s running next main command for state %s", u->id, service_state_to_string(s->state)); + service_run_next_main(s); + + } else { + + /* The service exited, so the service is officially + * gone. */ + s->main_command = NULL; + + switch (s->state) { + + case SERVICE_START_POST: + case SERVICE_RELOAD: + case SERVICE_STOP: + /* Need to wait until the operation is + * done */ + break; + + case SERVICE_START: + if (s->type == SERVICE_ONESHOT) { + /* This was our main goal, so let's go on */ + if (f == SERVICE_SUCCESS) + service_enter_start_post(s); + else + service_enter_signal(s, SERVICE_FINAL_SIGTERM, f); + break; + } else { + assert(s->type == SERVICE_DBUS || s->type == SERVICE_NOTIFY); + + /* Fall through */ + } + + case SERVICE_RUNNING: + service_enter_running(s, f); + break; + + case SERVICE_STOP_SIGTERM: + case SERVICE_STOP_SIGKILL: + + if (!control_pid_good(s)) + service_enter_stop_post(s, f); + + /* If there is still a control process, wait for that first */ + break; + + default: + assert_not_reached("Uh, main process died at wrong time."); + } + } + + } else if (s->control_pid == pid) { + + s->control_pid = 0; + + if (s->control_command) { + exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status); + + if (s->control_command->ignore) + f = SERVICE_SUCCESS; + } + + log_full(f == SERVICE_SUCCESS ? LOG_DEBUG : LOG_NOTICE, + "%s: control process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status); + + if (f != SERVICE_SUCCESS) + s->result = f; + + if (s->control_command && + s->control_command->command_next && + f == SERVICE_SUCCESS) { + + /* There is another command to * + * execute, so let's do that. */ + + log_debug("%s running next control command for state %s", u->id, service_state_to_string(s->state)); + service_run_next_control(s); + + } else { + /* No further commands for this step, so let's + * figure out what to do next */ + + s->control_command = NULL; + s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID; + + log_debug("%s got final SIGCHLD for state %s", u->id, service_state_to_string(s->state)); + + switch (s->state) { + + case SERVICE_START_PRE: + if (f == SERVICE_SUCCESS) + service_enter_start(s); + else + service_enter_signal(s, SERVICE_FINAL_SIGTERM, f); + break; + + case SERVICE_START: + assert(s->type == SERVICE_FORKING); + + if (f != SERVICE_SUCCESS) { + service_enter_signal(s, SERVICE_FINAL_SIGTERM, f); + break; + } + + if (s->pid_file) { + bool has_start_post; + int r; + + /* Let's try to load the pid file here if we can. + * The PID file might actually be created by a START_POST + * script. In that case don't worry if the loading fails. */ + + has_start_post = !!s->exec_command[SERVICE_EXEC_START_POST]; + r = service_load_pid_file(s, !has_start_post); + if (!has_start_post && r < 0) { + r = service_demand_pid_file(s); + if (r < 0 || !cgroup_good(s)) + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES); + break; + } + } else + service_search_main_pid(s); + + service_enter_start_post(s); + break; + + case SERVICE_START_POST: + if (f != SERVICE_SUCCESS) { + service_enter_stop(s, f); + break; + } + + if (s->pid_file) { + int r; + + r = service_load_pid_file(s, true); + if (r < 0) { + r = service_demand_pid_file(s); + if (r < 0 || !cgroup_good(s)) + service_enter_stop(s, SERVICE_FAILURE_RESOURCES); + break; + } + } else + service_search_main_pid(s); + + service_enter_running(s, SERVICE_SUCCESS); + break; + + case SERVICE_RELOAD: + if (f == SERVICE_SUCCESS) { + service_load_pid_file(s, true); + service_search_main_pid(s); + } + + s->reload_result = f; + service_enter_running(s, SERVICE_SUCCESS); + break; + + case SERVICE_STOP: + service_enter_signal(s, SERVICE_STOP_SIGTERM, f); + break; + + case SERVICE_STOP_SIGTERM: + case SERVICE_STOP_SIGKILL: + if (main_pid_good(s) <= 0) + service_enter_stop_post(s, f); + + /* If there is still a service + * process around, wait until + * that one quit, too */ + break; + + case SERVICE_STOP_POST: + case SERVICE_FINAL_SIGTERM: + case SERVICE_FINAL_SIGKILL: + service_enter_dead(s, f, true); + break; + + default: + assert_not_reached("Uh, control process died at wrong time."); + } + } + } + + /* Notify clients about changed exit status */ + unit_add_to_dbus_queue(u); +} + +static void service_timer_event(Unit *u, uint64_t elapsed, Watch* w) { + Service *s = SERVICE(u); + + assert(s); + assert(elapsed == 1); + + if (w == &s->watchdog_watch) { + service_handle_watchdog(s); + return; + } + + assert(w == &s->timer_watch); + + switch (s->state) { + + case SERVICE_START_PRE: + case SERVICE_START: + log_warning("%s operation timed out. Terminating.", u->id); + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_TIMEOUT); + break; + + case SERVICE_START_POST: + log_warning("%s operation timed out. Stopping.", u->id); + service_enter_stop(s, SERVICE_FAILURE_TIMEOUT); + break; + + case SERVICE_RELOAD: + log_warning("%s operation timed out. Stopping.", u->id); + s->reload_result = SERVICE_FAILURE_TIMEOUT; + service_enter_running(s, SERVICE_SUCCESS); + break; + + case SERVICE_STOP: + log_warning("%s stopping timed out. Terminating.", u->id); + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT); + break; + + case SERVICE_STOP_SIGTERM: + if (s->exec_context.send_sigkill) { + log_warning("%s stopping timed out. Killing.", u->id); + service_enter_signal(s, SERVICE_STOP_SIGKILL, SERVICE_FAILURE_TIMEOUT); + } else { + log_warning("%s stopping timed out. Skipping SIGKILL.", u->id); + service_enter_stop_post(s, SERVICE_FAILURE_TIMEOUT); + } + + break; + + case SERVICE_STOP_SIGKILL: + /* Uh, we sent a SIGKILL and it is still not gone? + * Must be something we cannot kill, so let's just be + * weirded out and continue */ + + log_warning("%s still around after SIGKILL. Ignoring.", u->id); + service_enter_stop_post(s, SERVICE_FAILURE_TIMEOUT); + break; + + case SERVICE_STOP_POST: + log_warning("%s stopping timed out (2). Terminating.", u->id); + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_TIMEOUT); + break; + + case SERVICE_FINAL_SIGTERM: + if (s->exec_context.send_sigkill) { + log_warning("%s stopping timed out (2). Killing.", u->id); + service_enter_signal(s, SERVICE_FINAL_SIGKILL, SERVICE_FAILURE_TIMEOUT); + } else { + log_warning("%s stopping timed out (2). Skipping SIGKILL. Entering failed mode.", u->id); + service_enter_dead(s, SERVICE_FAILURE_TIMEOUT, false); + } + + break; + + case SERVICE_FINAL_SIGKILL: + log_warning("%s still around after SIGKILL (2). Entering failed mode.", u->id); + service_enter_dead(s, SERVICE_FAILURE_TIMEOUT, true); + break; + + case SERVICE_AUTO_RESTART: + log_info("%s holdoff time over, scheduling restart.", u->id); + service_enter_restart(s); + break; + + default: + assert_not_reached("Timeout at wrong time."); + } +} + +static void service_cgroup_notify_event(Unit *u) { + Service *s = SERVICE(u); + + assert(u); + + log_debug("%s: cgroup is empty", u->id); + + switch (s->state) { + + /* Waiting for SIGCHLD is usually more interesting, + * because it includes return codes/signals. Which is + * why we ignore the cgroup events for most cases, + * except when we don't know pid which to expect the + * SIGCHLD for. */ + + case SERVICE_START: + case SERVICE_START_POST: + /* If we were hoping for the daemon to write its PID file, + * we can give up now. */ + if (s->pid_file_pathspec) { + log_warning("%s never wrote its PID file. Failing.", UNIT(s)->id); + service_unwatch_pid_file(s); + if (s->state == SERVICE_START) + service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES); + else + service_enter_stop(s, SERVICE_FAILURE_RESOURCES); + } + break; + + case SERVICE_RUNNING: + /* service_enter_running() will figure out what to do */ + service_enter_running(s, SERVICE_SUCCESS); + break; + + case SERVICE_STOP_SIGTERM: + case SERVICE_STOP_SIGKILL: + + if (main_pid_good(s) <= 0 && !control_pid_good(s)) + service_enter_stop_post(s, SERVICE_SUCCESS); + + break; + + case SERVICE_FINAL_SIGTERM: + case SERVICE_FINAL_SIGKILL: + if (main_pid_good(s) <= 0 && !control_pid_good(s)) + service_enter_dead(s, SERVICE_SUCCESS, SERVICE_SUCCESS); + + break; + + default: + ; + } +} + +static void service_notify_message(Unit *u, pid_t pid, char **tags) { + Service *s = SERVICE(u); + const char *e; + + assert(u); + + if (s->notify_access == NOTIFY_NONE) { + log_warning("%s: Got notification message from PID %lu, but reception is disabled.", + u->id, (unsigned long) pid); + return; + } + + if (s->notify_access == NOTIFY_MAIN && pid != s->main_pid) { + log_warning("%s: Got notification message from PID %lu, but reception only permitted for PID %lu", + u->id, (unsigned long) pid, (unsigned long) s->main_pid); + return; + } + + log_debug("%s: Got message", u->id); + + /* Interpret MAINPID= */ + if ((e = strv_find_prefix(tags, "MAINPID=")) && + (s->state == SERVICE_START || + s->state == SERVICE_START_POST || + s->state == SERVICE_RUNNING || + s->state == SERVICE_RELOAD)) { + + if (parse_pid(e + 8, &pid) < 0) + log_warning("Failed to parse notification message %s", e); + else { + log_debug("%s: got %s", u->id, e); + service_set_main_pid(s, pid); + } + } + + /* Interpret READY= */ + if (s->type == SERVICE_NOTIFY && + s->state == SERVICE_START && + strv_find(tags, "READY=1")) { + log_debug("%s: got READY=1", u->id); + + service_enter_start_post(s); + } + + /* Interpret STATUS= */ + if ((e = strv_find_prefix(tags, "STATUS="))) { + char *t; + + if (e[7]) { + if (!(t = strdup(e+7))) { + log_error("Failed to allocate string."); + return; + } + + log_debug("%s: got %s", u->id, e); + + free(s->status_text); + s->status_text = t; + } else { + free(s->status_text); + s->status_text = NULL; + } + + } + if (strv_find(tags, "WATCHDOG=1")) { + log_debug("%s: got WATCHDOG=1", u->id); + service_reset_watchdog(s); + } + + /* Notify clients about changed status or main pid */ + unit_add_to_dbus_queue(u); +} + +#ifdef HAVE_SYSV_COMPAT + +#ifdef TARGET_SUSE +static void sysv_facility_in_insserv_conf(Manager *mgr) { + FILE *f=NULL; + int r; + + if (!(f = fopen("/etc/insserv.conf", "re"))) { + r = errno == ENOENT ? 0 : -errno; + goto finish; + } + + while (!feof(f)) { + char l[LINE_MAX], *t; + char **parsed = NULL; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + r = -errno; + log_error("Failed to read configuration file '/etc/insserv.conf': %s", strerror(-r)); + goto finish; + } + + t = strstrip(l); + if (*t != '$' && *t != '<') + continue; + + parsed = strv_split(t,WHITESPACE); + /* we ignore , not used, equivalent to X-Interactive */ + if (parsed && !startswith_no_case (parsed[0], "")) { + char *facility; + Unit *u; + if (sysv_translate_facility(parsed[0], NULL, &facility) < 0) + continue; + if ((u = manager_get_unit(mgr, facility)) && (u->type == UNIT_TARGET)) { + UnitDependency e; + char *dep = NULL, *name, **j; + + STRV_FOREACH (j, parsed+1) { + if (*j[0]=='+') { + e = UNIT_WANTS; + name = *j+1; + } + else { + e = UNIT_REQUIRES; + name = *j; + } + if (sysv_translate_facility(name, NULL, &dep) < 0) + continue; + + r = unit_add_two_dependencies_by_name(u, UNIT_BEFORE, e, dep, NULL, true); + free(dep); + } + } + free(facility); + } + strv_free(parsed); + } +finish: + if (f) + fclose(f); + +} +#endif + +static int service_enumerate(Manager *m) { + char **p; + unsigned i; + DIR *d = NULL; + char *path = NULL, *fpath = NULL, *name = NULL; + Set *runlevel_services[ELEMENTSOF(rcnd_table)], *shutdown_services = NULL; + Unit *service; + Iterator j; + int r; + + assert(m); + + if (m->running_as != MANAGER_SYSTEM) + return 0; + + zero(runlevel_services); + + STRV_FOREACH(p, m->lookup_paths.sysvrcnd_path) + for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) { + struct dirent *de; + + free(path); + path = join(*p, "/", rcnd_table[i].path, NULL); + if (!path) { + r = -ENOMEM; + goto finish; + } + + if (d) + closedir(d); + + if (!(d = opendir(path))) { + if (errno != ENOENT) + log_warning("opendir() failed on %s: %s", path, strerror(errno)); + + continue; + } + + while ((de = readdir(d))) { + int a, b; + + if (ignore_file(de->d_name)) + continue; + + if (de->d_name[0] != 'S' && de->d_name[0] != 'K') + continue; + + if (strlen(de->d_name) < 4) + continue; + + a = undecchar(de->d_name[1]); + b = undecchar(de->d_name[2]); + + if (a < 0 || b < 0) + continue; + + free(fpath); + fpath = join(path, "/", de->d_name, NULL); + if (!fpath) { + r = -ENOMEM; + goto finish; + } + + if (access(fpath, X_OK) < 0) { + + if (errno != ENOENT) + log_warning("access() failed on %s: %s", fpath, strerror(errno)); + + continue; + } + + free(name); + if (!(name = sysv_translate_name(de->d_name + 3))) { + r = -ENOMEM; + goto finish; + } + + if ((r = manager_load_unit_prepare(m, name, NULL, NULL, &service)) < 0) { + log_warning("Failed to prepare unit %s: %s", name, strerror(-r)); + continue; + } + + if (de->d_name[0] == 'S') { + + if (rcnd_table[i].type == RUNLEVEL_UP || rcnd_table[i].type == RUNLEVEL_SYSINIT) { + SERVICE(service)->sysv_start_priority_from_rcnd = + MAX(a*10 + b, SERVICE(service)->sysv_start_priority_from_rcnd); + + SERVICE(service)->sysv_enabled = true; + } + + if ((r = set_ensure_allocated(&runlevel_services[i], trivial_hash_func, trivial_compare_func)) < 0) + goto finish; + + if ((r = set_put(runlevel_services[i], service)) < 0) + goto finish; + + } else if (de->d_name[0] == 'K' && + (rcnd_table[i].type == RUNLEVEL_DOWN || + rcnd_table[i].type == RUNLEVEL_SYSINIT)) { + + if ((r = set_ensure_allocated(&shutdown_services, trivial_hash_func, trivial_compare_func)) < 0) + goto finish; + + if ((r = set_put(shutdown_services, service)) < 0) + goto finish; + } + } + } + + /* Now we loaded all stubs and are aware of the lowest + start-up priority for all services, not let's actually load + the services, this will also tell us which services are + actually native now */ + manager_dispatch_load_queue(m); + + /* If this is a native service, rely on native ways to pull in + * a service, don't pull it in via sysv rcN.d links. */ + for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) + SET_FOREACH(service, runlevel_services[i], j) { + service = unit_follow_merge(service); + + if (service->fragment_path) + continue; + + if ((r = unit_add_two_dependencies_by_name_inverse(service, UNIT_AFTER, UNIT_WANTS, rcnd_table[i].target, NULL, true)) < 0) + goto finish; + } + + /* We honour K links only for halt/reboot. For the normal + * runlevels we assume the stop jobs will be implicitly added + * by the core logic. Also, we don't really distinguish here + * between the runlevels 0 and 6 and just add them to the + * special shutdown target. On SUSE the boot.d/ runlevel is + * also used for shutdown, so we add links for that too to the + * shutdown target.*/ + SET_FOREACH(service, shutdown_services, j) { + service = unit_follow_merge(service); + + if (service->fragment_path) + continue; + + if ((r = unit_add_two_dependencies_by_name(service, UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true)) < 0) + goto finish; + } + + r = 0; + +#ifdef TARGET_SUSE + sysv_facility_in_insserv_conf (m); +#endif + +finish: + free(path); + free(fpath); + free(name); + + for (i = 0; i < ELEMENTSOF(rcnd_table); i++) + set_free(runlevel_services[i]); + set_free(shutdown_services); + + if (d) + closedir(d); + + return r; +} +#endif + +static void service_bus_name_owner_change( + Unit *u, + const char *name, + const char *old_owner, + const char *new_owner) { + + Service *s = SERVICE(u); + + assert(s); + assert(name); + + assert(streq(s->bus_name, name)); + assert(old_owner || new_owner); + + if (old_owner && new_owner) + log_debug("%s's D-Bus name %s changed owner from %s to %s", u->id, name, old_owner, new_owner); + else if (old_owner) + log_debug("%s's D-Bus name %s no longer registered by %s", u->id, name, old_owner); + else + log_debug("%s's D-Bus name %s now registered by %s", u->id, name, new_owner); + + s->bus_name_good = !!new_owner; + + if (s->type == SERVICE_DBUS) { + + /* service_enter_running() will figure out what to + * do */ + if (s->state == SERVICE_RUNNING) + service_enter_running(s, SERVICE_SUCCESS); + else if (s->state == SERVICE_START && new_owner) + service_enter_start_post(s); + + } else if (new_owner && + s->main_pid <= 0 && + (s->state == SERVICE_START || + s->state == SERVICE_START_POST || + s->state == SERVICE_RUNNING || + s->state == SERVICE_RELOAD)) { + + /* Try to acquire PID from bus service */ + log_debug("Trying to acquire PID from D-Bus name..."); + + bus_query_pid(u->manager, name); + } +} + +static void service_bus_query_pid_done( + Unit *u, + const char *name, + pid_t pid) { + + Service *s = SERVICE(u); + + assert(s); + assert(name); + + log_debug("%s's D-Bus name %s is now owned by process %u", u->id, name, (unsigned) pid); + + if (s->main_pid <= 0 && + (s->state == SERVICE_START || + s->state == SERVICE_START_POST || + s->state == SERVICE_RUNNING || + s->state == SERVICE_RELOAD)) + service_set_main_pid(s, pid); +} + +int service_set_socket_fd(Service *s, int fd, Socket *sock) { + + assert(s); + assert(fd >= 0); + + /* This is called by the socket code when instantiating a new + * service for a stream socket and the socket needs to be + * configured. */ + + if (UNIT(s)->load_state != UNIT_LOADED) + return -EINVAL; + + if (s->socket_fd >= 0) + return -EBUSY; + + if (s->state != SERVICE_DEAD) + return -EAGAIN; + + s->socket_fd = fd; + s->got_socket_fd = true; + + unit_ref_set(&s->accept_socket, UNIT(sock)); + + return unit_add_two_dependencies(UNIT(sock), UNIT_BEFORE, UNIT_TRIGGERS, UNIT(s), false); +} + +static void service_reset_failed(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + + if (s->state == SERVICE_FAILED) + service_set_state(s, SERVICE_DEAD); + + s->result = SERVICE_SUCCESS; + s->reload_result = SERVICE_SUCCESS; +} + +static bool service_need_daemon_reload(Unit *u) { + Service *s = SERVICE(u); + + assert(s); + +#ifdef HAVE_SYSV_COMPAT + if (s->sysv_path) { + struct stat st; + + zero(st); + if (stat(s->sysv_path, &st) < 0) + /* What, cannot access this anymore? */ + return true; + + if (s->sysv_mtime > 0 && + timespec_load(&st.st_mtim) != s->sysv_mtime) + return true; + } +#endif + + return false; +} + +static int service_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) { + Service *s = SERVICE(u); + int r = 0; + Set *pid_set = NULL; + + assert(s); + + if (s->main_pid <= 0 && who == KILL_MAIN) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill"); + return -ESRCH; + } + + if (s->control_pid <= 0 && who == KILL_CONTROL) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill"); + return -ESRCH; + } + + if (who == KILL_CONTROL || who == KILL_ALL) + if (s->control_pid > 0) + if (kill(s->control_pid, signo) < 0) + r = -errno; + + if (who == KILL_MAIN || who == KILL_ALL) + if (s->main_pid > 0) + if (kill(s->main_pid, signo) < 0) + r = -errno; + + if (who == KILL_ALL && mode == KILL_CONTROL_GROUP) { + int q; + + if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + /* Exclude the control/main pid from being killed via the cgroup */ + if (s->control_pid > 0) + if ((q = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) { + r = q; + goto finish; + } + + if (s->main_pid > 0) + if ((q = set_put(pid_set, LONG_TO_PTR(s->main_pid))) < 0) { + r = q; + goto finish; + } + + if ((q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set)) < 0) + if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) + r = q; + } + +finish: + if (pid_set) + set_free(pid_set); + + return r; +} + +static const char* const service_state_table[_SERVICE_STATE_MAX] = { + [SERVICE_DEAD] = "dead", + [SERVICE_START_PRE] = "start-pre", + [SERVICE_START] = "start", + [SERVICE_START_POST] = "start-post", + [SERVICE_RUNNING] = "running", + [SERVICE_EXITED] = "exited", + [SERVICE_RELOAD] = "reload", + [SERVICE_STOP] = "stop", + [SERVICE_STOP_SIGTERM] = "stop-sigterm", + [SERVICE_STOP_SIGKILL] = "stop-sigkill", + [SERVICE_STOP_POST] = "stop-post", + [SERVICE_FINAL_SIGTERM] = "final-sigterm", + [SERVICE_FINAL_SIGKILL] = "final-sigkill", + [SERVICE_FAILED] = "failed", + [SERVICE_AUTO_RESTART] = "auto-restart", +}; + +DEFINE_STRING_TABLE_LOOKUP(service_state, ServiceState); + +static const char* const service_restart_table[_SERVICE_RESTART_MAX] = { + [SERVICE_RESTART_NO] = "no", + [SERVICE_RESTART_ON_SUCCESS] = "on-success", + [SERVICE_RESTART_ON_FAILURE] = "on-failure", + [SERVICE_RESTART_ON_ABORT] = "on-abort", + [SERVICE_RESTART_ALWAYS] = "always" +}; + +DEFINE_STRING_TABLE_LOOKUP(service_restart, ServiceRestart); + +static const char* const service_type_table[_SERVICE_TYPE_MAX] = { + [SERVICE_SIMPLE] = "simple", + [SERVICE_FORKING] = "forking", + [SERVICE_ONESHOT] = "oneshot", + [SERVICE_DBUS] = "dbus", + [SERVICE_NOTIFY] = "notify" +}; + +DEFINE_STRING_TABLE_LOOKUP(service_type, ServiceType); + +static const char* const service_exec_command_table[_SERVICE_EXEC_COMMAND_MAX] = { + [SERVICE_EXEC_START_PRE] = "ExecStartPre", + [SERVICE_EXEC_START] = "ExecStart", + [SERVICE_EXEC_START_POST] = "ExecStartPost", + [SERVICE_EXEC_RELOAD] = "ExecReload", + [SERVICE_EXEC_STOP] = "ExecStop", + [SERVICE_EXEC_STOP_POST] = "ExecStopPost", +}; + +DEFINE_STRING_TABLE_LOOKUP(service_exec_command, ServiceExecCommand); + +static const char* const notify_access_table[_NOTIFY_ACCESS_MAX] = { + [NOTIFY_NONE] = "none", + [NOTIFY_MAIN] = "main", + [NOTIFY_ALL] = "all" +}; + +DEFINE_STRING_TABLE_LOOKUP(notify_access, NotifyAccess); + +static const char* const service_result_table[_SERVICE_RESULT_MAX] = { + [SERVICE_SUCCESS] = "success", + [SERVICE_FAILURE_RESOURCES] = "resources", + [SERVICE_FAILURE_TIMEOUT] = "timeout", + [SERVICE_FAILURE_EXIT_CODE] = "exit-code", + [SERVICE_FAILURE_SIGNAL] = "signal", + [SERVICE_FAILURE_CORE_DUMP] = "core-dump", + [SERVICE_FAILURE_WATCHDOG] = "watchdog" +}; + +DEFINE_STRING_TABLE_LOOKUP(service_result, ServiceResult); + +static const char* const start_limit_action_table[_SERVICE_START_LIMIT_MAX] = { + [SERVICE_START_LIMIT_NONE] = "none", + [SERVICE_START_LIMIT_REBOOT] = "reboot", + [SERVICE_START_LIMIT_REBOOT_FORCE] = "reboot-force", + [SERVICE_START_LIMIT_REBOOT_IMMEDIATE] = "reboot-immediate" +}; +DEFINE_STRING_TABLE_LOOKUP(start_limit_action, StartLimitAction); + +const UnitVTable service_vtable = { + .suffix = ".service", + .object_size = sizeof(Service), + .sections = + "Unit\0" + "Service\0" + "Install\0", + .show_status = true, + + .init = service_init, + .done = service_done, + .load = service_load, + + .coldplug = service_coldplug, + + .dump = service_dump, + + .start = service_start, + .stop = service_stop, + .reload = service_reload, + + .can_reload = service_can_reload, + + .kill = service_kill, + + .serialize = service_serialize, + .deserialize_item = service_deserialize_item, + + .active_state = service_active_state, + .sub_state_to_string = service_sub_state_to_string, + + .check_gc = service_check_gc, + .check_snapshot = service_check_snapshot, + + .sigchld_event = service_sigchld_event, + .timer_event = service_timer_event, + .fd_event = service_fd_event, + + .reset_failed = service_reset_failed, + + .need_daemon_reload = service_need_daemon_reload, + + .cgroup_notify_empty = service_cgroup_notify_event, + .notify_message = service_notify_message, + + .bus_name_owner_change = service_bus_name_owner_change, + .bus_query_pid_done = service_bus_query_pid_done, + + .bus_interface = "org.freedesktop.systemd1.Service", + .bus_message_handler = bus_service_message_handler, + .bus_invalidating_properties = bus_service_invalidating_properties, + +#ifdef HAVE_SYSV_COMPAT + .enumerate = service_enumerate +#endif +}; diff --git a/src/service.h b/src/service.h new file mode 100644 index 0000000..60b1051 --- /dev/null +++ b/src/service.h @@ -0,0 +1,220 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooservicehfoo +#define fooservicehfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct Service Service; + +#include "unit.h" +#include "path.h" +#include "ratelimit.h" +#include "service.h" + +typedef enum ServiceState { + SERVICE_DEAD, + SERVICE_START_PRE, + SERVICE_START, + SERVICE_START_POST, + SERVICE_RUNNING, + SERVICE_EXITED, /* Nothing is running anymore, but RemainAfterExit is true hence this is OK */ + SERVICE_RELOAD, + SERVICE_STOP, /* No STOP_PRE state, instead just register multiple STOP executables */ + SERVICE_STOP_SIGTERM, + SERVICE_STOP_SIGKILL, + SERVICE_STOP_POST, + SERVICE_FINAL_SIGTERM, /* In case the STOP_POST executable hangs, we shoot that down, too */ + SERVICE_FINAL_SIGKILL, + SERVICE_FAILED, + SERVICE_AUTO_RESTART, + _SERVICE_STATE_MAX, + _SERVICE_STATE_INVALID = -1 +} ServiceState; + +typedef enum ServiceRestart { + SERVICE_RESTART_NO, + SERVICE_RESTART_ON_SUCCESS, + SERVICE_RESTART_ON_FAILURE, + SERVICE_RESTART_ON_ABORT, + SERVICE_RESTART_ALWAYS, + _SERVICE_RESTART_MAX, + _SERVICE_RESTART_INVALID = -1 +} ServiceRestart; + +typedef enum ServiceType { + SERVICE_SIMPLE, /* we fork and go on right-away (i.e. modern socket activated daemons) */ + SERVICE_FORKING, /* forks by itself (i.e. traditional daemons) */ + SERVICE_ONESHOT, /* we fork and wait until the program finishes (i.e. programs like fsck which run and need to finish before we continue) */ + SERVICE_DBUS, /* we fork and wait until a specific D-Bus name appears on the bus */ + SERVICE_NOTIFY, /* we fork and wait until a daemon sends us a ready message with sd_notify() */ + _SERVICE_TYPE_MAX, + _SERVICE_TYPE_INVALID = -1 +} ServiceType; + +typedef enum ServiceExecCommand { + SERVICE_EXEC_START_PRE, + SERVICE_EXEC_START, + SERVICE_EXEC_START_POST, + SERVICE_EXEC_RELOAD, + SERVICE_EXEC_STOP, + SERVICE_EXEC_STOP_POST, + _SERVICE_EXEC_COMMAND_MAX, + _SERVICE_EXEC_COMMAND_INVALID = -1 +} ServiceExecCommand; + +typedef enum NotifyAccess { + NOTIFY_NONE, + NOTIFY_ALL, + NOTIFY_MAIN, + _NOTIFY_ACCESS_MAX, + _NOTIFY_ACCESS_INVALID = -1 +} NotifyAccess; + +typedef enum ServiceResult { + SERVICE_SUCCESS, + SERVICE_FAILURE_RESOURCES, + SERVICE_FAILURE_TIMEOUT, + SERVICE_FAILURE_EXIT_CODE, + SERVICE_FAILURE_SIGNAL, + SERVICE_FAILURE_CORE_DUMP, + SERVICE_FAILURE_WATCHDOG, + _SERVICE_RESULT_MAX, + _SERVICE_RESULT_INVALID = -1 +} ServiceResult; + +typedef enum StartLimitAction { + SERVICE_START_LIMIT_NONE, + SERVICE_START_LIMIT_REBOOT, + SERVICE_START_LIMIT_REBOOT_FORCE, + SERVICE_START_LIMIT_REBOOT_IMMEDIATE, + _SERVICE_START_LIMIT_MAX, + _SERVICE_START_LIMIT_INVALID = -1 +} StartLimitAction; + +struct Service { + Unit meta; + + ServiceType type; + ServiceRestart restart; + + /* If set we'll read the main daemon PID from this file */ + char *pid_file; + + usec_t restart_usec; + usec_t timeout_usec; + + dual_timestamp watchdog_timestamp; + usec_t watchdog_usec; + Watch watchdog_watch; + + ExecCommand* exec_command[_SERVICE_EXEC_COMMAND_MAX]; + ExecContext exec_context; + + ServiceState state, deserialized_state; + + /* The exit status of the real main process */ + ExecStatus main_exec_status; + + /* The currently executed control process */ + ExecCommand *control_command; + + /* The currently executed main process, which may be NULL if + * the main process got started via forking mode and not by + * us */ + ExecCommand *main_command; + + /* The ID of the control command currently being executed */ + ServiceExecCommand control_command_id; + + pid_t main_pid, control_pid; + int socket_fd; + + int fsck_passno; + + bool permissions_start_only; + bool root_directory_start_only; + bool remain_after_exit; + bool guess_main_pid; + + /* If we shut down, remember why */ + ServiceResult result; + ServiceResult reload_result; + + bool main_pid_known:1; + bool main_pid_alien:1; + bool bus_name_good:1; + bool forbid_restart:1; + bool got_socket_fd:1; +#ifdef HAVE_SYSV_COMPAT + bool sysv_has_lsb:1; + bool sysv_enabled:1; + int sysv_start_priority_from_rcnd; + int sysv_start_priority; + + char *sysv_path; + char *sysv_runlevels; + usec_t sysv_mtime; +#endif + + char *bus_name; + + char *status_text; + + RateLimit start_limit; + StartLimitAction start_limit_action; + + + UnitRef accept_socket; + + Watch timer_watch; + PathSpec *pid_file_pathspec; + + NotifyAccess notify_access; +}; + +extern const UnitVTable service_vtable; + +struct Socket; + +int service_set_socket_fd(Service *s, int fd, struct Socket *socket); + +const char* service_state_to_string(ServiceState i); +ServiceState service_state_from_string(const char *s); + +const char* service_restart_to_string(ServiceRestart i); +ServiceRestart service_restart_from_string(const char *s); + +const char* service_type_to_string(ServiceType i); +ServiceType service_type_from_string(const char *s); + +const char* service_exec_command_to_string(ServiceExecCommand i); +ServiceExecCommand service_exec_command_from_string(const char *s); + +const char* notify_access_to_string(NotifyAccess i); +NotifyAccess notify_access_from_string(const char *s); + +const char* service_result_to_string(ServiceResult i); +ServiceResult service_result_from_string(const char *s); + +const char* start_limit_action_to_string(StartLimitAction i); +StartLimitAction start_limit_action_from_string(const char *s); + +#endif diff --git a/src/set.c b/src/set.c new file mode 100644 index 0000000..097b9d3 --- /dev/null +++ b/src/set.c @@ -0,0 +1,118 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "set.h" +#include "hashmap.h" + +#define MAKE_SET(h) ((Set*) (h)) +#define MAKE_HASHMAP(s) ((Hashmap*) (s)) + +/* For now this is not much more than a wrapper around a hashmap */ + +Set *set_new(hash_func_t hash_func, compare_func_t compare_func) { + return MAKE_SET(hashmap_new(hash_func, compare_func)); +} + +void set_free(Set* s) { + hashmap_free(MAKE_HASHMAP(s)); +} + +void set_free_free(Set *s) { + hashmap_free_free(MAKE_HASHMAP(s)); +} + +int set_ensure_allocated(Set **s, hash_func_t hash_func, compare_func_t compare_func) { + return hashmap_ensure_allocated((Hashmap**) s, hash_func, compare_func); +} + +int set_put(Set *s, void *value) { + return hashmap_put(MAKE_HASHMAP(s), value, value); +} + +int set_replace(Set *s, void *value) { + return hashmap_replace(MAKE_HASHMAP(s), value, value); +} + +void *set_get(Set *s, void *value) { + return hashmap_get(MAKE_HASHMAP(s), value); +} + +void *set_remove(Set *s, void *value) { + return hashmap_remove(MAKE_HASHMAP(s), value); +} + +int set_remove_and_put(Set *s, void *old_value, void *new_value) { + return hashmap_remove_and_put(MAKE_HASHMAP(s), old_value, new_value, new_value); +} + +unsigned set_size(Set *s) { + return hashmap_size(MAKE_HASHMAP(s)); +} + +bool set_isempty(Set *s) { + return hashmap_isempty(MAKE_HASHMAP(s)); +} + +void *set_iterate(Set *s, Iterator *i) { + return hashmap_iterate(MAKE_HASHMAP(s), i, NULL); +} + +void *set_iterate_backwards(Set *s, Iterator *i) { + return hashmap_iterate_backwards(MAKE_HASHMAP(s), i, NULL); +} + +void *set_iterate_skip(Set *s, void *value, Iterator *i) { + return hashmap_iterate_skip(MAKE_HASHMAP(s), value, i); +} + +void *set_steal_first(Set *s) { + return hashmap_steal_first(MAKE_HASHMAP(s)); +} + +void* set_first(Set *s) { + return hashmap_first(MAKE_HASHMAP(s)); +} + +void* set_last(Set *s) { + return hashmap_last(MAKE_HASHMAP(s)); +} + +int set_merge(Set *s, Set *other) { + return hashmap_merge(MAKE_HASHMAP(s), MAKE_HASHMAP(other)); +} + +void set_move(Set *s, Set *other) { + return hashmap_move(MAKE_HASHMAP(s), MAKE_HASHMAP(other)); +} + +int set_move_one(Set *s, Set *other, void *value) { + return hashmap_move_one(MAKE_HASHMAP(s), MAKE_HASHMAP(other), value); +} + +Set* set_copy(Set *s) { + return MAKE_SET(hashmap_copy(MAKE_HASHMAP(s))); +} + +void set_clear(Set *s) { + hashmap_clear(MAKE_HASHMAP(s)); +} diff --git a/src/set.h b/src/set.h new file mode 100644 index 0000000..885780c --- /dev/null +++ b/src/set.h @@ -0,0 +1,69 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosethfoo +#define foosethfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +/* Pretty straightforward set implementation. Internally based on the + * hashmap. That means that as a minor optimization a NULL set + * object will be treated as empty set for all read + * operations. That way it is not necessary to instantiate an object + * for each set use. */ + +#include "hashmap.h" + +typedef struct Set Set; + +Set *set_new(hash_func_t hash_func, compare_func_t compare_func); +void set_free(Set* s); +void set_free_free(Set *s); +Set* set_copy(Set *s); +int set_ensure_allocated(Set **s, hash_func_t hash_func, compare_func_t compare_func); + +int set_put(Set *s, void *value); +int set_replace(Set *s, void *value); +void *set_get(Set *s, void *value); +void *set_remove(Set *s, void *value); +int set_remove_and_put(Set *s, void *old_value, void *new_value); + +int set_merge(Set *s, Set *other); +void set_move(Set *s, Set *other); +int set_move_one(Set *s, Set *other, void *value); + +unsigned set_size(Set *s); +bool set_isempty(Set *s); + +void *set_iterate(Set *s, Iterator *i); +void *set_iterate_backwards(Set *s, Iterator *i); +void *set_iterate_skip(Set *s, void *value, Iterator *i); + +void set_clear(Set *s); +void *set_steal_first(Set *s); +void* set_first(Set *s); +void* set_last(Set *s); + +#define SET_FOREACH(e, s, i) \ + for ((i) = ITERATOR_FIRST, (e) = set_iterate((s), &(i)); (e); (e) = set_iterate((s), &(i))) + +#define SET_FOREACH_BACKWARDS(e, s, i) \ + for ((i) = ITERATOR_LAST, (e) = set_iterate_backwards((s), &(i)); (e); (e) = set_iterate_backwards((s), &(i))) + +#endif diff --git a/src/shutdown.c b/src/shutdown.c new file mode 100644 index 0000000..d157e0f --- /dev/null +++ b/src/shutdown.c @@ -0,0 +1,485 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 ProFUSION embedded systems + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "missing.h" +#include "log.h" +#include "umount.h" +#include "util.h" +#include "virt.h" + +#define TIMEOUT_USEC (5 * USEC_PER_SEC) +#define FINALIZE_ATTEMPTS 50 + +static bool ignore_proc(pid_t pid) { + char buf[PATH_MAX]; + FILE *f; + char c; + size_t count; + uid_t uid; + int r; + + /* We are PID 1, let's not commit suicide */ + if (pid == 1) + return true; + + r = get_process_uid(pid, &uid); + if (r < 0) + return true; /* not really, but better safe than sorry */ + + /* Non-root processes otherwise are always subject to be killed */ + if (uid != 0) + return false; + + snprintf(buf, sizeof(buf), "/proc/%lu/cmdline", (unsigned long) pid); + char_array_0(buf); + + f = fopen(buf, "re"); + if (!f) + return true; /* not really, but has the desired effect */ + + count = fread(&c, 1, 1, f); + fclose(f); + + /* Kernel threads have an empty cmdline */ + if (count <= 0) + return true; + + /* Processes with argv[0][0] = '@' we ignore from the killing + * spree. + * + * http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons */ + if (count == 1 && c == '@') + return true; + + return false; +} + +static int killall(int sign) { + DIR *dir; + struct dirent *d; + unsigned int n_processes = 0; + + dir = opendir("/proc"); + if (!dir) + return -errno; + + while ((d = readdir(dir))) { + pid_t pid; + + if (parse_pid(d->d_name, &pid) < 0) + continue; + + if (ignore_proc(pid)) + continue; + + if (kill(pid, sign) == 0) + n_processes++; + else + log_warning("Could not kill %d: %m", pid); + } + + closedir(dir); + + return n_processes; +} + +static void wait_for_children(int n_processes, sigset_t *mask) { + usec_t until; + + assert(mask); + + until = now(CLOCK_MONOTONIC) + TIMEOUT_USEC; + for (;;) { + struct timespec ts; + int k; + usec_t n; + + for (;;) { + pid_t pid = waitpid(-1, NULL, WNOHANG); + + if (pid == 0) + break; + + if (pid < 0 && errno == ECHILD) + return; + + if (n_processes > 0) + if (--n_processes == 0) + return; + } + + n = now(CLOCK_MONOTONIC); + if (n >= until) + return; + + timespec_store(&ts, until - n); + + if ((k = sigtimedwait(mask, NULL, &ts)) != SIGCHLD) { + + if (k < 0 && errno != EAGAIN) { + log_error("sigtimedwait() failed: %m"); + return; + } + + if (k >= 0) + log_warning("sigtimedwait() returned unexpected signal."); + } + } +} + +static void send_signal(int sign) { + sigset_t mask, oldmask; + int n_processes; + + assert_se(sigemptyset(&mask) == 0); + assert_se(sigaddset(&mask, SIGCHLD) == 0); + assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0); + + if (kill(-1, SIGSTOP) < 0 && errno != ESRCH) + log_warning("kill(-1, SIGSTOP) failed: %m"); + + n_processes = killall(sign); + + if (kill(-1, SIGCONT) < 0 && errno != ESRCH) + log_warning("kill(-1, SIGCONT) failed: %m"); + + if (n_processes <= 0) + goto finish; + + wait_for_children(n_processes, &mask); + +finish: + sigprocmask(SIG_SETMASK, &oldmask, NULL); +} + +static void ultimate_send_signal(int sign) { + sigset_t mask, oldmask; + int r; + + assert_se(sigemptyset(&mask) == 0); + assert_se(sigaddset(&mask, SIGCHLD) == 0); + assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0); + + if (kill(-1, SIGSTOP) < 0 && errno != ESRCH) + log_warning("kill(-1, SIGSTOP) failed: %m"); + + r = kill(-1, sign); + if (r < 0 && errno != ESRCH) + log_warning("kill(-1, %s) failed: %m", signal_to_string(sign)); + + if (kill(-1, SIGCONT) < 0 && errno != ESRCH) + log_warning("kill(-1, SIGCONT) failed: %m"); + + if (r < 0) + goto finish; + + wait_for_children(0, &mask); + +finish: + sigprocmask(SIG_SETMASK, &oldmask, NULL); +} + +static int prepare_new_root(void) { + static const char dirs[] = + "/run/initramfs/oldroot\0" + "/run/initramfs/proc\0" + "/run/initramfs/sys\0" + "/run/initramfs/dev\0" + "/run/initramfs/run\0"; + + const char *dir; + + if (mount("/run/initramfs", "/run/initramfs", NULL, MS_BIND, NULL) < 0) { + log_error("Failed to mount bind /run/initramfs on /run/initramfs: %m"); + return -errno; + } + + if (mount(NULL, "/run/initramfs", NULL, MS_PRIVATE, NULL) < 0) { + log_error("Failed to make /run/initramfs private mount: %m"); + return -errno; + } + + NULSTR_FOREACH(dir, dirs) + if (mkdir_p(dir, 0755) < 0 && errno != EEXIST) { + log_error("Failed to mkdir %s: %m", dir); + return -errno; + } + + if (mount("/sys", "/run/initramfs/sys", NULL, MS_BIND, NULL) < 0) { + log_error("Failed to mount bind /sys on /run/initramfs/sys: %m"); + return -errno; + } + + if (mount("/proc", "/run/initramfs/proc", NULL, MS_BIND, NULL) < 0) { + log_error("Failed to mount bind /proc on /run/initramfs/proc: %m"); + return -errno; + } + + if (mount("/dev", "/run/initramfs/dev", NULL, MS_BIND, NULL) < 0) { + log_error("Failed to mount bind /dev on /run/initramfs/dev: %m"); + return -errno; + } + + if (mount("/run", "/run/initramfs/run", NULL, MS_BIND, NULL) < 0) { + log_error("Failed to mount bind /run on /run/initramfs/run: %m"); + return -errno; + } + + return 0; +} + +static int pivot_to_new_root(void) { + int fd; + + chdir("/run/initramfs"); + + /* + In case some evil process made "/" MS_SHARED + It works for pivot_root, but the ref count for the root device + is not decreasing :-/ + */ + if (mount(NULL, "/", NULL, MS_PRIVATE, NULL) < 0) { + log_error("Failed to make \"/\" private mount %m"); + return -errno; + } + + if (pivot_root(".", "oldroot") < 0) { + log_error("pivot failed: %m"); + /* only chroot if pivot root succeded */ + return -errno; + } + + chroot("."); + log_info("Successfully changed into root pivot."); + + fd = open("/dev/console", O_RDWR); + if (fd < 0) + log_error("Failed to open /dev/console: %m"); + else { + make_stdio(fd); + + /* Initialize the controlling terminal */ + setsid(); + ioctl(STDIN_FILENO, TIOCSCTTY, NULL); + } + + return 0; +} + +int main(int argc, char *argv[]) { + int cmd, r; + unsigned retries; + bool need_umount = true, need_swapoff = true, need_loop_detach = true, need_dm_detach = true; + bool killed_everbody = false, in_container; + + log_parse_environment(); + log_set_target(LOG_TARGET_CONSOLE); /* syslog will die if not gone yet */ + log_open(); + + umask(0022); + + if (getpid() != 1) { + log_error("Not executed by init (pid 1)."); + r = -EPERM; + goto error; + } + + if (argc != 2) { + log_error("Invalid number of arguments."); + r = -EINVAL; + goto error; + } + + in_container = detect_container(NULL) > 0; + + if (streq(argv[1], "reboot")) + cmd = RB_AUTOBOOT; + else if (streq(argv[1], "poweroff")) + cmd = RB_POWER_OFF; + else if (streq(argv[1], "halt")) + cmd = RB_HALT_SYSTEM; + else if (streq(argv[1], "kexec")) + cmd = LINUX_REBOOT_CMD_KEXEC; + else { + log_error("Unknown action '%s'.", argv[1]); + r = -EINVAL; + goto error; + } + + /* lock us into memory */ + if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0) + log_warning("Cannot lock process memory: %m"); + + log_info("Sending SIGTERM to remaining processes..."); + send_signal(SIGTERM); + + log_info("Sending SIGKILL to remaining processes..."); + send_signal(SIGKILL); + + if (in_container) + need_swapoff = false; + + /* Unmount all mountpoints, swaps, and loopback devices */ + for (retries = 0; retries < FINALIZE_ATTEMPTS; retries++) { + bool changed = false; + + if (need_umount) { + log_info("Unmounting file systems."); + r = umount_all(&changed); + if (r == 0) + need_umount = false; + else if (r > 0) + log_info("Not all file systems unmounted, %d left.", r); + else + log_error("Failed to unmount file systems: %s", strerror(-r)); + } + + if (need_swapoff) { + log_info("Disabling swaps."); + r = swapoff_all(&changed); + if (r == 0) + need_swapoff = false; + else if (r > 0) + log_info("Not all swaps are turned off, %d left.", r); + else + log_error("Failed to turn off swaps: %s", strerror(-r)); + } + + if (need_loop_detach) { + log_info("Detaching loop devices."); + r = loopback_detach_all(&changed); + if (r == 0) + need_loop_detach = false; + else if (r > 0) + log_info("Not all loop devices detached, %d left.", r); + else + log_error("Failed to detach loop devices: %s", strerror(-r)); + } + + if (need_dm_detach) { + log_info("Detaching DM devices."); + r = dm_detach_all(&changed); + if (r == 0) + need_dm_detach = false; + else if (r > 0) + log_warning("Not all DM devices detached, %d left.", r); + else + log_error("Failed to detach DM devices: %s", strerror(-r)); + } + + if (!need_umount && !need_swapoff && !need_loop_detach && !need_dm_detach) { + if (retries > 0) + log_info("All filesystems, swaps, loop devices, DM devices detached."); + /* Yay, done */ + break; + } + + /* If in this iteration we didn't manage to + * unmount/deactivate anything, we either kill more + * processes, or simply give up */ + if (!changed) { + + if (killed_everbody) { + /* Hmm, we already killed everybody, + * let's just give up */ + log_error("Cannot finalize remaining file systems and devices, giving up."); + break; + } + + log_warning("Cannot finalize remaining file systems and devices, trying to kill remaining processes."); + ultimate_send_signal(SIGTERM); + ultimate_send_signal(SIGKILL); + killed_everbody = true; + } + + log_debug("Couldn't finalize remaining file systems and devices after %u retries, trying again.", retries+1); + } + + if (retries >= FINALIZE_ATTEMPTS) + log_error("Too many iterations, giving up."); + + execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, NULL); + + /* If we are in a container, just exit, this will kill our + * container for good. */ + if (in_container) { + log_error("Exiting container."); + exit(0); + } + + if (access("/run/initramfs/shutdown", X_OK) == 0) { + + if (prepare_new_root() >= 0 && + pivot_to_new_root() >= 0) { + execv("/shutdown", argv); + log_error("Failed to execute shutdown binary: %m"); + } + } + + sync(); + + if (cmd == LINUX_REBOOT_CMD_KEXEC) { + /* We cheat and exec kexec to avoid doing all its work */ + pid_t pid = fork(); + + if (pid < 0) + log_error("Could not fork: %m. Falling back to normal reboot."); + else if (pid > 0) { + wait_for_terminate_and_warn("kexec", pid); + log_warning("kexec failed. Falling back to normal reboot."); + } else { + /* Child */ + const char *args[3] = { "/sbin/kexec", "-e", NULL }; + execv(args[0], (char * const *) args); + return EXIT_FAILURE; + } + + cmd = RB_AUTOBOOT; + } + + reboot(cmd); + log_error("Failed to invoke reboot(): %m"); + r = -errno; + + error: + log_error("Critical error while doing system shutdown: %s", strerror(-r)); + + freeze(); + return EXIT_FAILURE; +} diff --git a/src/shutdownd.c b/src/shutdownd.c new file mode 100644 index 0000000..b4052d4 --- /dev/null +++ b/src/shutdownd.c @@ -0,0 +1,366 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "shutdownd.h" +#include "log.h" +#include "macro.h" +#include "util.h" +#include "utmp-wtmp.h" + +static int read_packet(int fd, struct shutdownd_command *_c) { + struct msghdr msghdr; + struct iovec iovec; + struct ucred *ucred; + union { + struct cmsghdr cmsghdr; + uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; + } control; + struct shutdownd_command c; + ssize_t n; + + assert(fd >= 0); + assert(_c); + + zero(iovec); + iovec.iov_base = &c; + iovec.iov_len = sizeof(c); + + zero(control); + zero(msghdr); + msghdr.msg_iov = &iovec; + msghdr.msg_iovlen = 1; + msghdr.msg_control = &control; + msghdr.msg_controllen = sizeof(control); + + if ((n = recvmsg(fd, &msghdr, MSG_DONTWAIT)) <= 0) { + if (n >= 0) { + log_error("Short read"); + return -EIO; + } + + if (errno == EAGAIN || errno == EINTR) + return 0; + + log_error("recvmsg(): %m"); + return -errno; + } + + if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) || + control.cmsghdr.cmsg_level != SOL_SOCKET || + control.cmsghdr.cmsg_type != SCM_CREDENTIALS || + control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) { + log_warning("Received message without credentials. Ignoring."); + return 0; + } + + ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr); + if (ucred->uid != 0) { + log_warning("Got request from unprivileged user. Ignoring."); + return 0; + } + + if (n != sizeof(c)) { + log_warning("Message has invalid size. Ignoring"); + return 0; + } + + char_array_0(c.wall_message); + + *_c = c; + return 1; +} + +static void warn_wall(usec_t n, struct shutdownd_command *c) { + char date[FORMAT_TIMESTAMP_MAX]; + const char *prefix; + char *l = NULL; + + assert(c); + assert(c->warn_wall); + + if (n >= c->elapse) + return; + + if (c->mode == 'H') + prefix = "The system is going down for system halt at "; + else if (c->mode == 'P') + prefix = "The system is going down for power-off at "; + else if (c->mode == 'r') + prefix = "The system is going down for reboot at "; + else + assert_not_reached("Unknown mode!"); + + if (asprintf(&l, "%s%s%s%s!", c->wall_message, c->wall_message[0] ? "\n" : "", + prefix, format_timestamp(date, sizeof(date), c->elapse)) < 0) + log_error("Failed to allocate wall message"); + else { + utmp_wall(l, NULL); + free(l); + } +} + +static usec_t when_wall(usec_t n, usec_t elapse) { + + static const struct { + usec_t delay; + usec_t interval; + } table[] = { + { 10 * USEC_PER_MINUTE, USEC_PER_MINUTE }, + { USEC_PER_HOUR, 15 * USEC_PER_MINUTE }, + { 3 * USEC_PER_HOUR, 30 * USEC_PER_MINUTE } + }; + + usec_t left, sub; + unsigned i; + + /* If the time is already passed, then don't announce */ + if (n >= elapse) + return 0; + + left = elapse - n; + for (i = 0; i < ELEMENTSOF(table); i++) + if (n + table[i].delay >= elapse) { + sub = ((left / table[i].interval) * table[i].interval); + break; + } + + if (i >= ELEMENTSOF(table)) + sub = ((left / USEC_PER_HOUR) * USEC_PER_HOUR); + + return elapse > sub ? elapse - sub : 1; +} + +static usec_t when_nologin(usec_t elapse) { + return elapse > 5*USEC_PER_MINUTE ? elapse - 5*USEC_PER_MINUTE : 1; +} + +int main(int argc, char *argv[]) { + enum { + FD_SOCKET, + FD_WALL_TIMER, + FD_NOLOGIN_TIMER, + FD_SHUTDOWN_TIMER, + _FD_MAX + }; + + int r = EXIT_FAILURE, n_fds; + struct shutdownd_command c; + struct pollfd pollfd[_FD_MAX]; + bool exec_shutdown = false, unlink_nologin = false, failed = false; + unsigned i; + + if (getppid() != 1) { + log_error("This program should be invoked by init only."); + return EXIT_FAILURE; + } + + if (argc > 1) { + log_error("This program does not take arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if ((n_fds = sd_listen_fds(true)) < 0) { + log_error("Failed to read listening file descriptors from environment: %s", strerror(-r)); + return EXIT_FAILURE; + } + + if (n_fds != 1) { + log_error("Need exactly one file descriptor."); + return EXIT_FAILURE; + } + + zero(c); + zero(pollfd); + + pollfd[FD_SOCKET].fd = SD_LISTEN_FDS_START; + pollfd[FD_SOCKET].events = POLLIN; + + for (i = 0; i < _FD_MAX; i++) { + + if (i == FD_SOCKET) + continue; + + pollfd[i].events = POLLIN; + + if ((pollfd[i].fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) { + log_error("timerfd_create(): %m"); + failed = true; + } + } + + if (failed) + goto finish; + + log_debug("systemd-shutdownd running as pid %lu", (unsigned long) getpid()); + + sd_notify(false, + "READY=1\n" + "STATUS=Processing requests..."); + + do { + int k; + usec_t n; + + if (poll(pollfd, _FD_MAX, -1) < 0) { + + if (errno == EAGAIN || errno == EINTR) + continue; + + log_error("poll(): %m"); + goto finish; + } + + n = now(CLOCK_REALTIME); + + if (pollfd[FD_SOCKET].revents) { + + if ((k = read_packet(pollfd[FD_SOCKET].fd, &c)) < 0) + goto finish; + else if (k > 0 && c.elapse > 0) { + struct itimerspec its; + char date[FORMAT_TIMESTAMP_MAX]; + + if (c.warn_wall) { + /* Send wall messages every so often */ + zero(its); + timespec_store(&its.it_value, when_wall(n, c.elapse)); + if (timerfd_settime(pollfd[FD_WALL_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) { + log_error("timerfd_settime(): %m"); + goto finish; + } + + /* Warn immediately if less than 15 minutes are left */ + if (n < c.elapse && + n + 15*USEC_PER_MINUTE >= c.elapse) + warn_wall(n, &c); + } + + /* Disallow logins 5 minutes prior to shutdown */ + zero(its); + timespec_store(&its.it_value, when_nologin(c.elapse)); + if (timerfd_settime(pollfd[FD_NOLOGIN_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) { + log_error("timerfd_settime(): %m"); + goto finish; + } + + /* Shutdown after the specified time is reached */ + zero(its); + timespec_store(&its.it_value, c.elapse); + if (timerfd_settime(pollfd[FD_SHUTDOWN_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) { + log_error("timerfd_settime(): %m"); + goto finish; + } + + sd_notifyf(false, + "STATUS=Shutting down at %s...", + format_timestamp(date, sizeof(date), c.elapse)); + } + } + + if (pollfd[FD_WALL_TIMER].revents) { + struct itimerspec its; + + warn_wall(n, &c); + flush_fd(pollfd[FD_WALL_TIMER].fd); + + /* Restart timer */ + zero(its); + timespec_store(&its.it_value, when_wall(n, c.elapse)); + if (timerfd_settime(pollfd[FD_WALL_TIMER].fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) { + log_error("timerfd_settime(): %m"); + goto finish; + } + } + + if (pollfd[FD_NOLOGIN_TIMER].revents) { + int e; + + log_info("Creating /run/nologin, blocking further logins..."); + + if ((e = write_one_line_file_atomic("/run/nologin", "System is going down.")) < 0) + log_error("Failed to create /run/nologin: %s", strerror(-e)); + else + unlink_nologin = true; + + flush_fd(pollfd[FD_NOLOGIN_TIMER].fd); + } + + if (pollfd[FD_SHUTDOWN_TIMER].revents) { + exec_shutdown = true; + goto finish; + } + + } while (c.elapse > 0); + + r = EXIT_SUCCESS; + + log_debug("systemd-shutdownd stopped as pid %lu", (unsigned long) getpid()); + +finish: + + for (i = 0; i < _FD_MAX; i++) + if (pollfd[i].fd >= 0) + close_nointr_nofail(pollfd[i].fd); + + if (unlink_nologin) + unlink("/run/nologin"); + + if (exec_shutdown && !c.dry_run) { + char sw[3]; + + sw[0] = '-'; + sw[1] = c.mode; + sw[2] = 0; + + execl(SYSTEMCTL_BINARY_PATH, + "shutdown", + sw, + "now", + (c.warn_wall && c.wall_message[0]) ? c.wall_message : + (c.warn_wall ? NULL : "--no-wall"), + NULL); + + log_error("Failed to execute /sbin/shutdown: %m"); + } + + sd_notify(false, + "STATUS=Exiting..."); + + return r; +} diff --git a/src/shutdownd.h b/src/shutdownd.h new file mode 100644 index 0000000..4581649 --- /dev/null +++ b/src/shutdownd.h @@ -0,0 +1,46 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooshutdowndhfoo +#define fooshutdowndhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "util.h" +#include "macro.h" + +/* This is a private message, we don't care much about ABI + * stability. */ + +_packed_ struct shutdownd_command { + usec_t elapse; + char mode; /* H, P, r, i.e. the switches usually passed to + * shutdown to select whether to halt, power-off or + * reboot the machine */ + bool dry_run; + bool warn_wall; + + /* Yepp, sometimes we are lazy and use fixed-size strings like + * this one. Shame on us. But then again, we'd have to + * pre-allocate the receive buffer anyway, so there's nothing + * too bad here. */ + char wall_message[4096]; +}; + +#endif diff --git a/src/snapshot.c b/src/snapshot.c new file mode 100644 index 0000000..82ec510 --- /dev/null +++ b/src/snapshot.c @@ -0,0 +1,309 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "unit.h" +#include "snapshot.h" +#include "unit-name.h" +#include "dbus-snapshot.h" +#include "bus-errors.h" + +static const UnitActiveState state_translation_table[_SNAPSHOT_STATE_MAX] = { + [SNAPSHOT_DEAD] = UNIT_INACTIVE, + [SNAPSHOT_ACTIVE] = UNIT_ACTIVE +}; + +static void snapshot_init(Unit *u) { + Snapshot *s = SNAPSHOT(u); + + assert(s); + assert(UNIT(s)->load_state == UNIT_STUB); + + UNIT(s)->ignore_on_isolate = true; + UNIT(s)->ignore_on_snapshot = true; +} + +static void snapshot_set_state(Snapshot *s, SnapshotState state) { + SnapshotState old_state; + assert(s); + + old_state = s->state; + s->state = state; + + if (state != old_state) + log_debug("%s changed %s -> %s", + UNIT(s)->id, + snapshot_state_to_string(old_state), + snapshot_state_to_string(state)); + + unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true); +} + +static int snapshot_load(Unit *u) { + Snapshot *s = SNAPSHOT(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + /* Make sure that only snapshots created via snapshot_create() + * can be loaded */ + if (!s->by_snapshot_create && UNIT(s)->manager->n_reloading <= 0) + return -ENOENT; + + u->load_state = UNIT_LOADED; + return 0; +} + +static int snapshot_coldplug(Unit *u) { + Snapshot *s = SNAPSHOT(u); + + assert(s); + assert(s->state == SNAPSHOT_DEAD); + + if (s->deserialized_state != s->state) + snapshot_set_state(s, s->deserialized_state); + + return 0; +} + +static void snapshot_dump(Unit *u, FILE *f, const char *prefix) { + Snapshot *s = SNAPSHOT(u); + + assert(s); + assert(f); + + fprintf(f, + "%sSnapshot State: %s\n" + "%sClean Up: %s\n", + prefix, snapshot_state_to_string(s->state), + prefix, yes_no(s->cleanup)); +} + +static int snapshot_start(Unit *u) { + Snapshot *s = SNAPSHOT(u); + + assert(s); + assert(s->state == SNAPSHOT_DEAD); + + snapshot_set_state(s, SNAPSHOT_ACTIVE); + + if (s->cleanup) + unit_add_to_cleanup_queue(u); + + return 0; +} + +static int snapshot_stop(Unit *u) { + Snapshot *s = SNAPSHOT(u); + + assert(s); + assert(s->state == SNAPSHOT_ACTIVE); + + snapshot_set_state(s, SNAPSHOT_DEAD); + return 0; +} + +static int snapshot_serialize(Unit *u, FILE *f, FDSet *fds) { + Snapshot *s = SNAPSHOT(u); + Unit *other; + Iterator i; + + assert(s); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", snapshot_state_to_string(s->state)); + unit_serialize_item(u, f, "cleanup", yes_no(s->cleanup)); + SET_FOREACH(other, u->dependencies[UNIT_WANTS], i) + unit_serialize_item(u, f, "wants", other->id); + + return 0; +} + +static int snapshot_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Snapshot *s = SNAPSHOT(u); + int r; + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + SnapshotState state; + + if ((state = snapshot_state_from_string(value)) < 0) + log_debug("Failed to parse state value %s", value); + else + s->deserialized_state = state; + + } else if (streq(key, "cleanup")) { + + if ((r = parse_boolean(value)) < 0) + log_debug("Failed to parse cleanup value %s", value); + else + s->cleanup = r; + + } else if (streq(key, "wants")) { + + if ((r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, value, NULL, true)) < 0) + return r; + } else + log_debug("Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState snapshot_active_state(Unit *u) { + assert(u); + + return state_translation_table[SNAPSHOT(u)->state]; +} + +static const char *snapshot_sub_state_to_string(Unit *u) { + assert(u); + + return snapshot_state_to_string(SNAPSHOT(u)->state); +} + +int snapshot_create(Manager *m, const char *name, bool cleanup, DBusError *e, Snapshot **_s) { + Iterator i; + Unit *other, *u = NULL; + char *n = NULL; + int r; + const char *k; + + assert(m); + assert(_s); + + if (name) { + if (!unit_name_is_valid(name, false)) { + dbus_set_error(e, BUS_ERROR_INVALID_NAME, "Unit name %s is not valid.", name); + return -EINVAL; + } + + if (unit_name_to_type(name) != UNIT_SNAPSHOT) { + dbus_set_error(e, BUS_ERROR_UNIT_TYPE_MISMATCH, "Unit name %s lacks snapshot suffix.", name); + return -EINVAL; + } + + if (manager_get_unit(m, name)) { + dbus_set_error(e, BUS_ERROR_UNIT_EXISTS, "Snapshot %s exists already.", name); + return -EEXIST; + } + + } else { + + for (;;) { + if (asprintf(&n, "snapshot-%u.snapshot", ++ m->n_snapshots) < 0) + return -ENOMEM; + + if (!manager_get_unit(m, n)) + break; + + free(n); + } + + name = n; + } + + r = manager_load_unit_prepare(m, name, NULL, e, &u); + free(n); + + if (r < 0) + goto fail; + + SNAPSHOT(u)->by_snapshot_create = true; + manager_dispatch_load_queue(m); + assert(u->load_state == UNIT_LOADED); + + HASHMAP_FOREACH_KEY(other, k, m->units, i) { + + if (other->ignore_on_snapshot) + continue; + + if (k != other->id) + continue; + + if (UNIT_VTABLE(other)->check_snapshot) + if (!UNIT_VTABLE(other)->check_snapshot(other)) + continue; + + if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + continue; + + if ((r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, other, true)) < 0) + goto fail; + } + + SNAPSHOT(u)->cleanup = cleanup; + *_s = SNAPSHOT(u); + + return 0; + +fail: + if (u) + unit_add_to_cleanup_queue(u); + + return r; +} + +void snapshot_remove(Snapshot *s) { + assert(s); + + unit_add_to_cleanup_queue(UNIT(s)); +} + +static const char* const snapshot_state_table[_SNAPSHOT_STATE_MAX] = { + [SNAPSHOT_DEAD] = "dead", + [SNAPSHOT_ACTIVE] = "active" +}; + +DEFINE_STRING_TABLE_LOOKUP(snapshot_state, SnapshotState); + +const UnitVTable snapshot_vtable = { + .suffix = ".snapshot", + .object_size = sizeof(Snapshot), + + .no_alias = true, + .no_instances = true, + .no_gc = true, + + .init = snapshot_init, + + .load = snapshot_load, + .coldplug = snapshot_coldplug, + + .dump = snapshot_dump, + + .start = snapshot_start, + .stop = snapshot_stop, + + .serialize = snapshot_serialize, + .deserialize_item = snapshot_deserialize_item, + + .active_state = snapshot_active_state, + .sub_state_to_string = snapshot_sub_state_to_string, + + .bus_interface = "org.freedesktop.systemd1.Snapshot", + .bus_message_handler = bus_snapshot_message_handler +}; diff --git a/src/snapshot.h b/src/snapshot.h new file mode 100644 index 0000000..bf92e99 --- /dev/null +++ b/src/snapshot.h @@ -0,0 +1,53 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosnapshothfoo +#define foosnapshothfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct Snapshot Snapshot; + +#include "unit.h" + +typedef enum SnapshotState { + SNAPSHOT_DEAD, + SNAPSHOT_ACTIVE, + _SNAPSHOT_STATE_MAX, + _SNAPSHOT_STATE_INVALID = -1 +} SnapshotState; + +struct Snapshot { + Unit meta; + + SnapshotState state, deserialized_state; + + bool cleanup; + bool by_snapshot_create:1; +}; + +extern const UnitVTable snapshot_vtable; + +int snapshot_create(Manager *m, const char *name, bool cleanup, DBusError *e, Snapshot **s); +void snapshot_remove(Snapshot *s); + +const char* snapshot_state_to_string(SnapshotState i); +SnapshotState snapshot_state_from_string(const char *s); + +#endif diff --git a/src/socket-util.c b/src/socket-util.c new file mode 100644 index 0000000..acc4d33 --- /dev/null +++ b/src/socket-util.c @@ -0,0 +1,652 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "util.h" +#include "socket-util.h" +#include "missing.h" +#include "label.h" + +int socket_address_parse(SocketAddress *a, const char *s) { + int r; + char *e, *n; + unsigned u; + + assert(a); + assert(s); + + zero(*a); + a->type = SOCK_STREAM; + + if (*s == '[') { + /* IPv6 in [x:.....:z]:p notation */ + + if (!socket_ipv6_is_supported()) { + log_warning("Binding to IPv6 address not available since kernel does not support IPv6."); + return -EAFNOSUPPORT; + } + + if (!(e = strchr(s+1, ']'))) + return -EINVAL; + + if (!(n = strndup(s+1, e-s-1))) + return -ENOMEM; + + errno = 0; + if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0) { + free(n); + return errno != 0 ? -errno : -EINVAL; + } + + free(n); + + e++; + if (*e != ':') + return -EINVAL; + + e++; + if ((r = safe_atou(e, &u)) < 0) + return r; + + if (u <= 0 || u > 0xFFFF) + return -EINVAL; + + a->sockaddr.in6.sin6_family = AF_INET6; + a->sockaddr.in6.sin6_port = htons((uint16_t) u); + a->size = sizeof(struct sockaddr_in6); + + } else if (*s == '/') { + /* AF_UNIX socket */ + + size_t l; + + l = strlen(s); + if (l >= sizeof(a->sockaddr.un.sun_path)) + return -EINVAL; + + a->sockaddr.un.sun_family = AF_UNIX; + memcpy(a->sockaddr.un.sun_path, s, l); + a->size = offsetof(struct sockaddr_un, sun_path) + l + 1; + + } else if (*s == '@') { + /* Abstract AF_UNIX socket */ + size_t l; + + l = strlen(s+1); + if (l >= sizeof(a->sockaddr.un.sun_path) - 1) + return -EINVAL; + + a->sockaddr.un.sun_family = AF_UNIX; + memcpy(a->sockaddr.un.sun_path+1, s+1, l); + a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l; + + } else { + + if ((e = strchr(s, ':'))) { + + if ((r = safe_atou(e+1, &u)) < 0) + return r; + + if (u <= 0 || u > 0xFFFF) + return -EINVAL; + + if (!(n = strndup(s, e-s))) + return -ENOMEM; + + /* IPv4 in w.x.y.z:p notation? */ + if ((r = inet_pton(AF_INET, n, &a->sockaddr.in4.sin_addr)) < 0) { + free(n); + return -errno; + } + + if (r > 0) { + /* Gotcha, it's a traditional IPv4 address */ + free(n); + + a->sockaddr.in4.sin_family = AF_INET; + a->sockaddr.in4.sin_port = htons((uint16_t) u); + a->size = sizeof(struct sockaddr_in); + } else { + unsigned idx; + + if (strlen(n) > IF_NAMESIZE-1) { + free(n); + return -EINVAL; + } + + /* Uh, our last resort, an interface name */ + idx = if_nametoindex(n); + free(n); + + if (idx == 0) + return -EINVAL; + + if (!socket_ipv6_is_supported()) { + log_warning("Binding to interface is not available since kernel does not support IPv6."); + return -EAFNOSUPPORT; + } + + a->sockaddr.in6.sin6_family = AF_INET6; + a->sockaddr.in6.sin6_port = htons((uint16_t) u); + a->sockaddr.in6.sin6_scope_id = idx; + a->sockaddr.in6.sin6_addr = in6addr_any; + a->size = sizeof(struct sockaddr_in6); + } + } else { + + /* Just a port */ + if ((r = safe_atou(s, &u)) < 0) + return r; + + if (u <= 0 || u > 0xFFFF) + return -EINVAL; + + if (socket_ipv6_is_supported()) { + a->sockaddr.in6.sin6_family = AF_INET6; + a->sockaddr.in6.sin6_port = htons((uint16_t) u); + a->sockaddr.in6.sin6_addr = in6addr_any; + a->size = sizeof(struct sockaddr_in6); + } else { + a->sockaddr.in4.sin_family = AF_INET; + a->sockaddr.in4.sin_port = htons((uint16_t) u); + a->sockaddr.in4.sin_addr.s_addr = INADDR_ANY; + a->size = sizeof(struct sockaddr_in); + } + } + } + + return 0; +} + +int socket_address_parse_netlink(SocketAddress *a, const char *s) { + int family; + unsigned group = 0; + char* sfamily = NULL; + assert(a); + assert(s); + + zero(*a); + a->type = SOCK_RAW; + + errno = 0; + if (sscanf(s, "%ms %u", &sfamily, &group) < 1) + return errno ? -errno : -EINVAL; + + if ((family = netlink_family_from_string(sfamily)) < 0) + if (safe_atoi(sfamily, &family) < 0) { + free(sfamily); + return -EINVAL; + } + + free(sfamily); + + a->sockaddr.nl.nl_family = AF_NETLINK; + a->sockaddr.nl.nl_groups = group; + + a->type = SOCK_RAW; + a->size = sizeof(struct sockaddr_nl); + a->protocol = family; + + return 0; +} + +int socket_address_verify(const SocketAddress *a) { + assert(a); + + switch (socket_address_family(a)) { + + case AF_INET: + if (a->size != sizeof(struct sockaddr_in)) + return -EINVAL; + + if (a->sockaddr.in4.sin_port == 0) + return -EINVAL; + + if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM) + return -EINVAL; + + return 0; + + case AF_INET6: + if (a->size != sizeof(struct sockaddr_in6)) + return -EINVAL; + + if (a->sockaddr.in6.sin6_port == 0) + return -EINVAL; + + if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM) + return -EINVAL; + + return 0; + + case AF_UNIX: + if (a->size < offsetof(struct sockaddr_un, sun_path)) + return -EINVAL; + + if (a->size > offsetof(struct sockaddr_un, sun_path)) { + + if (a->sockaddr.un.sun_path[0] != 0) { + char *e; + + /* path */ + if (!(e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path)))) + return -EINVAL; + + if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1) + return -EINVAL; + } + } + + if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM && a->type != SOCK_SEQPACKET) + return -EINVAL; + + return 0; + + case AF_NETLINK: + + if (a->size != sizeof(struct sockaddr_nl)) + return -EINVAL; + + if (a->type != SOCK_RAW && a->type != SOCK_DGRAM) + return -EINVAL; + + return 0; + + default: + return -EAFNOSUPPORT; + } +} + +int socket_address_print(const SocketAddress *a, char **p) { + int r; + assert(a); + assert(p); + + if ((r = socket_address_verify(a)) < 0) + return r; + + switch (socket_address_family(a)) { + + case AF_INET: { + char *ret; + + if (!(ret = new(char, INET_ADDRSTRLEN+1+5+1))) + return -ENOMEM; + + if (!inet_ntop(AF_INET, &a->sockaddr.in4.sin_addr, ret, INET_ADDRSTRLEN)) { + free(ret); + return -errno; + } + + sprintf(strchr(ret, 0), ":%u", ntohs(a->sockaddr.in4.sin_port)); + *p = ret; + return 0; + } + + case AF_INET6: { + char *ret; + + if (!(ret = new(char, 1+INET6_ADDRSTRLEN+2+5+1))) + return -ENOMEM; + + ret[0] = '['; + if (!inet_ntop(AF_INET6, &a->sockaddr.in6.sin6_addr, ret+1, INET6_ADDRSTRLEN)) { + free(ret); + return -errno; + } + + sprintf(strchr(ret, 0), "]:%u", ntohs(a->sockaddr.in6.sin6_port)); + *p = ret; + return 0; + } + + case AF_UNIX: { + char *ret; + + if (a->size <= offsetof(struct sockaddr_un, sun_path)) { + + if (!(ret = strdup(""))) + return -ENOMEM; + + } else if (a->sockaddr.un.sun_path[0] == 0) { + /* abstract */ + + /* FIXME: We assume we can print the + * socket path here and that it hasn't + * more than one NUL byte. That is + * actually an invalid assumption */ + + if (!(ret = new(char, sizeof(a->sockaddr.un.sun_path)+1))) + return -ENOMEM; + + ret[0] = '@'; + memcpy(ret+1, a->sockaddr.un.sun_path+1, sizeof(a->sockaddr.un.sun_path)-1); + ret[sizeof(a->sockaddr.un.sun_path)] = 0; + + } else { + + if (!(ret = strdup(a->sockaddr.un.sun_path))) + return -ENOMEM; + } + + *p = ret; + return 0; + } + + case AF_NETLINK: { + const char *sfamily; + + if ((sfamily = netlink_family_to_string(a->protocol))) + r = asprintf(p, "%s %u", sfamily, a->sockaddr.nl.nl_groups); + else + r = asprintf(p, "%i %u", a->protocol, a->sockaddr.nl.nl_groups); + + if (r < 0) + return -ENOMEM; + + return 0; + } + + default: + return -EINVAL; + } +} + +int socket_address_listen( + const SocketAddress *a, + int backlog, + SocketAddressBindIPv6Only only, + const char *bind_to_device, + bool free_bind, + bool transparent, + mode_t directory_mode, + mode_t socket_mode, + const char *label, + int *ret) { + + int r, fd, one; + assert(a); + assert(ret); + + if ((r = socket_address_verify(a)) < 0) + return r; + + if (socket_address_family(a) == AF_INET6 && !socket_ipv6_is_supported()) + return -EAFNOSUPPORT; + + r = label_socket_set(label); + if (r < 0) + return r; + + fd = socket(socket_address_family(a), a->type | SOCK_NONBLOCK | SOCK_CLOEXEC, a->protocol); + r = fd < 0 ? -errno : 0; + + label_socket_clear(); + + if (r < 0) + return r; + + if (socket_address_family(a) == AF_INET6 && only != SOCKET_ADDRESS_DEFAULT) { + int flag = only == SOCKET_ADDRESS_IPV6_ONLY; + + if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) < 0) + goto fail; + } + + if (socket_address_family(a) == AF_INET || socket_address_family(a) == AF_INET6) { + if (bind_to_device) + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, bind_to_device, strlen(bind_to_device)+1) < 0) + goto fail; + + if (free_bind) { + one = 1; + if (setsockopt(fd, IPPROTO_IP, IP_FREEBIND, &one, sizeof(one)) < 0) + log_warning("IP_FREEBIND failed: %m"); + } + + if (transparent) { + one = 1; + if (setsockopt(fd, IPPROTO_IP, IP_TRANSPARENT, &one, sizeof(one)) < 0) + log_warning("IP_TRANSPARENT failed: %m"); + } + } + + one = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) + goto fail; + + if (socket_address_family(a) == AF_UNIX && a->sockaddr.un.sun_path[0] != 0) { + mode_t old_mask; + + /* Create parents */ + mkdir_parents(a->sockaddr.un.sun_path, directory_mode); + + /* Enforce the right access mode for the socket*/ + old_mask = umask(~ socket_mode); + + /* Include the original umask in our mask */ + umask(~socket_mode | old_mask); + + r = label_bind(fd, &a->sockaddr.sa, a->size); + + if (r < 0 && errno == EADDRINUSE) { + /* Unlink and try again */ + unlink(a->sockaddr.un.sun_path); + r = bind(fd, &a->sockaddr.sa, a->size); + } + + umask(old_mask); + } else + r = bind(fd, &a->sockaddr.sa, a->size); + + if (r < 0) + goto fail; + + if (socket_address_can_accept(a)) + if (listen(fd, backlog) < 0) + goto fail; + + *ret = fd; + return 0; + +fail: + r = -errno; + close_nointr_nofail(fd); + return r; +} + +bool socket_address_can_accept(const SocketAddress *a) { + assert(a); + + return + a->type == SOCK_STREAM || + a->type == SOCK_SEQPACKET; +} + +bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) { + assert(a); + assert(b); + + /* Invalid addresses are unequal to all */ + if (socket_address_verify(a) < 0 || + socket_address_verify(b) < 0) + return false; + + if (a->type != b->type) + return false; + + if (a->size != b->size) + return false; + + if (socket_address_family(a) != socket_address_family(b)) + return false; + + switch (socket_address_family(a)) { + + case AF_INET: + if (a->sockaddr.in4.sin_addr.s_addr != b->sockaddr.in4.sin_addr.s_addr) + return false; + + if (a->sockaddr.in4.sin_port != b->sockaddr.in4.sin_port) + return false; + + break; + + case AF_INET6: + if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0) + return false; + + if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port) + return false; + + break; + + case AF_UNIX: + + if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0)) + return false; + + if (a->sockaddr.un.sun_path[0]) { + if (strncmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, sizeof(a->sockaddr.un.sun_path)) != 0) + return false; + } else { + if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0) + return false; + } + + break; + + case AF_NETLINK: + + if (a->protocol != b->protocol) + return false; + + if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups) + return false; + + break; + + default: + /* Cannot compare, so we assume the addresses are different */ + return false; + } + + return true; +} + +bool socket_address_is(const SocketAddress *a, const char *s, int type) { + struct SocketAddress b; + + assert(a); + assert(s); + + if (socket_address_parse(&b, s) < 0) + return false; + + b.type = type; + + return socket_address_equal(a, &b); +} + +bool socket_address_is_netlink(const SocketAddress *a, const char *s) { + struct SocketAddress b; + + assert(a); + assert(s); + + if (socket_address_parse_netlink(&b, s) < 0) + return false; + + return socket_address_equal(a, &b); +} + +bool socket_address_needs_mount(const SocketAddress *a, const char *prefix) { + assert(a); + + if (socket_address_family(a) != AF_UNIX) + return false; + + if (a->sockaddr.un.sun_path[0] == 0) + return false; + + return path_startswith(a->sockaddr.un.sun_path, prefix); +} + +bool socket_ipv6_is_supported(void) { + char *l = 0; + bool enabled; + + if (access("/sys/module/ipv6", F_OK) != 0) + return 0; + + /* If we can't check "disable" parameter, assume enabled */ + if (read_one_line_file("/sys/module/ipv6/parameters/disable", &l) < 0) + return 1; + + /* If module was loaded with disable=1 no IPv6 available */ + enabled = l[0] == '0'; + free(l); + + return enabled; +} + +static const char* const netlink_family_table[] = { + [NETLINK_ROUTE] = "route", + [NETLINK_FIREWALL] = "firewall", + [NETLINK_INET_DIAG] = "inet-diag", + [NETLINK_NFLOG] = "nflog", + [NETLINK_XFRM] = "xfrm", + [NETLINK_SELINUX] = "selinux", + [NETLINK_ISCSI] = "iscsi", + [NETLINK_AUDIT] = "audit", + [NETLINK_FIB_LOOKUP] = "fib-lookup", + [NETLINK_CONNECTOR] = "connector", + [NETLINK_NETFILTER] = "netfilter", + [NETLINK_IP6_FW] = "ip6-fw", + [NETLINK_DNRTMSG] = "dnrtmsg", + [NETLINK_KOBJECT_UEVENT] = "kobject-uevent", + [NETLINK_GENERIC] = "generic", + [NETLINK_SCSITRANSPORT] = "scsitransport", + [NETLINK_ECRYPTFS] = "ecryptfs" +}; + +DEFINE_STRING_TABLE_LOOKUP(netlink_family, int); + +static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = { + [SOCKET_ADDRESS_DEFAULT] = "default", + [SOCKET_ADDRESS_BOTH] = "both", + [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only" +}; + +DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only); diff --git a/src/socket-util.h b/src/socket-util.h new file mode 100644 index 0000000..8ccbd37 --- /dev/null +++ b/src/socket-util.h @@ -0,0 +1,102 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosocketutilhfoo +#define foosocketutilhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "util.h" + +union sockaddr_union { + struct sockaddr sa; + struct sockaddr_in in4; + struct sockaddr_in6 in6; + struct sockaddr_un un; + struct sockaddr_nl nl; + struct sockaddr_storage storage; +}; + +typedef struct SocketAddress { + union sockaddr_union sockaddr; + + /* We store the size here explicitly due to the weird + * sockaddr_un semantics for abstract sockets */ + socklen_t size; + + /* Socket type, i.e. SOCK_STREAM, SOCK_DGRAM, ... */ + int type; + + /* Socket protocol, IPPROTO_xxx, usually 0, except for netlink */ + int protocol; +} SocketAddress; + +typedef enum SocketAddressBindIPv6Only { + SOCKET_ADDRESS_DEFAULT, + SOCKET_ADDRESS_BOTH, + SOCKET_ADDRESS_IPV6_ONLY, + _SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX, + _SOCKET_ADDRESS_BIND_IPV6_ONLY_INVALID = -1 +} SocketAddressBindIPv6Only; + +#define socket_address_family(a) ((a)->sockaddr.sa.sa_family) + +int socket_address_parse(SocketAddress *a, const char *s); +int socket_address_parse_netlink(SocketAddress *a, const char *s); +int socket_address_print(const SocketAddress *a, char **p); +int socket_address_verify(const SocketAddress *a); + +bool socket_address_can_accept(const SocketAddress *a); + +int socket_address_listen( + const SocketAddress *a, + int backlog, + SocketAddressBindIPv6Only only, + const char *bind_to_device, + bool free_bind, + bool transparent, + mode_t directory_mode, + mode_t socket_mode, + const char *label, + int *ret); + +bool socket_address_is(const SocketAddress *a, const char *s, int type); +bool socket_address_is_netlink(const SocketAddress *a, const char *s); + +bool socket_address_equal(const SocketAddress *a, const SocketAddress *b); + +bool socket_address_needs_mount(const SocketAddress *a, const char *prefix); + +const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b); +SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s); + +const char* netlink_family_to_string(int b); +int netlink_family_from_string(const char *s); + +bool socket_ipv6_is_supported(void); + +#endif diff --git a/src/socket.c b/src/socket.c new file mode 100644 index 0000000..15a517b --- /dev/null +++ b/src/socket.c @@ -0,0 +1,2202 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "unit.h" +#include "socket.h" +#include "netinet/tcp.h" +#include "log.h" +#include "load-dropin.h" +#include "load-fragment.h" +#include "strv.h" +#include "unit-name.h" +#include "dbus-socket.h" +#include "missing.h" +#include "special.h" +#include "bus-errors.h" +#include "label.h" +#include "exit-status.h" +#include "def.h" + +static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = { + [SOCKET_DEAD] = UNIT_INACTIVE, + [SOCKET_START_PRE] = UNIT_ACTIVATING, + [SOCKET_START_POST] = UNIT_ACTIVATING, + [SOCKET_LISTENING] = UNIT_ACTIVE, + [SOCKET_RUNNING] = UNIT_ACTIVE, + [SOCKET_STOP_PRE] = UNIT_DEACTIVATING, + [SOCKET_STOP_PRE_SIGTERM] = UNIT_DEACTIVATING, + [SOCKET_STOP_PRE_SIGKILL] = UNIT_DEACTIVATING, + [SOCKET_STOP_POST] = UNIT_DEACTIVATING, + [SOCKET_FINAL_SIGTERM] = UNIT_DEACTIVATING, + [SOCKET_FINAL_SIGKILL] = UNIT_DEACTIVATING, + [SOCKET_FAILED] = UNIT_FAILED +}; + +static void socket_init(Unit *u) { + Socket *s = SOCKET(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + s->backlog = SOMAXCONN; + s->timeout_usec = DEFAULT_TIMEOUT_USEC; + s->directory_mode = 0755; + s->socket_mode = 0666; + + s->max_connections = 64; + + s->priority = -1; + s->ip_tos = -1; + s->ip_ttl = -1; + s->mark = -1; + + exec_context_init(&s->exec_context); + s->exec_context.std_output = u->manager->default_std_output; + s->exec_context.std_error = u->manager->default_std_error; + + s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID; +} + +static void socket_unwatch_control_pid(Socket *s) { + assert(s); + + if (s->control_pid <= 0) + return; + + unit_unwatch_pid(UNIT(s), s->control_pid); + s->control_pid = 0; +} + +static void socket_done(Unit *u) { + Socket *s = SOCKET(u); + SocketPort *p; + + assert(s); + + while ((p = s->ports)) { + LIST_REMOVE(SocketPort, port, s->ports, p); + + if (p->fd >= 0) { + unit_unwatch_fd(UNIT(s), &p->fd_watch); + close_nointr_nofail(p->fd); + } + + free(p->path); + free(p); + } + + exec_context_done(&s->exec_context); + exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX); + s->control_command = NULL; + + socket_unwatch_control_pid(s); + + unit_ref_unset(&s->service); + + free(s->tcp_congestion); + s->tcp_congestion = NULL; + + free(s->bind_to_device); + s->bind_to_device = NULL; + + unit_unwatch_timer(u, &s->timer_watch); +} + +static int socket_instantiate_service(Socket *s) { + char *prefix, *name; + int r; + Unit *u; + + assert(s); + + /* This fills in s->service if it isn't filled in yet. For + * Accept=yes sockets we create the next connection service + * here. For Accept=no this is mostly a NOP since the service + * is figured out at load time anyway. */ + + if (UNIT_DEREF(s->service)) + return 0; + + assert(s->accept); + + if (!(prefix = unit_name_to_prefix(UNIT(s)->id))) + return -ENOMEM; + + r = asprintf(&name, "%s@%u.service", prefix, s->n_accepted); + free(prefix); + + if (r < 0) + return -ENOMEM; + + r = manager_load_unit(UNIT(s)->manager, name, NULL, NULL, &u); + free(name); + + if (r < 0) + return r; + +#ifdef HAVE_SYSV_COMPAT + if (SERVICE(u)->sysv_path) { + log_error("Using SysV services for socket activation is not supported. Refusing."); + return -ENOENT; + } +#endif + + u->no_gc = true; + unit_ref_set(&s->service, u); + + return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false); +} + +static bool have_non_accept_socket(Socket *s) { + SocketPort *p; + + assert(s); + + if (!s->accept) + return true; + + LIST_FOREACH(port, p, s->ports) { + + if (p->type != SOCKET_SOCKET) + return true; + + if (!socket_address_can_accept(&p->address)) + return true; + } + + return false; +} + +static int socket_verify(Socket *s) { + assert(s); + + if (UNIT(s)->load_state != UNIT_LOADED) + return 0; + + if (!s->ports) { + log_error("%s lacks Listen setting. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->accept && have_non_accept_socket(s)) { + log_error("%s configured for accepting sockets, but sockets are non-accepting. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->accept && s->max_connections <= 0) { + log_error("%s's MaxConnection setting too small. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->accept && UNIT_DEREF(s->service)) { + log_error("Explicit service configuration for accepting sockets not supported on %s. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + if (s->exec_context.pam_name && s->exec_context.kill_mode != KILL_CONTROL_GROUP) { + log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + return 0; +} + +static bool socket_needs_mount(Socket *s, const char *prefix) { + SocketPort *p; + + assert(s); + + LIST_FOREACH(port, p, s->ports) { + + if (p->type == SOCKET_SOCKET) { + if (socket_address_needs_mount(&p->address, prefix)) + return true; + } else if (p->type == SOCKET_FIFO || p->type == SOCKET_SPECIAL) { + if (path_startswith(p->path, prefix)) + return true; + } + } + + return false; +} + +int socket_add_one_mount_link(Socket *s, Mount *m) { + int r; + + assert(s); + assert(m); + + if (UNIT(s)->load_state != UNIT_LOADED || + UNIT(m)->load_state != UNIT_LOADED) + return 0; + + if (!socket_needs_mount(s, m->where)) + return 0; + + if ((r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0) + return r; + + return 0; +} + +static int socket_add_mount_links(Socket *s) { + Unit *other; + int r; + + assert(s); + + LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT]) + if ((r = socket_add_one_mount_link(s, MOUNT(other))) < 0) + return r; + + return 0; +} + +static int socket_add_device_link(Socket *s) { + char *t; + int r; + + assert(s); + + if (!s->bind_to_device) + return 0; + + if (asprintf(&t, "/sys/subsystem/net/devices/%s", s->bind_to_device) < 0) + return -ENOMEM; + + r = unit_add_node_link(UNIT(s), t, false); + free(t); + + return r; +} + +static int socket_add_default_dependencies(Socket *s) { + int r; + assert(s); + + if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) { + if ((r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SOCKETS_TARGET, NULL, true)) < 0) + return r; + + if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true)) < 0) + return r; + } + + return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); +} + +static bool socket_has_exec(Socket *s) { + unsigned i; + assert(s); + + for (i = 0; i < _SOCKET_EXEC_COMMAND_MAX; i++) + if (s->exec_command[i]) + return true; + + return false; +} + +static int socket_load(Unit *u) { + Socket *s = SOCKET(u); + int r; + + assert(u); + assert(u->load_state == UNIT_STUB); + + if ((r = unit_load_fragment_and_dropin(u)) < 0) + return r; + + /* This is a new unit? Then let's add in some extras */ + if (u->load_state == UNIT_LOADED) { + + if (have_non_accept_socket(s)) { + + if (!UNIT_DEREF(s->service)) { + Unit *x; + + r = unit_load_related_unit(u, ".service", &x); + if (r < 0) + return r; + + unit_ref_set(&s->service, x); + } + + r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(s->service), true); + if (r < 0) + return r; + } + + if ((r = socket_add_mount_links(s)) < 0) + return r; + + if ((r = socket_add_device_link(s)) < 0) + return r; + + if (socket_has_exec(s)) + if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0) + return r; + + if ((r = unit_add_default_cgroups(u)) < 0) + return r; + + if (UNIT(s)->default_dependencies) + if ((r = socket_add_default_dependencies(s)) < 0) + return r; + } + + return socket_verify(s); +} + +static const char* listen_lookup(int family, int type) { + + if (family == AF_NETLINK) + return "ListenNetlink"; + + if (type == SOCK_STREAM) + return "ListenStream"; + else if (type == SOCK_DGRAM) + return "ListenDatagram"; + else if (type == SOCK_SEQPACKET) + return "ListenSequentialPacket"; + + assert_not_reached("Unknown socket type"); + return NULL; +} + +static void socket_dump(Unit *u, FILE *f, const char *prefix) { + + SocketExecCommand c; + Socket *s = SOCKET(u); + SocketPort *p; + const char *prefix2; + char *p2; + + assert(s); + assert(f); + + p2 = strappend(prefix, "\t"); + prefix2 = p2 ? p2 : prefix; + + fprintf(f, + "%sSocket State: %s\n" + "%sResult: %s\n" + "%sBindIPv6Only: %s\n" + "%sBacklog: %u\n" + "%sSocketMode: %04o\n" + "%sDirectoryMode: %04o\n" + "%sKeepAlive: %s\n" + "%sFreeBind: %s\n" + "%sTransparent: %s\n" + "%sBroadcast: %s\n" + "%sPassCredentials: %s\n" + "%sTCPCongestion: %s\n", + prefix, socket_state_to_string(s->state), + prefix, socket_result_to_string(s->result), + prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only), + prefix, s->backlog, + prefix, s->socket_mode, + prefix, s->directory_mode, + prefix, yes_no(s->keep_alive), + prefix, yes_no(s->free_bind), + prefix, yes_no(s->transparent), + prefix, yes_no(s->broadcast), + prefix, yes_no(s->pass_cred), + prefix, strna(s->tcp_congestion)); + + if (s->control_pid > 0) + fprintf(f, + "%sControl PID: %lu\n", + prefix, (unsigned long) s->control_pid); + + if (s->bind_to_device) + fprintf(f, + "%sBindToDevice: %s\n", + prefix, s->bind_to_device); + + if (s->accept) + fprintf(f, + "%sAccepted: %u\n" + "%sNConnections: %u\n" + "%sMaxConnections: %u\n", + prefix, s->n_accepted, + prefix, s->n_connections, + prefix, s->max_connections); + + if (s->priority >= 0) + fprintf(f, + "%sPriority: %i\n", + prefix, s->priority); + + if (s->receive_buffer > 0) + fprintf(f, + "%sReceiveBuffer: %zu\n", + prefix, s->receive_buffer); + + if (s->send_buffer > 0) + fprintf(f, + "%sSendBuffer: %zu\n", + prefix, s->send_buffer); + + if (s->ip_tos >= 0) + fprintf(f, + "%sIPTOS: %i\n", + prefix, s->ip_tos); + + if (s->ip_ttl >= 0) + fprintf(f, + "%sIPTTL: %i\n", + prefix, s->ip_ttl); + + if (s->pipe_size > 0) + fprintf(f, + "%sPipeSize: %zu\n", + prefix, s->pipe_size); + + if (s->mark >= 0) + fprintf(f, + "%sMark: %i\n", + prefix, s->mark); + + if (s->mq_maxmsg > 0) + fprintf(f, + "%sMessageQueueMaxMessages: %li\n", + prefix, s->mq_maxmsg); + + if (s->mq_msgsize > 0) + fprintf(f, + "%sMessageQueueMessageSize: %li\n", + prefix, s->mq_msgsize); + + LIST_FOREACH(port, p, s->ports) { + + if (p->type == SOCKET_SOCKET) { + const char *t; + int r; + char *k = NULL; + + if ((r = socket_address_print(&p->address, &k)) < 0) + t = strerror(-r); + else + t = k; + + fprintf(f, "%s%s: %s\n", prefix, listen_lookup(socket_address_family(&p->address), p->address.type), t); + free(k); + } else if (p->type == SOCKET_SPECIAL) + fprintf(f, "%sListenSpecial: %s\n", prefix, p->path); + else if (p->type == SOCKET_MQUEUE) + fprintf(f, "%sListenMessageQueue: %s\n", prefix, p->path); + else + fprintf(f, "%sListenFIFO: %s\n", prefix, p->path); + } + + exec_context_dump(&s->exec_context, f, prefix); + + for (c = 0; c < _SOCKET_EXEC_COMMAND_MAX; c++) { + if (!s->exec_command[c]) + continue; + + fprintf(f, "%s-> %s:\n", + prefix, socket_exec_command_to_string(c)); + + exec_command_dump_list(s->exec_command[c], f, prefix2); + } + + free(p2); +} + +static int instance_from_socket(int fd, unsigned nr, char **instance) { + socklen_t l; + char *r; + union { + struct sockaddr sa; + struct sockaddr_un un; + struct sockaddr_in in; + struct sockaddr_in6 in6; + struct sockaddr_storage storage; + } local, remote; + + assert(fd >= 0); + assert(instance); + + l = sizeof(local); + if (getsockname(fd, &local.sa, &l) < 0) + return -errno; + + l = sizeof(remote); + if (getpeername(fd, &remote.sa, &l) < 0) + return -errno; + + switch (local.sa.sa_family) { + + case AF_INET: { + uint32_t + a = ntohl(local.in.sin_addr.s_addr), + b = ntohl(remote.in.sin_addr.s_addr); + + if (asprintf(&r, + "%u.%u.%u.%u:%u-%u.%u.%u.%u:%u", + a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF, + ntohs(local.in.sin_port), + b >> 24, (b >> 16) & 0xFF, (b >> 8) & 0xFF, b & 0xFF, + ntohs(remote.in.sin_port)) < 0) + return -ENOMEM; + + break; + } + + case AF_INET6: { + static const char ipv4_prefix[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF + }; + + if (memcmp(&local.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0 && + memcmp(&remote.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) { + const uint8_t + *a = local.in6.sin6_addr.s6_addr+12, + *b = remote.in6.sin6_addr.s6_addr+12; + + if (asprintf(&r, + "%u.%u.%u.%u:%u-%u.%u.%u.%u:%u", + a[0], a[1], a[2], a[3], + ntohs(local.in6.sin6_port), + b[0], b[1], b[2], b[3], + ntohs(remote.in6.sin6_port)) < 0) + return -ENOMEM; + } else { + char a[INET6_ADDRSTRLEN], b[INET6_ADDRSTRLEN]; + + if (asprintf(&r, + "%s:%u-%s:%u", + inet_ntop(AF_INET6, &local.in6.sin6_addr, a, sizeof(a)), + ntohs(local.in6.sin6_port), + inet_ntop(AF_INET6, &remote.in6.sin6_addr, b, sizeof(b)), + ntohs(remote.in6.sin6_port)) < 0) + return -ENOMEM; + } + + break; + } + + case AF_UNIX: { + struct ucred ucred; + + l = sizeof(ucred); + if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0) + return -errno; + + if (asprintf(&r, + "%u-%lu-%lu", + nr, + (unsigned long) ucred.pid, + (unsigned long) ucred.uid) < 0) + return -ENOMEM; + + break; + } + + default: + assert_not_reached("Unhandled socket type."); + } + + *instance = r; + return 0; +} + +static void socket_close_fds(Socket *s) { + SocketPort *p; + + assert(s); + + LIST_FOREACH(port, p, s->ports) { + if (p->fd < 0) + continue; + + unit_unwatch_fd(UNIT(s), &p->fd_watch); + close_nointr_nofail(p->fd); + + /* One little note: we should never delete any sockets + * in the file system here! After all some other + * process we spawned might still have a reference of + * this fd and wants to continue to use it. Therefore + * we delete sockets in the file system before we + * create a new one, not after we stopped using + * one! */ + + p->fd = -1; + } +} + +static void socket_apply_socket_options(Socket *s, int fd) { + assert(s); + assert(fd >= 0); + + if (s->keep_alive) { + int b = s->keep_alive; + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &b, sizeof(b)) < 0) + log_warning("SO_KEEPALIVE failed: %m"); + } + + if (s->broadcast) { + int one = 1; + if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) < 0) + log_warning("SO_BROADCAST failed: %m"); + } + + if (s->pass_cred) { + int one = 1; + if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0) + log_warning("SO_PASSCRED failed: %m"); + } + + if (s->priority >= 0) + if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &s->priority, sizeof(s->priority)) < 0) + log_warning("SO_PRIORITY failed: %m"); + + if (s->receive_buffer > 0) { + int value = (int) s->receive_buffer; + + /* We first try with SO_RCVBUFFORCE, in case we have the perms for that */ + + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0) + log_warning("SO_RCVBUF failed: %m"); + } + + if (s->send_buffer > 0) { + int value = (int) s->send_buffer; + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0) + log_warning("SO_SNDBUF failed: %m"); + } + + if (s->mark >= 0) + if (setsockopt(fd, SOL_SOCKET, SO_MARK, &s->mark, sizeof(s->mark)) < 0) + log_warning("SO_MARK failed: %m"); + + if (s->ip_tos >= 0) + if (setsockopt(fd, IPPROTO_IP, IP_TOS, &s->ip_tos, sizeof(s->ip_tos)) < 0) + log_warning("IP_TOS failed: %m"); + + if (s->ip_ttl >= 0) { + int r, x; + + r = setsockopt(fd, IPPROTO_IP, IP_TTL, &s->ip_ttl, sizeof(s->ip_ttl)); + + if (socket_ipv6_is_supported()) + x = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &s->ip_ttl, sizeof(s->ip_ttl)); + else { + x = -1; + errno = EAFNOSUPPORT; + } + + if (r < 0 && x < 0) + log_warning("IP_TTL/IPV6_UNICAST_HOPS failed: %m"); + } + + if (s->tcp_congestion) + if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0) + log_warning("TCP_CONGESTION failed: %m"); +} + +static void socket_apply_fifo_options(Socket *s, int fd) { + assert(s); + assert(fd >= 0); + + if (s->pipe_size > 0) + if (fcntl(fd, F_SETPIPE_SZ, s->pipe_size) < 0) + log_warning("F_SETPIPE_SZ: %m"); +} + +static int fifo_address_create( + const char *path, + mode_t directory_mode, + mode_t socket_mode, + int *_fd) { + + int fd = -1, r = 0; + struct stat st; + mode_t old_mask; + + assert(path); + assert(_fd); + + mkdir_parents(path, directory_mode); + + if ((r = label_fifofile_set(path)) < 0) + goto fail; + + /* Enforce the right access mode for the fifo */ + old_mask = umask(~ socket_mode); + + /* Include the original umask in our mask */ + umask(~socket_mode | old_mask); + + r = mkfifo(path, socket_mode); + umask(old_mask); + + if (r < 0 && errno != EEXIST) { + r = -errno; + goto fail; + } + + if ((fd = open(path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) { + r = -errno; + goto fail; + } + + label_file_clear(); + + if (fstat(fd, &st) < 0) { + r = -errno; + goto fail; + } + + if (!S_ISFIFO(st.st_mode) || + (st.st_mode & 0777) != (socket_mode & ~old_mask) || + st.st_uid != getuid() || + st.st_gid != getgid()) { + + r = -EEXIST; + goto fail; + } + + *_fd = fd; + return 0; + +fail: + label_file_clear(); + + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +static int special_address_create( + const char *path, + int *_fd) { + + int fd = -1, r = 0; + struct stat st; + + assert(path); + assert(_fd); + + if ((fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) { + r = -errno; + goto fail; + } + + if (fstat(fd, &st) < 0) { + r = -errno; + goto fail; + } + + /* Check whether this is a /proc, /sys or /dev file or char device */ + if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) { + r = -EEXIST; + goto fail; + } + + *_fd = fd; + return 0; + +fail: + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +static int mq_address_create( + const char *path, + mode_t mq_mode, + long maxmsg, + long msgsize, + int *_fd) { + + int fd = -1, r = 0; + struct stat st; + mode_t old_mask; + struct mq_attr _attr, *attr = NULL; + + assert(path); + assert(_fd); + + if (maxmsg > 0 && msgsize > 0) { + zero(_attr); + _attr.mq_flags = O_NONBLOCK; + _attr.mq_maxmsg = maxmsg; + _attr.mq_msgsize = msgsize; + attr = &_attr; + } + + /* Enforce the right access mode for the mq */ + old_mask = umask(~ mq_mode); + + /* Include the original umask in our mask */ + umask(~mq_mode | old_mask); + + fd = mq_open(path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_CREAT, mq_mode, attr); + umask(old_mask); + + if (fd < 0) { + r = -errno; + goto fail; + } + + if (fstat(fd, &st) < 0) { + r = -errno; + goto fail; + } + + if ((st.st_mode & 0777) != (mq_mode & ~old_mask) || + st.st_uid != getuid() || + st.st_gid != getgid()) { + + r = -EEXIST; + goto fail; + } + + *_fd = fd; + return 0; + +fail: + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} + +static int socket_open_fds(Socket *s) { + SocketPort *p; + int r; + char *label = NULL; + bool know_label = false; + + assert(s); + + LIST_FOREACH(port, p, s->ports) { + + if (p->fd >= 0) + continue; + + if (p->type == SOCKET_SOCKET) { + + if (!know_label) { + + if ((r = socket_instantiate_service(s)) < 0) + return r; + + if (UNIT_DEREF(s->service) && + SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) { + r = label_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label); + + if (r < 0) { + if (r != -EPERM) + return r; + } + } + + know_label = true; + } + + if ((r = socket_address_listen( + &p->address, + s->backlog, + s->bind_ipv6_only, + s->bind_to_device, + s->free_bind, + s->transparent, + s->directory_mode, + s->socket_mode, + label, + &p->fd)) < 0) + goto rollback; + + socket_apply_socket_options(s, p->fd); + + } else if (p->type == SOCKET_SPECIAL) { + + if ((r = special_address_create( + p->path, + &p->fd)) < 0) + goto rollback; + + } else if (p->type == SOCKET_FIFO) { + + if ((r = fifo_address_create( + p->path, + s->directory_mode, + s->socket_mode, + &p->fd)) < 0) + goto rollback; + + socket_apply_fifo_options(s, p->fd); + } else if (p->type == SOCKET_MQUEUE) { + + if ((r = mq_address_create( + p->path, + s->socket_mode, + s->mq_maxmsg, + s->mq_msgsize, + &p->fd)) < 0) + goto rollback; + } else + assert_not_reached("Unknown port type"); + } + + label_free(label); + return 0; + +rollback: + socket_close_fds(s); + label_free(label); + return r; +} + +static void socket_unwatch_fds(Socket *s) { + SocketPort *p; + + assert(s); + + LIST_FOREACH(port, p, s->ports) { + if (p->fd < 0) + continue; + + unit_unwatch_fd(UNIT(s), &p->fd_watch); + } +} + +static int socket_watch_fds(Socket *s) { + SocketPort *p; + int r; + + assert(s); + + LIST_FOREACH(port, p, s->ports) { + if (p->fd < 0) + continue; + + p->fd_watch.socket_accept = + s->accept && + p->type == SOCKET_SOCKET && + socket_address_can_accept(&p->address); + + if ((r = unit_watch_fd(UNIT(s), p->fd, EPOLLIN, &p->fd_watch)) < 0) + goto fail; + } + + return 0; + +fail: + socket_unwatch_fds(s); + return r; +} + +static void socket_set_state(Socket *s, SocketState state) { + SocketState old_state; + assert(s); + + old_state = s->state; + s->state = state; + + if (state != SOCKET_START_PRE && + state != SOCKET_START_POST && + state != SOCKET_STOP_PRE && + state != SOCKET_STOP_PRE_SIGTERM && + state != SOCKET_STOP_PRE_SIGKILL && + state != SOCKET_STOP_POST && + state != SOCKET_FINAL_SIGTERM && + state != SOCKET_FINAL_SIGKILL) { + unit_unwatch_timer(UNIT(s), &s->timer_watch); + socket_unwatch_control_pid(s); + s->control_command = NULL; + s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID; + } + + if (state != SOCKET_LISTENING) + socket_unwatch_fds(s); + + if (state != SOCKET_START_POST && + state != SOCKET_LISTENING && + state != SOCKET_RUNNING && + state != SOCKET_STOP_PRE && + state != SOCKET_STOP_PRE_SIGTERM && + state != SOCKET_STOP_PRE_SIGKILL) + socket_close_fds(s); + + if (state != old_state) + log_debug("%s changed %s -> %s", + UNIT(s)->id, + socket_state_to_string(old_state), + socket_state_to_string(state)); + + unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true); +} + +static int socket_coldplug(Unit *u) { + Socket *s = SOCKET(u); + int r; + + assert(s); + assert(s->state == SOCKET_DEAD); + + if (s->deserialized_state != s->state) { + + if (s->deserialized_state == SOCKET_START_PRE || + s->deserialized_state == SOCKET_START_POST || + s->deserialized_state == SOCKET_STOP_PRE || + s->deserialized_state == SOCKET_STOP_PRE_SIGTERM || + s->deserialized_state == SOCKET_STOP_PRE_SIGKILL || + s->deserialized_state == SOCKET_STOP_POST || + s->deserialized_state == SOCKET_FINAL_SIGTERM || + s->deserialized_state == SOCKET_FINAL_SIGKILL) { + + if (s->control_pid <= 0) + return -EBADMSG; + + if ((r = unit_watch_pid(UNIT(s), s->control_pid)) < 0) + return r; + + if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) + return r; + } + + if (s->deserialized_state == SOCKET_START_POST || + s->deserialized_state == SOCKET_LISTENING || + s->deserialized_state == SOCKET_RUNNING || + s->deserialized_state == SOCKET_STOP_PRE || + s->deserialized_state == SOCKET_STOP_PRE_SIGTERM || + s->deserialized_state == SOCKET_STOP_PRE_SIGKILL) + if ((r = socket_open_fds(s)) < 0) + return r; + + if (s->deserialized_state == SOCKET_LISTENING) + if ((r = socket_watch_fds(s)) < 0) + return r; + + socket_set_state(s, s->deserialized_state); + } + + return 0; +} + +static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { + pid_t pid; + int r; + char **argv; + + assert(s); + assert(c); + assert(_pid); + + if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) + goto fail; + + if (!(argv = unit_full_printf_strv(UNIT(s), c->argv))) { + r = -ENOMEM; + goto fail; + } + + r = exec_spawn(c, + argv, + &s->exec_context, + NULL, 0, + UNIT(s)->manager->environment, + true, + true, + true, + UNIT(s)->manager->confirm_spawn, + UNIT(s)->cgroup_bondings, + UNIT(s)->cgroup_attributes, + &pid); + + strv_free(argv); + if (r < 0) + goto fail; + + if ((r = unit_watch_pid(UNIT(s), pid)) < 0) + /* FIXME: we need to do something here */ + goto fail; + + *_pid = pid; + + return 0; + +fail: + unit_unwatch_timer(UNIT(s), &s->timer_watch); + + return r; +} + +static void socket_enter_dead(Socket *s, SocketResult f) { + assert(s); + + if (f != SOCKET_SUCCESS) + s->result = f; + + socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD); +} + +static void socket_enter_signal(Socket *s, SocketState state, SocketResult f); + +static void socket_enter_stop_post(Socket *s, SocketResult f) { + int r; + assert(s); + + if (f != SOCKET_SUCCESS) + s->result = f; + + socket_unwatch_control_pid(s); + + s->control_command_id = SOCKET_EXEC_STOP_POST; + + if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST])) { + if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) + goto fail; + + socket_set_state(s, SOCKET_STOP_POST); + } else + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_SUCCESS); + + return; + +fail: + log_warning("%s failed to run 'stop-post' task: %s", UNIT(s)->id, strerror(-r)); + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES); +} + +static void socket_enter_signal(Socket *s, SocketState state, SocketResult f) { + int r; + Set *pid_set = NULL; + bool wait_for_exit = false; + + assert(s); + + if (f != SOCKET_SUCCESS) + s->result = f; + + if (s->exec_context.kill_mode != KILL_NONE) { + int sig = (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_FINAL_SIGTERM) ? s->exec_context.kill_signal : SIGKILL; + + if (s->control_pid > 0) { + if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH) + + log_warning("Failed to kill control process %li: %m", (long) s->control_pid); + else + wait_for_exit = true; + } + + if (s->exec_context.kill_mode == KILL_CONTROL_GROUP) { + + if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) { + r = -ENOMEM; + goto fail; + } + + /* Exclude the control pid from being killed via the cgroup */ + if (s->control_pid > 0) + if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) + goto fail; + + if ((r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set)) < 0) { + if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) + log_warning("Failed to kill control group: %s", strerror(-r)); + } else if (r > 0) + wait_for_exit = true; + + set_free(pid_set); + pid_set = NULL; + } + } + + if (wait_for_exit) { + if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) + goto fail; + + socket_set_state(s, state); + } else if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL) + socket_enter_stop_post(s, SOCKET_SUCCESS); + else + socket_enter_dead(s, SOCKET_SUCCESS); + + return; + +fail: + log_warning("%s failed to kill processes: %s", UNIT(s)->id, strerror(-r)); + + if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL) + socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES); + else + socket_enter_dead(s, SOCKET_FAILURE_RESOURCES); + + if (pid_set) + set_free(pid_set); +} + +static void socket_enter_stop_pre(Socket *s, SocketResult f) { + int r; + assert(s); + + if (f != SOCKET_SUCCESS) + s->result = f; + + socket_unwatch_control_pid(s); + + s->control_command_id = SOCKET_EXEC_STOP_PRE; + + if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE])) { + if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) + goto fail; + + socket_set_state(s, SOCKET_STOP_PRE); + } else + socket_enter_stop_post(s, SOCKET_SUCCESS); + + return; + +fail: + log_warning("%s failed to run 'stop-pre' task: %s", UNIT(s)->id, strerror(-r)); + socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES); +} + +static void socket_enter_listening(Socket *s) { + int r; + assert(s); + + r = socket_watch_fds(s); + if (r < 0) { + log_warning("%s failed to watch sockets: %s", UNIT(s)->id, strerror(-r)); + goto fail; + } + + socket_set_state(s, SOCKET_LISTENING); + return; + +fail: + socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); +} + +static void socket_enter_start_post(Socket *s) { + int r; + assert(s); + + r = socket_open_fds(s); + if (r < 0) { + log_warning("%s failed to listen on sockets: %s", UNIT(s)->id, strerror(-r)); + goto fail; + } + + socket_unwatch_control_pid(s); + + s->control_command_id = SOCKET_EXEC_START_POST; + + if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST])) { + r = socket_spawn(s, s->control_command, &s->control_pid); + if (r < 0) { + log_warning("%s failed to run 'start-post' task: %s", UNIT(s)->id, strerror(-r)); + goto fail; + } + + socket_set_state(s, SOCKET_START_POST); + } else + socket_enter_listening(s); + + return; + +fail: + socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); +} + +static void socket_enter_start_pre(Socket *s) { + int r; + assert(s); + + socket_unwatch_control_pid(s); + + s->control_command_id = SOCKET_EXEC_START_PRE; + + if ((s->control_command = s->exec_command[SOCKET_EXEC_START_PRE])) { + if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) + goto fail; + + socket_set_state(s, SOCKET_START_PRE); + } else + socket_enter_start_post(s); + + return; + +fail: + log_warning("%s failed to run 'start-pre' task: %s", UNIT(s)->id, strerror(-r)); + socket_enter_dead(s, SOCKET_FAILURE_RESOURCES); +} + +static void socket_enter_running(Socket *s, int cfd) { + int r; + DBusError error; + + assert(s); + dbus_error_init(&error); + + /* We don't take connections anymore if we are supposed to + * shut down anyway */ + if (unit_pending_inactive(UNIT(s))) { + log_debug("Suppressing connection request on %s since unit stop is scheduled.", UNIT(s)->id); + + if (cfd >= 0) + close_nointr_nofail(cfd); + else { + /* Flush all sockets by closing and reopening them */ + socket_close_fds(s); + + r = socket_watch_fds(s); + if (r < 0) { + log_warning("%s failed to watch sockets: %s", UNIT(s)->id, strerror(-r)); + socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); + } + } + + return; + } + + if (cfd < 0) { + Iterator i; + Unit *u; + bool pending = false; + + /* If there's already a start pending don't bother to + * do anything */ + SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERS], i) + if (unit_pending_active(u)) { + pending = true; + break; + } + + if (!pending) { + r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL); + if (r < 0) + goto fail; + } + + socket_set_state(s, SOCKET_RUNNING); + } else { + char *prefix, *instance = NULL, *name; + Service *service; + + if (s->n_connections >= s->max_connections) { + log_warning("Too many incoming connections (%u)", s->n_connections); + close_nointr_nofail(cfd); + return; + } + + r = socket_instantiate_service(s); + if (r < 0) + goto fail; + + r = instance_from_socket(cfd, s->n_accepted, &instance); + if (r < 0) { + if (r != -ENOTCONN) + goto fail; + + /* ENOTCONN is legitimate if TCP RST was received. + * This connection is over, but the socket unit lives on. */ + close_nointr_nofail(cfd); + return; + } + + prefix = unit_name_to_prefix(UNIT(s)->id); + if (!prefix) { + free(instance); + r = -ENOMEM; + goto fail; + } + + name = unit_name_build(prefix, instance, ".service"); + free(prefix); + free(instance); + + if (!name) { + r = -ENOMEM; + goto fail; + } + + r = unit_add_name(UNIT_DEREF(s->service), name); + if (r < 0) { + free(name); + goto fail; + } + + service = SERVICE(UNIT_DEREF(s->service)); + unit_ref_unset(&s->service); + s->n_accepted ++; + + UNIT(service)->no_gc = false; + + unit_choose_id(UNIT(service), name); + free(name); + + r = service_set_socket_fd(service, cfd, s); + if (r < 0) + goto fail; + + cfd = -1; + s->n_connections ++; + + r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(service), JOB_REPLACE, true, &error, NULL); + if (r < 0) + goto fail; + + /* Notify clients about changed counters */ + unit_add_to_dbus_queue(UNIT(s)); + } + + return; + +fail: + log_warning("%s failed to queue socket startup job: %s", UNIT(s)->id, bus_error(&error, r)); + socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); + + if (cfd >= 0) + close_nointr_nofail(cfd); + + dbus_error_free(&error); +} + +static void socket_run_next(Socket *s) { + int r; + + assert(s); + assert(s->control_command); + assert(s->control_command->command_next); + + socket_unwatch_control_pid(s); + + s->control_command = s->control_command->command_next; + + if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0) + goto fail; + + return; + +fail: + log_warning("%s failed to run next task: %s", UNIT(s)->id, strerror(-r)); + + if (s->state == SOCKET_START_POST) + socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); + else if (s->state == SOCKET_STOP_POST) + socket_enter_dead(s, SOCKET_FAILURE_RESOURCES); + else + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES); +} + +static int socket_start(Unit *u) { + Socket *s = SOCKET(u); + + assert(s); + + /* We cannot fulfill this request right now, try again later + * please! */ + if (s->state == SOCKET_STOP_PRE || + s->state == SOCKET_STOP_PRE_SIGKILL || + s->state == SOCKET_STOP_PRE_SIGTERM || + s->state == SOCKET_STOP_POST || + s->state == SOCKET_FINAL_SIGTERM || + s->state == SOCKET_FINAL_SIGKILL) + return -EAGAIN; + + if (s->state == SOCKET_START_PRE || + s->state == SOCKET_START_POST) + return 0; + + /* Cannot run this without the service being around */ + if (UNIT_DEREF(s->service)) { + Service *service; + + service = SERVICE(UNIT_DEREF(s->service)); + + if (UNIT(service)->load_state != UNIT_LOADED) { + log_error("Socket service %s not loaded, refusing.", UNIT(service)->id); + return -ENOENT; + } + + /* If the service is already active we cannot start the + * socket */ + if (service->state != SERVICE_DEAD && + service->state != SERVICE_FAILED && + service->state != SERVICE_AUTO_RESTART) { + log_error("Socket service %s already active, refusing.", UNIT(service)->id); + return -EBUSY; + } + +#ifdef HAVE_SYSV_COMPAT + if (service->sysv_path) { + log_error("Using SysV services for socket activation is not supported. Refusing."); + return -ENOENT; + } +#endif + } + + assert(s->state == SOCKET_DEAD || s->state == SOCKET_FAILED); + + s->result = SOCKET_SUCCESS; + socket_enter_start_pre(s); + return 0; +} + +static int socket_stop(Unit *u) { + Socket *s = SOCKET(u); + + assert(s); + + /* Already on it */ + if (s->state == SOCKET_STOP_PRE || + s->state == SOCKET_STOP_PRE_SIGTERM || + s->state == SOCKET_STOP_PRE_SIGKILL || + s->state == SOCKET_STOP_POST || + s->state == SOCKET_FINAL_SIGTERM || + s->state == SOCKET_FINAL_SIGKILL) + return 0; + + /* If there's already something running we go directly into + * kill mode. */ + if (s->state == SOCKET_START_PRE || + s->state == SOCKET_START_POST) { + socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_SUCCESS); + return -EAGAIN; + } + + assert(s->state == SOCKET_LISTENING || s->state == SOCKET_RUNNING); + + socket_enter_stop_pre(s, SOCKET_SUCCESS); + return 0; +} + +static int socket_serialize(Unit *u, FILE *f, FDSet *fds) { + Socket *s = SOCKET(u); + SocketPort *p; + int r; + + assert(u); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", socket_state_to_string(s->state)); + unit_serialize_item(u, f, "result", socket_result_to_string(s->result)); + unit_serialize_item_format(u, f, "n-accepted", "%u", s->n_accepted); + + if (s->control_pid > 0) + unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid); + + if (s->control_command_id >= 0) + unit_serialize_item(u, f, "control-command", socket_exec_command_to_string(s->control_command_id)); + + LIST_FOREACH(port, p, s->ports) { + int copy; + + if (p->fd < 0) + continue; + + if ((copy = fdset_put_dup(fds, p->fd)) < 0) + return copy; + + if (p->type == SOCKET_SOCKET) { + char *t; + + if ((r = socket_address_print(&p->address, &t)) < 0) + return r; + + if (socket_address_family(&p->address) == AF_NETLINK) + unit_serialize_item_format(u, f, "netlink", "%i %s", copy, t); + else + unit_serialize_item_format(u, f, "socket", "%i %i %s", copy, p->address.type, t); + free(t); + } else if (p->type == SOCKET_SPECIAL) + unit_serialize_item_format(u, f, "special", "%i %s", copy, p->path); + else { + assert(p->type == SOCKET_FIFO); + unit_serialize_item_format(u, f, "fifo", "%i %s", copy, p->path); + } + } + + return 0; +} + +static int socket_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Socket *s = SOCKET(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + SocketState state; + + if ((state = socket_state_from_string(value)) < 0) + log_debug("Failed to parse state value %s", value); + else + s->deserialized_state = state; + } else if (streq(key, "result")) { + SocketResult f; + + f = socket_result_from_string(value); + if (f < 0) + log_debug("Failed to parse result value %s", value); + else if (f != SOCKET_SUCCESS) + s->result = f; + + } else if (streq(key, "n-accepted")) { + unsigned k; + + if (safe_atou(value, &k) < 0) + log_debug("Failed to parse n-accepted value %s", value); + else + s->n_accepted += k; + } else if (streq(key, "control-pid")) { + pid_t pid; + + if (parse_pid(value, &pid) < 0) + log_debug("Failed to parse control-pid value %s", value); + else + s->control_pid = pid; + } else if (streq(key, "control-command")) { + SocketExecCommand id; + + if ((id = socket_exec_command_from_string(value)) < 0) + log_debug("Failed to parse exec-command value %s", value); + else { + s->control_command_id = id; + s->control_command = s->exec_command[id]; + } + } else if (streq(key, "fifo")) { + int fd, skip = 0; + SocketPort *p; + + if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd)) + log_debug("Failed to parse fifo value %s", value); + else { + + LIST_FOREACH(port, p, s->ports) + if (p->type == SOCKET_FIFO && + streq_ptr(p->path, value+skip)) + break; + + if (p) { + if (p->fd >= 0) + close_nointr_nofail(p->fd); + p->fd = fdset_remove(fds, fd); + } + } + + } else if (streq(key, "special")) { + int fd, skip = 0; + SocketPort *p; + + if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd)) + log_debug("Failed to parse special value %s", value); + else { + + LIST_FOREACH(port, p, s->ports) + if (p->type == SOCKET_SPECIAL && + streq_ptr(p->path, value+skip)) + break; + + if (p) { + if (p->fd >= 0) + close_nointr_nofail(p->fd); + p->fd = fdset_remove(fds, fd); + } + } + + } else if (streq(key, "socket")) { + int fd, type, skip = 0; + SocketPort *p; + + if (sscanf(value, "%i %i %n", &fd, &type, &skip) < 2 || fd < 0 || type < 0 || !fdset_contains(fds, fd)) + log_debug("Failed to parse socket value %s", value); + else { + + LIST_FOREACH(port, p, s->ports) + if (socket_address_is(&p->address, value+skip, type)) + break; + + if (p) { + if (p->fd >= 0) + close_nointr_nofail(p->fd); + p->fd = fdset_remove(fds, fd); + } + } + + } else if (streq(key, "netlink")) { + int fd, skip = 0; + SocketPort *p; + + if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd)) + log_debug("Failed to parse socket value %s", value); + else { + + LIST_FOREACH(port, p, s->ports) + if (socket_address_is_netlink(&p->address, value+skip)) + break; + + if (p) { + if (p->fd >= 0) + close_nointr_nofail(p->fd); + p->fd = fdset_remove(fds, fd); + } + } + + } else + log_debug("Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState socket_active_state(Unit *u) { + assert(u); + + return state_translation_table[SOCKET(u)->state]; +} + +static const char *socket_sub_state_to_string(Unit *u) { + assert(u); + + return socket_state_to_string(SOCKET(u)->state); +} + +static bool socket_check_gc(Unit *u) { + Socket *s = SOCKET(u); + + assert(u); + + return s->n_connections > 0; +} + +static void socket_fd_event(Unit *u, int fd, uint32_t events, Watch *w) { + Socket *s = SOCKET(u); + int cfd = -1; + + assert(s); + assert(fd >= 0); + + if (s->state != SOCKET_LISTENING) + return; + + log_debug("Incoming traffic on %s", u->id); + + if (events != EPOLLIN) { + + if (events & EPOLLHUP) + log_error("%s: Got POLLHUP on a listening socket. The service probably invoked shutdown() on it, and should better not do that.", u->id); + else + log_error("%s: Got unexpected poll event (0x%x) on socket.", u->id, events); + + goto fail; + } + + if (w->socket_accept) { + for (;;) { + + if ((cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK)) < 0) { + + if (errno == EINTR) + continue; + + log_error("Failed to accept socket: %m"); + goto fail; + } + + break; + } + + socket_apply_socket_options(s, cfd); + } + + socket_enter_running(s, cfd); + return; + +fail: + socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); +} + +static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) { + Socket *s = SOCKET(u); + SocketResult f; + + assert(s); + assert(pid >= 0); + + if (pid != s->control_pid) + return; + + s->control_pid = 0; + + if (is_clean_exit(code, status)) + f = SOCKET_SUCCESS; + else if (code == CLD_EXITED) + f = SOCKET_FAILURE_EXIT_CODE; + else if (code == CLD_KILLED) + f = SOCKET_FAILURE_SIGNAL; + else if (code == CLD_DUMPED) + f = SOCKET_FAILURE_CORE_DUMP; + else + assert_not_reached("Unknown code"); + + if (s->control_command) { + exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status); + + if (s->control_command->ignore) + f = SOCKET_SUCCESS; + } + + log_full(f == SOCKET_SUCCESS ? LOG_DEBUG : LOG_NOTICE, + "%s control process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status); + + if (f != SOCKET_SUCCESS) + s->result = f; + + if (s->control_command && + s->control_command->command_next && + f == SOCKET_SUCCESS) { + + log_debug("%s running next command for state %s", u->id, socket_state_to_string(s->state)); + socket_run_next(s); + } else { + s->control_command = NULL; + s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID; + + /* No further commands for this step, so let's figure + * out what to do next */ + + log_debug("%s got final SIGCHLD for state %s", u->id, socket_state_to_string(s->state)); + + switch (s->state) { + + case SOCKET_START_PRE: + if (f == SOCKET_SUCCESS) + socket_enter_start_post(s); + else + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, f); + break; + + case SOCKET_START_POST: + if (f == SOCKET_SUCCESS) + socket_enter_listening(s); + else + socket_enter_stop_pre(s, f); + break; + + case SOCKET_STOP_PRE: + case SOCKET_STOP_PRE_SIGTERM: + case SOCKET_STOP_PRE_SIGKILL: + socket_enter_stop_post(s, f); + break; + + case SOCKET_STOP_POST: + case SOCKET_FINAL_SIGTERM: + case SOCKET_FINAL_SIGKILL: + socket_enter_dead(s, f); + break; + + default: + assert_not_reached("Uh, control process died at wrong time."); + } + } + + /* Notify clients about changed exit status */ + unit_add_to_dbus_queue(u); +} + +static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) { + Socket *s = SOCKET(u); + + assert(s); + assert(elapsed == 1); + assert(w == &s->timer_watch); + + switch (s->state) { + + case SOCKET_START_PRE: + log_warning("%s starting timed out. Terminating.", u->id); + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT); + break; + + case SOCKET_START_POST: + log_warning("%s starting timed out. Stopping.", u->id); + socket_enter_stop_pre(s, SOCKET_FAILURE_TIMEOUT); + break; + + case SOCKET_STOP_PRE: + log_warning("%s stopping timed out. Terminating.", u->id); + socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_FAILURE_TIMEOUT); + break; + + case SOCKET_STOP_PRE_SIGTERM: + if (s->exec_context.send_sigkill) { + log_warning("%s stopping timed out. Killing.", u->id); + socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_FAILURE_TIMEOUT); + } else { + log_warning("%s stopping timed out. Skipping SIGKILL. Ignoring.", u->id); + socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT); + } + break; + + case SOCKET_STOP_PRE_SIGKILL: + log_warning("%s still around after SIGKILL. Ignoring.", u->id); + socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT); + break; + + case SOCKET_STOP_POST: + log_warning("%s stopping timed out (2). Terminating.", u->id); + socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT); + break; + + case SOCKET_FINAL_SIGTERM: + if (s->exec_context.send_sigkill) { + log_warning("%s stopping timed out (2). Killing.", u->id); + socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_FAILURE_TIMEOUT); + } else { + log_warning("%s stopping timed out (2). Skipping SIGKILL. Ignoring.", u->id); + socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT); + } + break; + + case SOCKET_FINAL_SIGKILL: + log_warning("%s still around after SIGKILL (2). Entering failed mode.", u->id); + socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT); + break; + + default: + assert_not_reached("Timeout at wrong time."); + } +} + +int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) { + int *rfds; + unsigned rn_fds, k; + SocketPort *p; + + assert(s); + assert(fds); + assert(n_fds); + + /* Called from the service code for requesting our fds */ + + rn_fds = 0; + LIST_FOREACH(port, p, s->ports) + if (p->fd >= 0) + rn_fds++; + + if (rn_fds <= 0) { + *fds = NULL; + *n_fds = 0; + return 0; + } + + if (!(rfds = new(int, rn_fds))) + return -ENOMEM; + + k = 0; + LIST_FOREACH(port, p, s->ports) + if (p->fd >= 0) + rfds[k++] = p->fd; + + assert(k == rn_fds); + + *fds = rfds; + *n_fds = rn_fds; + + return 0; +} + +void socket_notify_service_dead(Socket *s) { + assert(s); + + /* The service is dead. Dang! + * + * This is strictly for one-instance-for-all-connections + * services. */ + + if (s->state == SOCKET_RUNNING) { + log_debug("%s got notified about service death.", UNIT(s)->id); + socket_enter_listening(s); + } +} + +void socket_connection_unref(Socket *s) { + assert(s); + + /* The service is dead. Yay! + * + * This is strictly for one-instance-per-connection + * services. */ + + assert(s->n_connections > 0); + s->n_connections--; + + log_debug("%s: One connection closed, %u left.", UNIT(s)->id, s->n_connections); +} + +static void socket_reset_failed(Unit *u) { + Socket *s = SOCKET(u); + + assert(s); + + if (s->state == SOCKET_FAILED) + socket_set_state(s, SOCKET_DEAD); + + s->result = SOCKET_SUCCESS; +} + +static int socket_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) { + Socket *s = SOCKET(u); + int r = 0; + Set *pid_set = NULL; + + assert(s); + + if (who == KILL_MAIN) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Socket units have no main processes"); + return -ESRCH; + } + + if (s->control_pid <= 0 && who == KILL_CONTROL) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill"); + return -ESRCH; + } + + if (who == KILL_CONTROL || who == KILL_ALL) + if (s->control_pid > 0) + if (kill(s->control_pid, signo) < 0) + r = -errno; + + if (who == KILL_ALL && mode == KILL_CONTROL_GROUP) { + int q; + + if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + /* Exclude the control pid from being killed via the cgroup */ + if (s->control_pid > 0) + if ((q = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) { + r = q; + goto finish; + } + + if ((q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set)) < 0) + if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) + r = q; + } + +finish: + if (pid_set) + set_free(pid_set); + + return r; +} + +static const char* const socket_state_table[_SOCKET_STATE_MAX] = { + [SOCKET_DEAD] = "dead", + [SOCKET_START_PRE] = "start-pre", + [SOCKET_START_POST] = "start-post", + [SOCKET_LISTENING] = "listening", + [SOCKET_RUNNING] = "running", + [SOCKET_STOP_PRE] = "stop-pre", + [SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm", + [SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill", + [SOCKET_STOP_POST] = "stop-post", + [SOCKET_FINAL_SIGTERM] = "final-sigterm", + [SOCKET_FINAL_SIGKILL] = "final-sigkill", + [SOCKET_FAILED] = "failed" +}; + +DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState); + +static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = { + [SOCKET_EXEC_START_PRE] = "StartPre", + [SOCKET_EXEC_START_POST] = "StartPost", + [SOCKET_EXEC_STOP_PRE] = "StopPre", + [SOCKET_EXEC_STOP_POST] = "StopPost" +}; + +DEFINE_STRING_TABLE_LOOKUP(socket_exec_command, SocketExecCommand); + +static const char* const socket_result_table[_SOCKET_RESULT_MAX] = { + [SOCKET_SUCCESS] = "success", + [SOCKET_FAILURE_RESOURCES] = "resources", + [SOCKET_FAILURE_TIMEOUT] = "timeout", + [SOCKET_FAILURE_EXIT_CODE] = "exit-code", + [SOCKET_FAILURE_SIGNAL] = "signal", + [SOCKET_FAILURE_CORE_DUMP] = "core-dump" +}; + +DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult); + +const UnitVTable socket_vtable = { + .suffix = ".socket", + .object_size = sizeof(Socket), + .sections = + "Unit\0" + "Socket\0" + "Install\0", + + .init = socket_init, + .done = socket_done, + .load = socket_load, + + .kill = socket_kill, + + .coldplug = socket_coldplug, + + .dump = socket_dump, + + .start = socket_start, + .stop = socket_stop, + + .serialize = socket_serialize, + .deserialize_item = socket_deserialize_item, + + .active_state = socket_active_state, + .sub_state_to_string = socket_sub_state_to_string, + + .check_gc = socket_check_gc, + + .fd_event = socket_fd_event, + .sigchld_event = socket_sigchld_event, + .timer_event = socket_timer_event, + + .reset_failed = socket_reset_failed, + + .bus_interface = "org.freedesktop.systemd1.Socket", + .bus_message_handler = bus_socket_message_handler, + .bus_invalidating_properties = bus_socket_invalidating_properties +}; diff --git a/src/socket.h b/src/socket.h new file mode 100644 index 0000000..d242796 --- /dev/null +++ b/src/socket.h @@ -0,0 +1,171 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosockethfoo +#define foosockethfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct Socket Socket; + +#include "manager.h" +#include "unit.h" +#include "socket-util.h" +#include "mount.h" +#include "service.h" + +typedef enum SocketState { + SOCKET_DEAD, + SOCKET_START_PRE, + SOCKET_START_POST, + SOCKET_LISTENING, + SOCKET_RUNNING, + SOCKET_STOP_PRE, + SOCKET_STOP_PRE_SIGTERM, + SOCKET_STOP_PRE_SIGKILL, + SOCKET_STOP_POST, + SOCKET_FINAL_SIGTERM, + SOCKET_FINAL_SIGKILL, + SOCKET_FAILED, + _SOCKET_STATE_MAX, + _SOCKET_STATE_INVALID = -1 +} SocketState; + +typedef enum SocketExecCommand { + SOCKET_EXEC_START_PRE, + SOCKET_EXEC_START_POST, + SOCKET_EXEC_STOP_PRE, + SOCKET_EXEC_STOP_POST, + _SOCKET_EXEC_COMMAND_MAX, + _SOCKET_EXEC_COMMAND_INVALID = -1 +} SocketExecCommand; + +typedef enum SocketType { + SOCKET_SOCKET, + SOCKET_FIFO, + SOCKET_SPECIAL, + SOCKET_MQUEUE, + _SOCKET_FIFO_MAX, + _SOCKET_FIFO_INVALID = -1 +} SocketType; + +typedef enum SocketResult { + SOCKET_SUCCESS, + SOCKET_FAILURE_RESOURCES, + SOCKET_FAILURE_TIMEOUT, + SOCKET_FAILURE_EXIT_CODE, + SOCKET_FAILURE_SIGNAL, + SOCKET_FAILURE_CORE_DUMP, + _SOCKET_RESULT_MAX, + _SOCKET_RESULT_INVALID = -1 +} SocketResult; + +typedef struct SocketPort { + SocketType type; + int fd; + + SocketAddress address; + char *path; + Watch fd_watch; + + LIST_FIELDS(struct SocketPort, port); +} SocketPort; + +struct Socket { + Unit meta; + + LIST_HEAD(SocketPort, ports); + + unsigned n_accepted; + unsigned n_connections; + unsigned max_connections; + + unsigned backlog; + usec_t timeout_usec; + + ExecCommand* exec_command[_SOCKET_EXEC_COMMAND_MAX]; + ExecContext exec_context; + + /* For Accept=no sockets refers to the one service we'll + activate. For Accept=yes sockets is either NULL, or filled + when the next service we spawn. */ + UnitRef service; + + SocketState state, deserialized_state; + + Watch timer_watch; + + ExecCommand* control_command; + SocketExecCommand control_command_id; + pid_t control_pid; + + mode_t directory_mode; + mode_t socket_mode; + + SocketResult result; + + bool accept; + + /* Socket options */ + bool keep_alive; + bool free_bind; + bool transparent; + bool broadcast; + bool pass_cred; + int priority; + int mark; + size_t receive_buffer; + size_t send_buffer; + int ip_tos; + int ip_ttl; + size_t pipe_size; + char *bind_to_device; + char *tcp_congestion; + long mq_maxmsg; + long mq_msgsize; + + /* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */ + SocketAddressBindIPv6Only bind_ipv6_only; +}; + +/* Called from the service code when collecting fds */ +int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds); + +/* Called from the service when it shut down */ +void socket_notify_service_dead(Socket *s); + +/* Called from the mount code figure out if a mount is a dependency of + * any of the sockets of this socket */ +int socket_add_one_mount_link(Socket *s, Mount *m); + +/* Called from the service code when a per-connection service ended */ +void socket_connection_unref(Socket *s); + +extern const UnitVTable socket_vtable; + +const char* socket_state_to_string(SocketState i); +SocketState socket_state_from_string(const char *s); + +const char* socket_exec_command_to_string(SocketExecCommand i); +SocketExecCommand socket_exec_command_from_string(const char *s); + +const char* socket_result_to_string(SocketResult i); +SocketResult socket_result_from_string(const char *s); + +#endif diff --git a/src/spawn-agent.c b/src/spawn-agent.c new file mode 100644 index 0000000..2de2530 --- /dev/null +++ b/src/spawn-agent.c @@ -0,0 +1,120 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "spawn-agent.h" + +static pid_t agent_pid = 0; + +void agent_open(void) { + pid_t parent_pid; + + if (agent_pid > 0) + return; + + /* We check STDIN here, not STDOUT, since this is about input, + * not output */ + if (!isatty(STDIN_FILENO)) + return; + + parent_pid = getpid(); + + /* Spawns a temporary TTY agent, making sure it goes away when + * we go away */ + + agent_pid = fork(); + if (agent_pid < 0) { + log_error("Failed to fork agent: %m"); + return; + } + + if (agent_pid == 0) { + /* In the child */ + + int fd; + bool stdout_is_tty, stderr_is_tty; + + /* Make sure the agent goes away when the parent dies */ + if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) + _exit(EXIT_FAILURE); + + /* Check whether our parent died before we were able + * to set the death signal */ + if (getppid() != parent_pid) + _exit(EXIT_SUCCESS); + + /* Don't leak fds to the agent */ + close_all_fds(NULL, 0); + + stdout_is_tty = isatty(STDOUT_FILENO); + stderr_is_tty = isatty(STDERR_FILENO); + + if (!stdout_is_tty || !stderr_is_tty) { + /* Detach from stdout/stderr. and reopen + * /dev/tty for them. This is important to + * ensure that when systemctl is started via + * popen() or a similar call that expects to + * read EOF we actually do generate EOF and + * not delay this indefinitely by because we + * keep an unused copy of stdin around. */ + fd = open("/dev/tty", O_WRONLY); + if (fd < 0) { + log_error("Failed to open /dev/tty: %m"); + _exit(EXIT_FAILURE); + } + + if (!stdout_is_tty) + dup2(fd, STDOUT_FILENO); + + if (!stderr_is_tty) + dup2(fd, STDERR_FILENO); + + if (fd > 2) + close(fd); + } + + execl(SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH, "--watch", NULL); + + log_error("Unable to execute agent: %m"); + _exit(EXIT_FAILURE); + } +} + +void agent_close(void) { + + if (agent_pid <= 0) + return; + + /* Inform agent that we are done */ + kill(agent_pid, SIGTERM); + kill(agent_pid, SIGCONT); + wait_for_terminate(agent_pid, NULL); + agent_pid = 0; +} diff --git a/src/spawn-agent.h b/src/spawn-agent.h new file mode 100644 index 0000000..fd0a910 --- /dev/null +++ b/src/spawn-agent.h @@ -0,0 +1,28 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foospawnagenthfoo +#define foospawnagenthfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +void agent_open(void); +void agent_close(void); + +#endif diff --git a/src/special.h b/src/special.h new file mode 100644 index 0000000..8185eaf --- /dev/null +++ b/src/special.h @@ -0,0 +1,88 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foospecialhfoo +#define foospecialhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#define SPECIAL_DEFAULT_TARGET "default.target" + +/* Shutdown targets */ +#define SPECIAL_UMOUNT_TARGET "umount.target" +/* This is not really intended to be started by directly. This is + * mostly so that other targets (reboot/halt/poweroff) can depend on + * it to bring all services down that want to be brought down on + * system shutdown. */ +#define SPECIAL_SHUTDOWN_TARGET "shutdown.target" +#define SPECIAL_HALT_TARGET "halt.target" +#define SPECIAL_POWEROFF_TARGET "poweroff.target" +#define SPECIAL_REBOOT_TARGET "reboot.target" +#define SPECIAL_KEXEC_TARGET "kexec.target" +#define SPECIAL_EXIT_TARGET "exit.target" + +/* Special boot targets */ +#define SPECIAL_RESCUE_TARGET "rescue.target" +#define SPECIAL_EMERGENCY_TARGET "emergency.target" + +/* Early boot targets */ +#define SPECIAL_SYSINIT_TARGET "sysinit.target" +#define SPECIAL_SOCKETS_TARGET "sockets.target" +#define SPECIAL_LOCAL_FS_TARGET "local-fs.target" /* LSB's $local_fs */ +#define SPECIAL_LOCAL_FS_PRE_TARGET "local-fs-pre.target" +#define SPECIAL_REMOTE_FS_TARGET "remote-fs.target" /* LSB's $remote_fs */ +#define SPECIAL_REMOTE_FS_PRE_TARGET "remote-fs-pre.target" +#define SPECIAL_SWAP_TARGET "swap.target" +#define SPECIAL_BASIC_TARGET "basic.target" + +/* LSB compatibility */ +#define SPECIAL_NETWORK_TARGET "network.target" /* LSB's $network */ +#define SPECIAL_NSS_LOOKUP_TARGET "nss-lookup.target" /* LSB's $named */ +#define SPECIAL_RPCBIND_TARGET "rpcbind.target" /* LSB's $portmap */ +#define SPECIAL_SYSLOG_TARGET "syslog.target" /* LSB's $syslog; Should pull in syslog.socket or syslog.service */ +#define SPECIAL_TIME_SYNC_TARGET "time-sync.target" /* LSB's $time */ +#define SPECIAL_DISPLAY_MANAGER_SERVICE "display-manager.service" /* Debian's $x-display-manager */ +#define SPECIAL_MAIL_TRANSFER_AGENT_TARGET "mail-transfer-agent.target" /* Debian's $mail-{transport|transfer-agent */ +#define SPECIAL_HTTP_DAEMON_TARGET "http-daemon.target" + +/* Magic early boot services */ +#define SPECIAL_FSCK_SERVICE "fsck@.service" +#define SPECIAL_QUOTACHECK_SERVICE "quotacheck.service" +#define SPECIAL_QUOTAON_SERVICE "quotaon.service" +#define SPECIAL_REMOUNT_ROOTFS_SERVICE "remount-rootfs.service" + +/* Services systemd relies on */ +#define SPECIAL_DBUS_SERVICE "dbus.service" +#define SPECIAL_DBUS_SOCKET "dbus.socket" +#define SPECIAL_JOURNALD_SOCKET "systemd-journald.socket" +#define SPECIAL_JOURNALD_SERVICE "systemd-journald.service" + +/* Magic init signals */ +#define SPECIAL_KBREQUEST_TARGET "kbrequest.target" +#define SPECIAL_SIGPWR_TARGET "sigpwr.target" +#define SPECIAL_CTRL_ALT_DEL_TARGET "ctrl-alt-del.target" + +/* For SysV compatibility. Usually an alias for a saner target. On + * SysV-free systems this doesn't exist. */ +#define SPECIAL_RUNLEVEL2_TARGET "runlevel2.target" +#define SPECIAL_RUNLEVEL3_TARGET "runlevel3.target" +#define SPECIAL_RUNLEVEL4_TARGET "runlevel4.target" +#define SPECIAL_RUNLEVEL5_TARGET "runlevel5.target" + +#endif diff --git a/src/specifier.c b/src/specifier.c new file mode 100644 index 0000000..a9fff88 --- /dev/null +++ b/src/specifier.c @@ -0,0 +1,108 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "macro.h" +#include "util.h" +#include "specifier.h" + +/* + * Generic infrastructure for replacing %x style specifiers in + * strings. Will call a callback for each replacement. + * + */ + +char *specifier_printf(const char *text, const Specifier table[], void *userdata) { + char *r, *t; + const char *f; + bool percent = false; + size_t l; + + assert(text); + assert(table); + + l = strlen(text); + if (!(r = new(char, l+1))) + return NULL; + + t = r; + + for (f = text; *f; f++, l--) { + + if (percent) { + if (*f == '%') + *(t++) = '%'; + else { + const Specifier *i; + + for (i = table; i->specifier; i++) + if (i->specifier == *f) + break; + + if (i->lookup) { + char *n, *w; + size_t k, j; + + if (!(w = i->lookup(i->specifier, i->data, userdata))) { + free(r); + return NULL; + } + + j = t - r; + k = strlen(w); + + if (!(n = new(char, j + k + l + 1))) { + free(r); + free(w); + return NULL; + } + + memcpy(n, r, j); + memcpy(n + j, w, k); + + free(r); + free(w); + + r = n; + t = n + j + k; + } else { + *(t++) = '%'; + *(t++) = *f; + } + } + + percent = false; + } else if (*f == '%') + percent = true; + else + *(t++) = *f; + } + + *t = 0; + return r; +} + +/* Generic handler for simple string replacements */ + +char* specifier_string(char specifier, void *data, void *userdata) { + return strdup(strempty(data)); +} diff --git a/src/specifier.h b/src/specifier.h new file mode 100644 index 0000000..041166c --- /dev/null +++ b/src/specifier.h @@ -0,0 +1,37 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foospecifierhfoo +#define foospecifierhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef char* (*SpecifierCallback)(char specifier, void *data, void *userdata); + +typedef struct Specifier { + const char specifier; + const SpecifierCallback lookup; + void *data; +} Specifier; + +char *specifier_printf(const char *text, const Specifier table[], void *userdata); + +char* specifier_string(char specifier, void *data, void *userdata); + +#endif diff --git a/src/strv.c b/src/strv.c new file mode 100644 index 0000000..bb309d9 --- /dev/null +++ b/src/strv.c @@ -0,0 +1,690 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "util.h" +#include "strv.h" + +char *strv_find(char **l, const char *name) { + char **i; + + assert(name); + + STRV_FOREACH(i, l) + if (streq(*i, name)) + return *i; + + return NULL; +} + +char *strv_find_prefix(char **l, const char *name) { + char **i; + + assert(name); + + STRV_FOREACH(i, l) + if (startswith(*i, name)) + return *i; + + return NULL; +} + +void strv_free(char **l) { + char **k; + + if (!l) + return; + + for (k = l; *k; k++) + free(*k); + + free(l); +} + +char **strv_copy(char **l) { + char **r, **k; + + k = r = new(char*, strv_length(l)+1); + if (!k) + return NULL; + + if (l) + for (; *l; k++, l++) + if (!(*k = strdup(*l))) + goto fail; + + *k = NULL; + return r; + +fail: + for (k--; k >= r; k--) + free(*k); + + free(r); + + return NULL; +} + +unsigned strv_length(char **l) { + unsigned n = 0; + + if (!l) + return 0; + + for (; *l; l++) + n++; + + return n; +} + +char **strv_new_ap(const char *x, va_list ap) { + const char *s; + char **a; + unsigned n = 0, i = 0; + va_list aq; + + if (x) { + n = 1; + + va_copy(aq, ap); + while (va_arg(aq, const char*)) + n++; + va_end(aq); + } + + if (!(a = new(char*, n+1))) + return NULL; + + if (x) { + if (!(a[i] = strdup(x))) { + free(a); + return NULL; + } + + i++; + + while ((s = va_arg(ap, const char*))) { + if (!(a[i] = strdup(s))) + goto fail; + + i++; + } + } + + a[i] = NULL; + + return a; + +fail: + + for (; i > 0; i--) + if (a[i-1]) + free(a[i-1]); + + free(a); + + return NULL; +} + +char **strv_new(const char *x, ...) { + char **r; + va_list ap; + + va_start(ap, x); + r = strv_new_ap(x, ap); + va_end(ap); + + return r; +} + +char **strv_merge(char **a, char **b) { + char **r, **k; + + if (!a) + return strv_copy(b); + + if (!b) + return strv_copy(a); + + if (!(r = new(char*, strv_length(a)+strv_length(b)+1))) + return NULL; + + for (k = r; *a; k++, a++) + if (!(*k = strdup(*a))) + goto fail; + for (; *b; k++, b++) + if (!(*k = strdup(*b))) + goto fail; + + *k = NULL; + return r; + +fail: + for (k--; k >= r; k--) + free(*k); + + free(r); + + return NULL; +} + +char **strv_merge_concat(char **a, char **b, const char *suffix) { + char **r, **k; + + /* Like strv_merge(), but appends suffix to all strings in b, before adding */ + + if (!b) + return strv_copy(a); + + r = new(char*, strv_length(a) + strv_length(b) + 1); + if (!r) + return NULL; + + k = r; + if (a) + for (; *a; k++, a++) { + *k = strdup(*a); + if (!*k) + goto fail; + } + + for (; *b; k++, b++) { + *k = strappend(*b, suffix); + if (!*k) + goto fail; + } + + *k = NULL; + return r; + +fail: + for (k--; k >= r; k--) + free(*k); + + free(r); + + return NULL; + +} + +char **strv_split(const char *s, const char *separator) { + char *state; + char *w; + size_t l; + unsigned n, i; + char **r; + + assert(s); + + n = 0; + FOREACH_WORD_SEPARATOR(w, l, s, separator, state) + n++; + + if (!(r = new(char*, n+1))) + return NULL; + + i = 0; + FOREACH_WORD_SEPARATOR(w, l, s, separator, state) + if (!(r[i++] = strndup(w, l))) { + strv_free(r); + return NULL; + } + + r[i] = NULL; + return r; +} + +char **strv_split_quoted(const char *s) { + char *state; + char *w; + size_t l; + unsigned n, i; + char **r; + + assert(s); + + n = 0; + FOREACH_WORD_QUOTED(w, l, s, state) + n++; + + if (!(r = new(char*, n+1))) + return NULL; + + i = 0; + FOREACH_WORD_QUOTED(w, l, s, state) + if (!(r[i++] = cunescape_length(w, l))) { + strv_free(r); + return NULL; + } + + r[i] = NULL; + return r; +} + +char *strv_join(char **l, const char *separator) { + char *r, *e; + char **s; + size_t n, k; + + if (!separator) + separator = " "; + + k = strlen(separator); + + n = 0; + STRV_FOREACH(s, l) { + if (n != 0) + n += k; + n += strlen(*s); + } + + if (!(r = new(char, n+1))) + return NULL; + + e = r; + STRV_FOREACH(s, l) { + if (e != r) + e = stpcpy(e, separator); + + e = stpcpy(e, *s); + } + + *e = 0; + + return r; +} + +char **strv_append(char **l, const char *s) { + char **r, **k; + + if (!l) + return strv_new(s, NULL); + + if (!s) + return strv_copy(l); + + r = new(char*, strv_length(l)+2); + if (!r) + return NULL; + + for (k = r; *l; k++, l++) + if (!(*k = strdup(*l))) + goto fail; + + if (!(*(k++) = strdup(s))) + goto fail; + + *k = NULL; + return r; + +fail: + for (k--; k >= r; k--) + free(*k); + + free(r); + + return NULL; +} + +char **strv_uniq(char **l) { + char **i; + + /* Drops duplicate entries. The first identical string will be + * kept, the others dropped */ + + STRV_FOREACH(i, l) + strv_remove(i+1, *i); + + return l; +} + +char **strv_remove(char **l, const char *s) { + char **f, **t; + + if (!l) + return NULL; + + assert(s); + + /* Drops every occurrence of s in the string list, edits + * in-place. */ + + for (f = t = l; *f; f++) { + + if (streq(*f, s)) { + free(*f); + continue; + } + + *(t++) = *f; + } + + *t = NULL; + return l; +} + +static int env_append(char **r, char ***k, char **a) { + assert(r); + assert(k); + + if (!a) + return 0; + + /* Add the entries of a to *k unless they already exist in *r + * in which case they are overridden instead. This assumes + * there is enough space in the r array. */ + + for (; *a; a++) { + char **j; + size_t n; + + n = strcspn(*a, "="); + + if ((*a)[n] == '=') + n++; + + for (j = r; j < *k; j++) + if (strncmp(*j, *a, n) == 0) + break; + + if (j >= *k) + (*k)++; + else + free(*j); + + if (!(*j = strdup(*a))) + return -ENOMEM; + } + + return 0; +} + +char **strv_env_merge(unsigned n_lists, ...) { + size_t n = 0; + char **l, **k, **r; + va_list ap; + unsigned i; + + /* Merges an arbitrary number of environment sets */ + + va_start(ap, n_lists); + for (i = 0; i < n_lists; i++) { + l = va_arg(ap, char**); + n += strv_length(l); + } + va_end(ap); + + if (!(r = new(char*, n+1))) + return NULL; + + k = r; + + va_start(ap, n_lists); + for (i = 0; i < n_lists; i++) { + l = va_arg(ap, char**); + if (env_append(r, &k, l) < 0) + goto fail; + } + va_end(ap); + + *k = NULL; + + return r; + +fail: + va_end(ap); + + for (k--; k >= r; k--) + free(*k); + + free(r); + + return NULL; +} + +static bool env_match(const char *t, const char *pattern) { + assert(t); + assert(pattern); + + /* pattern a matches string a + * a matches a= + * a matches a=b + * a= matches a= + * a=b matches a=b + * a= does not match a + * a=b does not match a= + * a=b does not match a + * a=b does not match a=c */ + + if (streq(t, pattern)) + return true; + + if (!strchr(pattern, '=')) { + size_t l = strlen(pattern); + + return strncmp(t, pattern, l) == 0 && t[l] == '='; + } + + return false; +} + +char **strv_env_delete(char **x, unsigned n_lists, ...) { + size_t n, i = 0; + char **k, **r; + va_list ap; + + /* Deletes every entry from x that is mentioned in the other + * string lists */ + + n = strv_length(x); + + r = new(char*, n+1); + if (!r) + return NULL; + + STRV_FOREACH(k, x) { + unsigned v; + + va_start(ap, n_lists); + for (v = 0; v < n_lists; v++) { + char **l, **j; + + l = va_arg(ap, char**); + STRV_FOREACH(j, l) + if (env_match(*k, *j)) + goto skip; + } + va_end(ap); + + r[i] = strdup(*k); + if (!r[i]) { + strv_free(r); + return NULL; + } + + i++; + continue; + + skip: + va_end(ap); + } + + r[i] = NULL; + + assert(i <= n); + + return r; +} + +char **strv_env_unset(char **l, const char *p) { + + char **f, **t; + + if (!l) + return NULL; + + assert(p); + + /* Drops every occurrence of the env var setting p in the + * string list. edits in-place. */ + + for (f = t = l; *f; f++) { + + if (env_match(*f, p)) { + free(*f); + continue; + } + + *(t++) = *f; + } + + *t = NULL; + return l; +} + +char **strv_env_set(char **x, const char *p) { + + char **k, **r; + char* m[2] = { (char*) p, NULL }; + + /* Overrides the env var setting of p, returns a new copy */ + + if (!(r = new(char*, strv_length(x)+2))) + return NULL; + + k = r; + if (env_append(r, &k, x) < 0) + goto fail; + + if (env_append(r, &k, m) < 0) + goto fail; + + *k = NULL; + + return r; + +fail: + for (k--; k >= r; k--) + free(*k); + + free(r); + + return NULL; + +} + +char *strv_env_get_with_length(char **l, const char *name, size_t k) { + char **i; + + assert(name); + + STRV_FOREACH(i, l) + if (strncmp(*i, name, k) == 0 && + (*i)[k] == '=') + return *i + k + 1; + + return NULL; +} + +char *strv_env_get(char **l, const char *name) { + return strv_env_get_with_length(l, name, strlen(name)); +} + +char **strv_env_clean(char **l) { + char **r, **ret; + + for (r = ret = l; *l; l++) { + const char *equal; + + equal = strchr(*l, '='); + + if (equal && equal[1] == 0) { + free(*l); + continue; + } + + *(r++) = *l; + } + + *r = NULL; + + return ret; +} + +char **strv_parse_nulstr(const char *s, size_t l) { + const char *p; + unsigned c = 0, i = 0; + char **v; + + assert(s || l <= 0); + + if (l <= 0) + return strv_new(NULL, NULL); + + for (p = s; p < s + l; p++) + if (*p == 0) + c++; + + if (s[l-1] != 0) + c++; + + if (!(v = new0(char*, c+1))) + return NULL; + + p = s; + while (p < s + l) { + const char *e; + + e = memchr(p, 0, s + l - p); + + if (!(v[i++] = strndup(p, e ? e - p : s + l - p))) { + strv_free(v); + return NULL; + } + + if (!e) + break; + + p = e + 1; + } + + assert(i == c); + + return v; +} + +bool strv_overlap(char **a, char **b) { + char **i, **j; + + STRV_FOREACH(i, a) { + STRV_FOREACH(j, b) { + if (streq(*i, *j)) + return true; + } + } + + return false; +} diff --git a/src/strv.h b/src/strv.h new file mode 100644 index 0000000..d038c9f --- /dev/null +++ b/src/strv.h @@ -0,0 +1,79 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foostrvhfoo +#define foostrvhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "macro.h" + +char *strv_find(char **l, const char *name); +char *strv_find_prefix(char **l, const char *name); + +void strv_free(char **l); +char **strv_copy(char **l) _malloc_; +unsigned strv_length(char **l); + +char **strv_merge(char **a, char **b); +char **strv_merge_concat(char **a, char **b, const char *suffix); +char **strv_append(char **l, const char *s); + +char **strv_remove(char **l, const char *s); +char **strv_uniq(char **l); + +#define strv_contains(l, s) (!!strv_find((l), (s))) + +char **strv_new(const char *x, ...) _sentinel_ _malloc_; +char **strv_new_ap(const char *x, va_list ap) _malloc_; + +static inline bool strv_isempty(char **l) { + return !l || !*l; +} + +char **strv_split(const char *s, const char *separator) _malloc_; +char **strv_split_quoted(const char *s) _malloc_; + +char *strv_join(char **l, const char *separator) _malloc_; + +char **strv_env_merge(unsigned n_lists, ...); +char **strv_env_delete(char **x, unsigned n_lists, ...); + +char **strv_env_set(char **x, const char *p); +char **strv_env_unset(char **l, const char *p); + +char *strv_env_get_with_length(char **l, const char *name, size_t k); +char *strv_env_get(char **x, const char *n); + +char **strv_env_clean(char **l); + +char **strv_parse_nulstr(const char *s, size_t l); + +bool strv_overlap(char **a, char **b); + +#define STRV_FOREACH(s, l) \ + for ((s) = (l); (s) && *(s); (s)++) + +#define STRV_FOREACH_BACKWARDS(s, l) \ + for (; (l) && ((s) >= (l)); (s)--) + +#endif diff --git a/src/swap.c b/src/swap.c new file mode 100644 index 0000000..9c72732 --- /dev/null +++ b/src/swap.c @@ -0,0 +1,1415 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "unit.h" +#include "swap.h" +#include "load-fragment.h" +#include "load-dropin.h" +#include "unit-name.h" +#include "dbus-swap.h" +#include "special.h" +#include "bus-errors.h" +#include "exit-status.h" +#include "def.h" + +static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = { + [SWAP_DEAD] = UNIT_INACTIVE, + [SWAP_ACTIVATING] = UNIT_ACTIVATING, + [SWAP_ACTIVE] = UNIT_ACTIVE, + [SWAP_DEACTIVATING] = UNIT_DEACTIVATING, + [SWAP_ACTIVATING_SIGTERM] = UNIT_DEACTIVATING, + [SWAP_ACTIVATING_SIGKILL] = UNIT_DEACTIVATING, + [SWAP_DEACTIVATING_SIGTERM] = UNIT_DEACTIVATING, + [SWAP_DEACTIVATING_SIGKILL] = UNIT_DEACTIVATING, + [SWAP_FAILED] = UNIT_FAILED +}; + +static void swap_unset_proc_swaps(Swap *s) { + Swap *first; + + assert(s); + + if (!s->parameters_proc_swaps.what) + return; + + /* Remove this unit from the chain of swaps which share the + * same kernel swap device. */ + + first = hashmap_get(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what); + LIST_REMOVE(Swap, same_proc_swaps, first, s); + + if (first) + hashmap_remove_and_replace(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what, first->parameters_proc_swaps.what, first); + else + hashmap_remove(UNIT(s)->manager->swaps_by_proc_swaps, s->parameters_proc_swaps.what); + + free(s->parameters_proc_swaps.what); + s->parameters_proc_swaps.what = NULL; +} + +static void swap_init(Unit *u) { + Swap *s = SWAP(u); + + assert(s); + assert(UNIT(s)->load_state == UNIT_STUB); + + s->timeout_usec = DEFAULT_TIMEOUT_USEC; + + exec_context_init(&s->exec_context); + s->exec_context.std_output = u->manager->default_std_output; + s->exec_context.std_error = u->manager->default_std_error; + + s->parameters_etc_fstab.priority = s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1; + + s->timer_watch.type = WATCH_INVALID; + + s->control_command_id = _SWAP_EXEC_COMMAND_INVALID; + + UNIT(s)->ignore_on_isolate = true; +} + +static void swap_unwatch_control_pid(Swap *s) { + assert(s); + + if (s->control_pid <= 0) + return; + + unit_unwatch_pid(UNIT(s), s->control_pid); + s->control_pid = 0; +} + +static void swap_done(Unit *u) { + Swap *s = SWAP(u); + + assert(s); + + swap_unset_proc_swaps(s); + + free(s->what); + s->what = NULL; + + free(s->parameters_etc_fstab.what); + free(s->parameters_fragment.what); + s->parameters_etc_fstab.what = s->parameters_fragment.what = NULL; + + exec_context_done(&s->exec_context); + exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX); + s->control_command = NULL; + + swap_unwatch_control_pid(s); + + unit_unwatch_timer(u, &s->timer_watch); +} + +int swap_add_one_mount_link(Swap *s, Mount *m) { + int r; + + assert(s); + assert(m); + + if (UNIT(s)->load_state != UNIT_LOADED || + UNIT(m)->load_state != UNIT_LOADED) + return 0; + + if (is_device_path(s->what)) + return 0; + + if (!path_startswith(s->what, m->where)) + return 0; + + if ((r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0) + return r; + + return 0; +} + +static int swap_add_mount_links(Swap *s) { + Unit *other; + int r; + + assert(s); + + LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT]) + if ((r = swap_add_one_mount_link(s, MOUNT(other))) < 0) + return r; + + return 0; +} + +static int swap_add_target_links(Swap *s) { + Unit *tu; + SwapParameters *p; + int r; + + assert(s); + + if (s->from_fragment) + p = &s->parameters_fragment; + else if (s->from_etc_fstab) + p = &s->parameters_etc_fstab; + else + return 0; + + if ((r = manager_load_unit(UNIT(s)->manager, SPECIAL_SWAP_TARGET, NULL, NULL, &tu)) < 0) + return r; + + if (!p->noauto && + !p->nofail && + (p->handle || UNIT(s)->manager->swap_auto) && + s->from_etc_fstab && + UNIT(s)->manager->running_as == MANAGER_SYSTEM) + if ((r = unit_add_dependency(tu, UNIT_WANTS, UNIT(s), true)) < 0) + return r; + + return unit_add_dependency(UNIT(s), UNIT_BEFORE, tu, true); +} + +static int swap_add_device_links(Swap *s) { + SwapParameters *p; + + assert(s); + + if (!s->what) + return 0; + + if (s->from_fragment) + p = &s->parameters_fragment; + else if (s->from_etc_fstab) + p = &s->parameters_etc_fstab; + else + return 0; + + if (is_device_path(s->what)) + return unit_add_node_link(UNIT(s), s->what, + !p->noauto && p->nofail && + UNIT(s)->manager->running_as == MANAGER_SYSTEM); + else + /* File based swap devices need to be ordered after + * remount-rootfs.service, since they might need a + * writable file system. */ + return unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_REMOUNT_ROOTFS_SERVICE, NULL, true); +} + +static int swap_add_default_dependencies(Swap *s) { + int r; + + assert(s); + + if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) { + + if ((r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0) + return r; + } + + return 0; +} + +static int swap_verify(Swap *s) { + bool b; + char *e; + + if (UNIT(s)->load_state != UNIT_LOADED) + return 0; + + if (!(e = unit_name_from_path(s->what, ".swap"))) + return -ENOMEM; + + b = unit_has_name(UNIT(s), e); + free(e); + + if (!b) { + log_error("%s: Value of \"What\" and unit name do not match, not loading.\n", UNIT(s)->id); + return -EINVAL; + } + + if (s->exec_context.pam_name && s->exec_context.kill_mode != KILL_CONTROL_GROUP) { + log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(s)->id); + return -EINVAL; + } + + return 0; +} + +static int swap_load(Unit *u) { + int r; + Swap *s = SWAP(u); + + assert(s); + assert(u->load_state == UNIT_STUB); + + /* Load a .swap file */ + if ((r = unit_load_fragment_and_dropin_optional(u)) < 0) + return r; + + if (u->load_state == UNIT_LOADED) { + if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0) + return r; + + if (UNIT(s)->fragment_path) + s->from_fragment = true; + + if (!s->what) { + if (s->parameters_fragment.what) + s->what = strdup(s->parameters_fragment.what); + else if (s->parameters_etc_fstab.what) + s->what = strdup(s->parameters_etc_fstab.what); + else if (s->parameters_proc_swaps.what) + s->what = strdup(s->parameters_proc_swaps.what); + else + s->what = unit_name_to_path(u->id); + + if (!s->what) + return -ENOMEM; + } + + path_kill_slashes(s->what); + + if (!UNIT(s)->description) + if ((r = unit_set_description(u, s->what)) < 0) + return r; + + if ((r = swap_add_device_links(s)) < 0) + return r; + + if ((r = swap_add_mount_links(s)) < 0) + return r; + + if ((r = swap_add_target_links(s)) < 0) + return r; + + if ((r = unit_add_default_cgroups(u)) < 0) + return r; + + if (UNIT(s)->default_dependencies) + if ((r = swap_add_default_dependencies(s)) < 0) + return r; + } + + return swap_verify(s); +} + +int swap_add_one( + Manager *m, + const char *what, + const char *what_proc_swaps, + int priority, + bool noauto, + bool nofail, + bool handle, + bool set_flags) { + + Unit *u = NULL; + char *e = NULL, *wp = NULL; + bool delete = false; + int r; + SwapParameters *p; + + assert(m); + assert(what); + + e = unit_name_from_path(what, ".swap"); + if (!e) + return -ENOMEM; + + u = manager_get_unit(m, e); + + if (what_proc_swaps && + u && + SWAP(u)->from_proc_swaps && + !path_equal(SWAP(u)->parameters_proc_swaps.what, what_proc_swaps)) + return -EEXIST; + + if (!u) { + delete = true; + + u = unit_new(m, sizeof(Swap)); + if (!u) { + free(e); + return -ENOMEM; + } + + r = unit_add_name(u, e); + if (r < 0) + goto fail; + + SWAP(u)->what = strdup(what); + if (!SWAP(u)->what) { + r = -ENOMEM; + goto fail; + } + + unit_add_to_load_queue(u); + } else + delete = false; + + if (what_proc_swaps) { + Swap *first; + + p = &SWAP(u)->parameters_proc_swaps; + + if (!p->what) { + if (!(wp = strdup(what_proc_swaps))) { + r = -ENOMEM; + goto fail; + } + + if (!m->swaps_by_proc_swaps) + if (!(m->swaps_by_proc_swaps = hashmap_new(string_hash_func, string_compare_func))) { + r = -ENOMEM; + goto fail; + } + + free(p->what); + p->what = wp; + + first = hashmap_get(m->swaps_by_proc_swaps, wp); + LIST_PREPEND(Swap, same_proc_swaps, first, SWAP(u)); + + if ((r = hashmap_replace(m->swaps_by_proc_swaps, wp, first)) < 0) + goto fail; + } + + if (set_flags) { + SWAP(u)->is_active = true; + SWAP(u)->just_activated = !SWAP(u)->from_proc_swaps; + } + + SWAP(u)->from_proc_swaps = true; + + } else { + p = &SWAP(u)->parameters_etc_fstab; + + if (!(wp = strdup(what))) { + r = -ENOMEM; + goto fail; + } + + free(p->what); + p->what = wp; + + SWAP(u)->from_etc_fstab = true; + } + + p->priority = priority; + p->noauto = noauto; + p->nofail = nofail; + p->handle = handle; + + unit_add_to_dbus_queue(u); + + free(e); + + return 0; + +fail: + log_warning("Failed to load swap unit: %s", strerror(-r)); + + free(wp); + free(e); + + if (delete && u) + unit_free(u); + + return r; +} + +static int swap_process_new_swap(Manager *m, const char *device, int prio, bool set_flags) { + struct stat st; + int r = 0, k; + + assert(m); + + if (stat(device, &st) >= 0 && S_ISBLK(st.st_mode)) { + struct udev_device *d; + const char *dn; + struct udev_list_entry *item = NULL, *first = NULL; + + /* So this is a proper swap device. Create swap units + * for all names this swap device is known under */ + + if (!(d = udev_device_new_from_devnum(m->udev, 'b', st.st_rdev))) + return -ENOMEM; + + if ((dn = udev_device_get_devnode(d))) + r = swap_add_one(m, dn, device, prio, false, false, false, set_flags); + + /* Add additional units for all symlinks */ + first = udev_device_get_devlinks_list_entry(d); + udev_list_entry_foreach(item, first) { + const char *p; + + /* Don't bother with the /dev/block links */ + p = udev_list_entry_get_name(item); + + if (path_startswith(p, "/dev/block/")) + continue; + + if (stat(p, &st) >= 0) + if ((!S_ISBLK(st.st_mode)) || st.st_rdev != udev_device_get_devnum(d)) + continue; + + if ((k = swap_add_one(m, p, device, prio, false, false, false, set_flags)) < 0) + r = k; + } + + udev_device_unref(d); + } + + if ((k = swap_add_one(m, device, device, prio, false, false, false, set_flags)) < 0) + r = k; + + return r; +} + +static void swap_set_state(Swap *s, SwapState state) { + SwapState old_state; + + assert(s); + + old_state = s->state; + s->state = state; + + if (state != SWAP_ACTIVATING && + state != SWAP_ACTIVATING_SIGTERM && + state != SWAP_ACTIVATING_SIGKILL && + state != SWAP_DEACTIVATING && + state != SWAP_DEACTIVATING_SIGTERM && + state != SWAP_DEACTIVATING_SIGKILL) { + unit_unwatch_timer(UNIT(s), &s->timer_watch); + swap_unwatch_control_pid(s); + s->control_command = NULL; + s->control_command_id = _SWAP_EXEC_COMMAND_INVALID; + } + + if (state != old_state) + log_debug("%s changed %s -> %s", + UNIT(s)->id, + swap_state_to_string(old_state), + swap_state_to_string(state)); + + unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true); +} + +static int swap_coldplug(Unit *u) { + Swap *s = SWAP(u); + SwapState new_state = SWAP_DEAD; + int r; + + assert(s); + assert(s->state == SWAP_DEAD); + + if (s->deserialized_state != s->state) + new_state = s->deserialized_state; + else if (s->from_proc_swaps) + new_state = SWAP_ACTIVE; + + if (new_state != s->state) { + + if (new_state == SWAP_ACTIVATING || + new_state == SWAP_ACTIVATING_SIGTERM || + new_state == SWAP_ACTIVATING_SIGKILL || + new_state == SWAP_DEACTIVATING || + new_state == SWAP_DEACTIVATING_SIGTERM || + new_state == SWAP_DEACTIVATING_SIGKILL) { + + if (s->control_pid <= 0) + return -EBADMSG; + + if ((r = unit_watch_pid(UNIT(s), s->control_pid)) < 0) + return r; + + if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) + return r; + } + + swap_set_state(s, new_state); + } + + return 0; +} + +static void swap_dump(Unit *u, FILE *f, const char *prefix) { + Swap *s = SWAP(u); + SwapParameters *p; + + assert(s); + assert(f); + + if (s->from_proc_swaps) + p = &s->parameters_proc_swaps; + else if (s->from_fragment) + p = &s->parameters_fragment; + else + p = &s->parameters_etc_fstab; + + fprintf(f, + "%sSwap State: %s\n" + "%sResult: %s\n" + "%sWhat: %s\n" + "%sPriority: %i\n" + "%sNoAuto: %s\n" + "%sNoFail: %s\n" + "%sHandle: %s\n" + "%sFrom /etc/fstab: %s\n" + "%sFrom /proc/swaps: %s\n" + "%sFrom fragment: %s\n", + prefix, swap_state_to_string(s->state), + prefix, swap_result_to_string(s->result), + prefix, s->what, + prefix, p->priority, + prefix, yes_no(p->noauto), + prefix, yes_no(p->nofail), + prefix, yes_no(p->handle), + prefix, yes_no(s->from_etc_fstab), + prefix, yes_no(s->from_proc_swaps), + prefix, yes_no(s->from_fragment)); + + if (s->control_pid > 0) + fprintf(f, + "%sControl PID: %lu\n", + prefix, (unsigned long) s->control_pid); + + exec_context_dump(&s->exec_context, f, prefix); +} + +static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { + pid_t pid; + int r; + + assert(s); + assert(c); + assert(_pid); + + if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) + goto fail; + + if ((r = exec_spawn(c, + NULL, + &s->exec_context, + NULL, 0, + UNIT(s)->manager->environment, + true, + true, + true, + UNIT(s)->manager->confirm_spawn, + UNIT(s)->cgroup_bondings, + UNIT(s)->cgroup_attributes, + &pid)) < 0) + goto fail; + + if ((r = unit_watch_pid(UNIT(s), pid)) < 0) + /* FIXME: we need to do something here */ + goto fail; + + *_pid = pid; + + return 0; + +fail: + unit_unwatch_timer(UNIT(s), &s->timer_watch); + + return r; +} + +static void swap_enter_dead(Swap *s, SwapResult f) { + assert(s); + + if (f != SWAP_SUCCESS) + s->result = f; + + swap_set_state(s, s->result != SWAP_SUCCESS ? SWAP_FAILED : SWAP_DEAD); +} + +static void swap_enter_active(Swap *s, SwapResult f) { + assert(s); + + if (f != SWAP_SUCCESS) + s->result = f; + + swap_set_state(s, SWAP_ACTIVE); +} + +static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) { + int r; + Set *pid_set = NULL; + bool wait_for_exit = false; + + assert(s); + + if (f != SWAP_SUCCESS) + s->result = f; + + if (s->exec_context.kill_mode != KILL_NONE) { + int sig = (state == SWAP_ACTIVATING_SIGTERM || + state == SWAP_DEACTIVATING_SIGTERM) ? s->exec_context.kill_signal : SIGKILL; + + if (s->control_pid > 0) { + if (kill_and_sigcont(s->control_pid, sig) < 0 && errno != ESRCH) + + log_warning("Failed to kill control process %li: %m", (long) s->control_pid); + else + wait_for_exit = true; + } + + if (s->exec_context.kill_mode == KILL_CONTROL_GROUP) { + + if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) { + r = -ENOMEM; + goto fail; + } + + /* Exclude the control pid from being killed via the cgroup */ + if (s->control_pid > 0) + if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) + goto fail; + + if ((r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set)) < 0) { + if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) + log_warning("Failed to kill control group: %s", strerror(-r)); + } else if (r > 0) + wait_for_exit = true; + + set_free(pid_set); + pid_set = NULL; + } + } + + if (wait_for_exit) { + if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) + goto fail; + + swap_set_state(s, state); + } else + swap_enter_dead(s, SWAP_SUCCESS); + + return; + +fail: + log_warning("%s failed to kill processes: %s", UNIT(s)->id, strerror(-r)); + + swap_enter_dead(s, SWAP_FAILURE_RESOURCES); + + if (pid_set) + set_free(pid_set); +} + +static void swap_enter_activating(Swap *s) { + int r, priority; + + assert(s); + + s->control_command_id = SWAP_EXEC_ACTIVATE; + s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE; + + if (s->from_fragment) + priority = s->parameters_fragment.priority; + else if (s->from_etc_fstab) + priority = s->parameters_etc_fstab.priority; + else + priority = -1; + + if (priority >= 0) { + char p[LINE_MAX]; + + snprintf(p, sizeof(p), "%i", priority); + char_array_0(p); + + r = exec_command_set( + s->control_command, + "/sbin/swapon", + "-p", + p, + s->what, + NULL); + } else + r = exec_command_set( + s->control_command, + "/sbin/swapon", + s->what, + NULL); + + if (r < 0) + goto fail; + + swap_unwatch_control_pid(s); + + if ((r = swap_spawn(s, s->control_command, &s->control_pid)) < 0) + goto fail; + + swap_set_state(s, SWAP_ACTIVATING); + + return; + +fail: + log_warning("%s failed to run 'swapon' task: %s", UNIT(s)->id, strerror(-r)); + swap_enter_dead(s, SWAP_FAILURE_RESOURCES); +} + +static void swap_enter_deactivating(Swap *s) { + int r; + + assert(s); + + s->control_command_id = SWAP_EXEC_DEACTIVATE; + s->control_command = s->exec_command + SWAP_EXEC_DEACTIVATE; + + if ((r = exec_command_set( + s->control_command, + "/sbin/swapoff", + s->what, + NULL)) < 0) + goto fail; + + swap_unwatch_control_pid(s); + + if ((r = swap_spawn(s, s->control_command, &s->control_pid)) < 0) + goto fail; + + swap_set_state(s, SWAP_DEACTIVATING); + + return; + +fail: + log_warning("%s failed to run 'swapoff' task: %s", UNIT(s)->id, strerror(-r)); + swap_enter_active(s, SWAP_FAILURE_RESOURCES); +} + +static int swap_start(Unit *u) { + Swap *s = SWAP(u); + + assert(s); + + /* We cannot fulfill this request right now, try again later + * please! */ + + if (s->state == SWAP_DEACTIVATING || + s->state == SWAP_DEACTIVATING_SIGTERM || + s->state == SWAP_DEACTIVATING_SIGKILL || + s->state == SWAP_ACTIVATING_SIGTERM || + s->state == SWAP_ACTIVATING_SIGKILL) + return -EAGAIN; + + if (s->state == SWAP_ACTIVATING) + return 0; + + assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED); + + s->result = SWAP_SUCCESS; + swap_enter_activating(s); + return 0; +} + +static int swap_stop(Unit *u) { + Swap *s = SWAP(u); + + assert(s); + + if (s->state == SWAP_DEACTIVATING || + s->state == SWAP_DEACTIVATING_SIGTERM || + s->state == SWAP_DEACTIVATING_SIGKILL || + s->state == SWAP_ACTIVATING_SIGTERM || + s->state == SWAP_ACTIVATING_SIGKILL) + return 0; + + assert(s->state == SWAP_ACTIVATING || + s->state == SWAP_ACTIVE); + + swap_enter_deactivating(s); + return 0; +} + +static int swap_serialize(Unit *u, FILE *f, FDSet *fds) { + Swap *s = SWAP(u); + + assert(s); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", swap_state_to_string(s->state)); + unit_serialize_item(u, f, "result", swap_result_to_string(s->result)); + + if (s->control_pid > 0) + unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid); + + if (s->control_command_id >= 0) + unit_serialize_item(u, f, "control-command", swap_exec_command_to_string(s->control_command_id)); + + return 0; +} + +static int swap_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Swap *s = SWAP(u); + + assert(s); + assert(fds); + + if (streq(key, "state")) { + SwapState state; + + if ((state = swap_state_from_string(value)) < 0) + log_debug("Failed to parse state value %s", value); + else + s->deserialized_state = state; + } else if (streq(key, "result")) { + SwapResult f; + + f = swap_result_from_string(value); + if (f < 0) + log_debug("Failed to parse result value %s", value); + else if (f != SWAP_SUCCESS) + s->result = f; + } else if (streq(key, "control-pid")) { + pid_t pid; + + if (parse_pid(value, &pid) < 0) + log_debug("Failed to parse control-pid value %s", value); + else + s->control_pid = pid; + + } else if (streq(key, "control-command")) { + SwapExecCommand id; + + if ((id = swap_exec_command_from_string(value)) < 0) + log_debug("Failed to parse exec-command value %s", value); + else { + s->control_command_id = id; + s->control_command = s->exec_command + id; + } + + } else + log_debug("Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState swap_active_state(Unit *u) { + assert(u); + + return state_translation_table[SWAP(u)->state]; +} + +static const char *swap_sub_state_to_string(Unit *u) { + assert(u); + + return swap_state_to_string(SWAP(u)->state); +} + +static bool swap_check_gc(Unit *u) { + Swap *s = SWAP(u); + + assert(s); + + return s->from_etc_fstab || s->from_proc_swaps; +} + +static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) { + Swap *s = SWAP(u); + SwapResult f; + + assert(s); + assert(pid >= 0); + + if (pid != s->control_pid) + return; + + s->control_pid = 0; + + if (is_clean_exit(code, status)) + f = SWAP_SUCCESS; + else if (code == CLD_EXITED) + f = SWAP_FAILURE_EXIT_CODE; + else if (code == CLD_KILLED) + f = SWAP_FAILURE_SIGNAL; + else if (code == CLD_DUMPED) + f = SWAP_FAILURE_CORE_DUMP; + else + assert_not_reached("Unknown code"); + + if (f != SWAP_SUCCESS) + s->result = f; + + if (s->control_command) { + exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status); + + s->control_command = NULL; + s->control_command_id = _SWAP_EXEC_COMMAND_INVALID; + } + + log_full(f == SWAP_SUCCESS ? LOG_DEBUG : LOG_NOTICE, + "%s swap process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status); + + switch (s->state) { + + case SWAP_ACTIVATING: + case SWAP_ACTIVATING_SIGTERM: + case SWAP_ACTIVATING_SIGKILL: + + if (f == SWAP_SUCCESS) + swap_enter_active(s, f); + else + swap_enter_dead(s, f); + break; + + case SWAP_DEACTIVATING: + case SWAP_DEACTIVATING_SIGKILL: + case SWAP_DEACTIVATING_SIGTERM: + + if (f == SWAP_SUCCESS) + swap_enter_dead(s, f); + else + swap_enter_dead(s, f); + break; + + default: + assert_not_reached("Uh, control process died at wrong time."); + } + + /* Notify clients about changed exit status */ + unit_add_to_dbus_queue(u); + + /* Request a reload of /proc/swaps, so that following units + * can follow our state change */ + u->manager->request_reload = true; +} + +static void swap_timer_event(Unit *u, uint64_t elapsed, Watch *w) { + Swap *s = SWAP(u); + + assert(s); + assert(elapsed == 1); + assert(w == &s->timer_watch); + + switch (s->state) { + + case SWAP_ACTIVATING: + log_warning("%s activation timed out. Stopping.", u->id); + swap_enter_signal(s, SWAP_ACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT); + break; + + case SWAP_DEACTIVATING: + log_warning("%s deactivation timed out. Stopping.", u->id); + swap_enter_signal(s, SWAP_DEACTIVATING_SIGTERM, SWAP_FAILURE_TIMEOUT); + break; + + case SWAP_ACTIVATING_SIGTERM: + if (s->exec_context.send_sigkill) { + log_warning("%s activation timed out. Killing.", u->id); + swap_enter_signal(s, SWAP_ACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT); + } else { + log_warning("%s activation timed out. Skipping SIGKILL. Ignoring.", u->id); + swap_enter_dead(s, SWAP_FAILURE_TIMEOUT); + } + break; + + case SWAP_DEACTIVATING_SIGTERM: + if (s->exec_context.send_sigkill) { + log_warning("%s deactivation timed out. Killing.", u->id); + swap_enter_signal(s, SWAP_DEACTIVATING_SIGKILL, SWAP_FAILURE_TIMEOUT); + } else { + log_warning("%s deactivation timed out. Skipping SIGKILL. Ignoring.", u->id); + swap_enter_dead(s, SWAP_FAILURE_TIMEOUT); + } + break; + + case SWAP_ACTIVATING_SIGKILL: + case SWAP_DEACTIVATING_SIGKILL: + log_warning("%s swap process still around after SIGKILL. Ignoring.", u->id); + swap_enter_dead(s, SWAP_FAILURE_TIMEOUT); + break; + + default: + assert_not_reached("Timeout at wrong time."); + } +} + +static int swap_load_proc_swaps(Manager *m, bool set_flags) { + unsigned i; + int r = 0; + + assert(m); + + rewind(m->proc_swaps); + + (void) fscanf(m->proc_swaps, "%*s %*s %*s %*s %*s\n"); + + for (i = 1;; i++) { + char *dev = NULL, *d; + int prio = 0, k; + + if ((k = fscanf(m->proc_swaps, + "%ms " /* device/file */ + "%*s " /* type of swap */ + "%*s " /* swap size */ + "%*s " /* used */ + "%i\n", /* priority */ + &dev, &prio)) != 2) { + + if (k == EOF) + break; + + log_warning("Failed to parse /proc/swaps:%u.", i); + free(dev); + continue; + } + + d = cunescape(dev); + free(dev); + + if (!d) + return -ENOMEM; + + k = swap_process_new_swap(m, d, prio, set_flags); + free(d); + + if (k < 0) + r = k; + } + + return r; +} + +int swap_dispatch_reload(Manager *m) { + /* This function should go as soon as the kernel properly notifies us */ + + if (_likely_(!m->request_reload)) + return 0; + + m->request_reload = false; + + return swap_fd_event(m, EPOLLPRI); +} + +int swap_fd_event(Manager *m, int events) { + Unit *u; + int r; + + assert(m); + assert(events & EPOLLPRI); + + if ((r = swap_load_proc_swaps(m, true)) < 0) { + log_error("Failed to reread /proc/swaps: %s", strerror(-r)); + + /* Reset flags, just in case, for late calls */ + LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) { + Swap *swap = SWAP(u); + + swap->is_active = swap->just_activated = false; + } + + return 0; + } + + manager_dispatch_load_queue(m); + + LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_SWAP]) { + Swap *swap = SWAP(u); + + if (!swap->is_active) { + /* This has just been deactivated */ + + swap->from_proc_swaps = false; + swap_unset_proc_swaps(swap); + + switch (swap->state) { + + case SWAP_ACTIVE: + swap_enter_dead(swap, SWAP_SUCCESS); + break; + + default: + swap_set_state(swap, swap->state); + break; + } + + } else if (swap->just_activated) { + + /* New swap entry */ + + switch (swap->state) { + + case SWAP_DEAD: + case SWAP_FAILED: + swap_enter_active(swap, SWAP_SUCCESS); + break; + + default: + /* Nothing really changed, but let's + * issue an notification call + * nonetheless, in case somebody is + * waiting for this. */ + swap_set_state(swap, swap->state); + break; + } + } + + /* Reset the flags for later calls */ + swap->is_active = swap->just_activated = false; + } + + return 1; +} + +static Unit *swap_following(Unit *u) { + Swap *s = SWAP(u); + Swap *other, *first = NULL; + + assert(s); + + if (streq_ptr(s->what, s->parameters_proc_swaps.what)) + return NULL; + + /* Make everybody follow the unit that's named after the swap + * device in the kernel */ + + LIST_FOREACH_AFTER(same_proc_swaps, other, s) + if (streq_ptr(other->what, other->parameters_proc_swaps.what)) + return UNIT(other); + + LIST_FOREACH_BEFORE(same_proc_swaps, other, s) { + if (streq_ptr(other->what, other->parameters_proc_swaps.what)) + return UNIT(other); + + first = other; + } + + return UNIT(first); +} + +static int swap_following_set(Unit *u, Set **_set) { + Swap *s = SWAP(u); + Swap *other; + Set *set; + int r; + + assert(s); + assert(_set); + + if (LIST_JUST_US(same_proc_swaps, s)) { + *_set = NULL; + return 0; + } + + if (!(set = set_new(NULL, NULL))) + return -ENOMEM; + + LIST_FOREACH_AFTER(same_proc_swaps, other, s) + if ((r = set_put(set, other)) < 0) + goto fail; + + LIST_FOREACH_BEFORE(same_proc_swaps, other, s) + if ((r = set_put(set, other)) < 0) + goto fail; + + *_set = set; + return 1; + +fail: + set_free(set); + return r; +} + +static void swap_shutdown(Manager *m) { + assert(m); + + if (m->proc_swaps) { + fclose(m->proc_swaps); + m->proc_swaps = NULL; + } + + hashmap_free(m->swaps_by_proc_swaps); + m->swaps_by_proc_swaps = NULL; +} + +static int swap_enumerate(Manager *m) { + int r; + struct epoll_event ev; + assert(m); + + if (!m->proc_swaps) { + if (!(m->proc_swaps = fopen("/proc/swaps", "re"))) + return (errno == ENOENT) ? 0 : -errno; + + m->swap_watch.type = WATCH_SWAP; + m->swap_watch.fd = fileno(m->proc_swaps); + + zero(ev); + ev.events = EPOLLPRI; + ev.data.ptr = &m->swap_watch; + + if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->swap_watch.fd, &ev) < 0) + return -errno; + } + + /* We rely on mount.c to load /etc/fstab for us */ + + if ((r = swap_load_proc_swaps(m, false)) < 0) + swap_shutdown(m); + + return r; +} + +static void swap_reset_failed(Unit *u) { + Swap *s = SWAP(u); + + assert(s); + + if (s->state == SWAP_FAILED) + swap_set_state(s, SWAP_DEAD); + + s->result = SWAP_SUCCESS; +} + +static int swap_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) { + Swap *s = SWAP(u); + int r = 0; + Set *pid_set = NULL; + + assert(s); + + if (who == KILL_MAIN) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Swap units have no main processes"); + return -ESRCH; + } + + if (s->control_pid <= 0 && who == KILL_CONTROL) { + dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill"); + return -ESRCH; + } + + if (who == KILL_CONTROL || who == KILL_ALL) + if (s->control_pid > 0) + if (kill(s->control_pid, signo) < 0) + r = -errno; + + if (who == KILL_ALL && mode == KILL_CONTROL_GROUP) { + int q; + + if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + /* Exclude the control pid from being killed via the cgroup */ + if (s->control_pid > 0) + if ((q = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) { + r = q; + goto finish; + } + + if ((q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set)) < 0) + if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) + r = q; + } + +finish: + if (pid_set) + set_free(pid_set); + + return r; +} + +static const char* const swap_state_table[_SWAP_STATE_MAX] = { + [SWAP_DEAD] = "dead", + [SWAP_ACTIVATING] = "activating", + [SWAP_ACTIVE] = "active", + [SWAP_DEACTIVATING] = "deactivating", + [SWAP_ACTIVATING_SIGTERM] = "activating-sigterm", + [SWAP_ACTIVATING_SIGKILL] = "activating-sigkill", + [SWAP_DEACTIVATING_SIGTERM] = "deactivating-sigterm", + [SWAP_DEACTIVATING_SIGKILL] = "deactivating-sigkill", + [SWAP_FAILED] = "failed" +}; + +DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState); + +static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = { + [SWAP_EXEC_ACTIVATE] = "ExecActivate", + [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate", +}; + +DEFINE_STRING_TABLE_LOOKUP(swap_exec_command, SwapExecCommand); + +static const char* const swap_result_table[_SWAP_RESULT_MAX] = { + [SWAP_SUCCESS] = "success", + [SWAP_FAILURE_RESOURCES] = "resources", + [SWAP_FAILURE_TIMEOUT] = "timeout", + [SWAP_FAILURE_EXIT_CODE] = "exit-code", + [SWAP_FAILURE_SIGNAL] = "signal", + [SWAP_FAILURE_CORE_DUMP] = "core-dump" +}; + +DEFINE_STRING_TABLE_LOOKUP(swap_result, SwapResult); + +const UnitVTable swap_vtable = { + .suffix = ".swap", + .object_size = sizeof(Swap), + .sections = + "Unit\0" + "Swap\0" + "Install\0", + + .no_alias = true, + .no_instances = true, + .show_status = true, + + .init = swap_init, + .load = swap_load, + .done = swap_done, + + .coldplug = swap_coldplug, + + .dump = swap_dump, + + .start = swap_start, + .stop = swap_stop, + + .kill = swap_kill, + + .serialize = swap_serialize, + .deserialize_item = swap_deserialize_item, + + .active_state = swap_active_state, + .sub_state_to_string = swap_sub_state_to_string, + + .check_gc = swap_check_gc, + + .sigchld_event = swap_sigchld_event, + .timer_event = swap_timer_event, + + .reset_failed = swap_reset_failed, + + .bus_interface = "org.freedesktop.systemd1.Swap", + .bus_message_handler = bus_swap_message_handler, + .bus_invalidating_properties = bus_swap_invalidating_properties, + + .following = swap_following, + .following_set = swap_following_set, + + .enumerate = swap_enumerate, + .shutdown = swap_shutdown +}; diff --git a/src/swap.h b/src/swap.h new file mode 100644 index 0000000..62d08da --- /dev/null +++ b/src/swap.h @@ -0,0 +1,128 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooswaphfoo +#define fooswaphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + Copyright 2010 Maarten Lankhorst + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct Swap Swap; + +#include "unit.h" + +typedef enum SwapState { + SWAP_DEAD, + SWAP_ACTIVATING, + SWAP_ACTIVE, + SWAP_DEACTIVATING, + SWAP_ACTIVATING_SIGTERM, + SWAP_ACTIVATING_SIGKILL, + SWAP_DEACTIVATING_SIGTERM, + SWAP_DEACTIVATING_SIGKILL, + SWAP_FAILED, + _SWAP_STATE_MAX, + _SWAP_STATE_INVALID = -1 +} SwapState; + +typedef enum SwapExecCommand { + SWAP_EXEC_ACTIVATE, + SWAP_EXEC_DEACTIVATE, + _SWAP_EXEC_COMMAND_MAX, + _SWAP_EXEC_COMMAND_INVALID = -1 +} SwapExecCommand; + +typedef struct SwapParameters { + char *what; + int priority; + bool noauto:1; + bool nofail:1; + bool handle:1; +} SwapParameters; + +typedef enum SwapResult { + SWAP_SUCCESS, + SWAP_FAILURE_RESOURCES, + SWAP_FAILURE_TIMEOUT, + SWAP_FAILURE_EXIT_CODE, + SWAP_FAILURE_SIGNAL, + SWAP_FAILURE_CORE_DUMP, + _SWAP_RESULT_MAX, + _SWAP_RESULT_INVALID = -1 +} SwapResult; + +struct Swap { + Unit meta; + + char *what; + + SwapParameters parameters_etc_fstab; + SwapParameters parameters_proc_swaps; + SwapParameters parameters_fragment; + + bool from_etc_fstab:1; + bool from_proc_swaps:1; + bool from_fragment:1; + + /* Used while looking for swaps that vanished or got added + * from/to /proc/swaps */ + bool is_active:1; + bool just_activated:1; + + SwapResult result; + + usec_t timeout_usec; + + ExecCommand exec_command[_SWAP_EXEC_COMMAND_MAX]; + ExecContext exec_context; + + SwapState state, deserialized_state; + + ExecCommand* control_command; + SwapExecCommand control_command_id; + pid_t control_pid; + + Watch timer_watch; + + /* In order to be able to distinguish dependencies on + different device nodes we might end up creating multiple + devices for the same swap. We chain them up here. */ + + LIST_FIELDS(struct Swap, same_proc_swaps); +}; + +extern const UnitVTable swap_vtable; + +int swap_add_one(Manager *m, const char *what, const char *what_proc_swaps, int prio, bool no_auto, bool no_fail, bool handle, bool set_flags); + +int swap_add_one_mount_link(Swap *s, Mount *m); + +int swap_dispatch_reload(Manager *m); +int swap_fd_event(Manager *m, int events); + +const char* swap_state_to_string(SwapState i); +SwapState swap_state_from_string(const char *s); + +const char* swap_exec_command_to_string(SwapExecCommand i); +SwapExecCommand swap_exec_command_from_string(const char *s); + +const char* swap_result_to_string(SwapResult i); +SwapResult swap_result_from_string(const char *s); + +#endif diff --git a/src/sysctl.c b/src/sysctl.c new file mode 100644 index 0000000..8bdfb08 --- /dev/null +++ b/src/sysctl.c @@ -0,0 +1,266 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "strv.h" +#include "util.h" +#include "strv.h" + +#define PROC_SYS_PREFIX "/proc/sys/" + +static char **arg_prefixes = NULL; + +static int apply_sysctl(const char *property, const char *value) { + char *p, *n; + int r = 0, k; + + log_debug("Setting '%s' to '%s'", property, value); + + p = new(char, sizeof(PROC_SYS_PREFIX) + strlen(property)); + if (!p) { + log_error("Out of memory"); + return -ENOMEM; + } + + n = stpcpy(p, PROC_SYS_PREFIX); + strcpy(n, property); + + for (; *n; n++) + if (*n == '.') + *n = '/'; + + if (!strv_isempty(arg_prefixes)) { + char **i; + bool good = false; + + STRV_FOREACH(i, arg_prefixes) + if (path_startswith(p, *i)) { + good = true; + break; + } + + if (!good) { + log_debug("Skipping %s", p); + free(p); + return 0; + } + } + + k = write_one_line_file(p, value); + if (k < 0) { + + log_full(k == -ENOENT ? LOG_DEBUG : LOG_WARNING, + "Failed to write '%s' to '%s': %s", value, p, strerror(-k)); + + if (k != -ENOENT && r == 0) + r = k; + } + + free(p); + + return r; +} + +static int apply_file(const char *path, bool ignore_enoent) { + FILE *f; + int r = 0; + + assert(path); + + if (!(f = fopen(path, "re"))) { + if (ignore_enoent && errno == ENOENT) + return 0; + + log_error("Failed to open file '%s', ignoring: %m", path); + return -errno; + } + + log_debug("apply: %s\n", path); + while (!feof(f)) { + char l[LINE_MAX], *p, *value; + int k; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + log_error("Failed to read file '%s', ignoring: %m", path); + r = -errno; + goto finish; + } + + p = strstrip(l); + + if (!*p) + continue; + + if (strchr(COMMENTS, *p)) + continue; + + if (!(value = strchr(p, '='))) { + log_error("Line is not an assignment in file '%s': %s", path, value); + + if (r == 0) + r = -EINVAL; + continue; + } + + *value = 0; + value++; + + if ((k = apply_sysctl(strstrip(p), strstrip(value))) < 0 && r == 0) + r = k; + } + +finish: + fclose(f); + + return r; +} + +static int help(void) { + + printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n" + "Applies kernel sysctl settings.\n\n" + " -h --help Show this help\n" + " --prefix=PATH Only apply rules that apply to paths with the specified prefix\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_PREFIX + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "prefix", required_argument, NULL, ARG_PREFIX }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_PREFIX: { + char *p; + char **l; + + for (p = optarg; *p; p++) + if (*p == '.') + *p = '/'; + + l = strv_append(arg_prefixes, optarg); + if (!l) { + log_error("Out of memory"); + return -ENOMEM; + } + + strv_free(arg_prefixes); + arg_prefixes = l; + + break; + } + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + return 1; +} + +int main(int argc, char *argv[]) { + int r = 0; + + r = parse_argv(argc, argv); + if (r <= 0) + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + + if (argc-optind > 1) { + log_error("This program expects one or no arguments."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc > optind) + r = apply_file(argv[optind], false); + else { + char **files, **f; + + r = conf_files_list(&files, ".conf", + "/run/sysctl.d", + "/etc/sysctl.d", + "/usr/local/lib/sysctl.d", + "/usr/lib/sysctl.d", + "/lib/sysctl.d", + NULL); + if (r < 0) { + log_error("Failed to enumerate sysctl.d files: %s", strerror(-r)); + goto finish; + } + + STRV_FOREACH(f, files) { + int k; + + k = apply_file(*f, true); + if (k < 0 && r == 0) + r = k; + } + + apply_file("/etc/sysctl.conf", true); + + strv_free(files); + } +finish: + strv_free(arg_prefixes); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/sysfs-show.h b/src/sysfs-show.h new file mode 100644 index 0000000..9939e8b --- /dev/null +++ b/src/sysfs-show.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosysfsshowhfoo +#define foosysfsshowhfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +int show_sysfs(const char *seat, const char *prefix, unsigned columns); + +#endif diff --git a/src/system.conf b/src/system.conf new file mode 100644 index 0000000..33d09bc --- /dev/null +++ b/src/system.conf @@ -0,0 +1,26 @@ +# This file is part of systemd. +# +# systemd 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. +# +# See systemd.conf(5) for details + +[Manager] +#LogLevel=info +#LogTarget=journal-or-kmsg +#LogColor=yes +#LogLocation=no +#DumpCore=yes +#CrashShell=no +#ShowStatus=yes +#SysVConsole=yes +#CrashChVT=1 +#CPUAffinity=1 2 +#MountAuto=yes +#SwapAuto=yes +#DefaultControllers=cpu +#DefaultStandardOutput=journal +#DefaultStandardError=inherit +#JoinControllers=cpu,cpuacct diff --git a/src/systemadm.c b/src/systemadm.c new file mode 100644 index 0000000..f065c61 --- /dev/null +++ b/src/systemadm.c @@ -0,0 +1,7822 @@ +/* systemadm.c generated by valac 0.15.1, the Vala compiler + * generated from systemadm.vala, do not modify */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) + +#define TYPE_LEFT_LABEL (left_label_get_type ()) +#define LEFT_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_LEFT_LABEL, LeftLabel)) +#define LEFT_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_LEFT_LABEL, LeftLabelClass)) +#define IS_LEFT_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_LEFT_LABEL)) +#define IS_LEFT_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_LEFT_LABEL)) +#define LEFT_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_LEFT_LABEL, LeftLabelClass)) + +typedef struct _LeftLabel LeftLabel; +typedef struct _LeftLabelClass LeftLabelClass; +typedef struct _LeftLabelPrivate LeftLabelPrivate; +#define _g_free0(var) (var = (g_free (var), NULL)) + +#define TYPE_WRAP_LABEL (wrap_label_get_type ()) +#define WRAP_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_WRAP_LABEL, WrapLabel)) +#define WRAP_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_WRAP_LABEL, WrapLabelClass)) +#define IS_WRAP_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_WRAP_LABEL)) +#define IS_WRAP_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_WRAP_LABEL)) +#define WRAP_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_WRAP_LABEL, WrapLabelClass)) + +typedef struct _WrapLabel WrapLabel; +typedef struct _WrapLabelClass WrapLabelClass; +typedef struct _WrapLabelPrivate WrapLabelPrivate; + +#define TYPE_RIGHT_LABEL (right_label_get_type ()) +#define RIGHT_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RIGHT_LABEL, RightLabel)) +#define RIGHT_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RIGHT_LABEL, RightLabelClass)) +#define IS_RIGHT_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RIGHT_LABEL)) +#define IS_RIGHT_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_RIGHT_LABEL)) +#define RIGHT_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_RIGHT_LABEL, RightLabelClass)) + +typedef struct _RightLabel RightLabel; +typedef struct _RightLabelClass RightLabelClass; +typedef struct _RightLabelPrivate RightLabelPrivate; + +#define TYPE_MAIN_WINDOW (main_window_get_type ()) +#define MAIN_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MAIN_WINDOW, MainWindow)) +#define MAIN_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MAIN_WINDOW, MainWindowClass)) +#define IS_MAIN_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MAIN_WINDOW)) +#define IS_MAIN_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MAIN_WINDOW)) +#define MAIN_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MAIN_WINDOW, MainWindowClass)) + +typedef struct _MainWindow MainWindow; +typedef struct _MainWindowClass MainWindowClass; +typedef struct _MainWindowPrivate MainWindowPrivate; + +#define TYPE_UNIT (unit_get_type ()) +#define UNIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_UNIT, Unit)) +#define IS_UNIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_UNIT)) +#define UNIT_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TYPE_UNIT, UnitIface)) + +typedef struct _Unit Unit; +typedef struct _UnitIface UnitIface; + +#define TYPE_UNIT_PROXY (unit_proxy_get_type ()) + +#define UNIT_TYPE_JOB_LINK (unit_job_link_get_type ()) +typedef struct _UnitJobLink UnitJobLink; + +#define TYPE_MANAGER (manager_get_type ()) +#define MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MANAGER, Manager)) +#define IS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MANAGER)) +#define MANAGER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TYPE_MANAGER, ManagerIface)) + +typedef struct _Manager Manager; +typedef struct _ManagerIface ManagerIface; + +#define TYPE_MANAGER_PROXY (manager_proxy_get_type ()) + +#define MANAGER_TYPE_UNIT_INFO (manager_unit_info_get_type ()) +typedef struct _ManagerUnitInfo ManagerUnitInfo; + +#define MANAGER_TYPE_JOB_INFO (manager_job_info_get_type ()) +typedef struct _ManagerJobInfo ManagerJobInfo; + +#define TYPE_JOB (job_get_type ()) +#define JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_JOB, Job)) +#define IS_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_JOB)) +#define JOB_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TYPE_JOB, JobIface)) + +typedef struct _Job Job; +typedef struct _JobIface JobIface; + +#define TYPE_JOB_PROXY (job_proxy_get_type ()) + +#define JOB_TYPE_UNIT_LINK (job_unit_link_get_type ()) +typedef struct _JobUnitLink JobUnitLink; + +#define TYPE_PROPERTIES (properties_get_type ()) +#define PROPERTIES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PROPERTIES, Properties)) +#define IS_PROPERTIES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PROPERTIES)) +#define PROPERTIES_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TYPE_PROPERTIES, PropertiesIface)) + +typedef struct _Properties Properties; +typedef struct _PropertiesIface PropertiesIface; + +#define TYPE_PROPERTIES_PROXY (properties_proxy_get_type ()) +#define _gtk_tree_path_free0(var) ((var == NULL) ? NULL : (var = (gtk_tree_path_free (var), NULL))) +#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) + +struct _LeftLabel { + GtkLabel parent_instance; + LeftLabelPrivate * priv; +}; + +struct _LeftLabelClass { + GtkLabelClass parent_class; +}; + +struct _WrapLabel { + GtkLabel parent_instance; + WrapLabelPrivate * priv; +}; + +struct _WrapLabelClass { + GtkLabelClass parent_class; +}; + +struct _RightLabel { + WrapLabel parent_instance; + RightLabelPrivate * priv; +}; + +struct _RightLabelClass { + WrapLabelClass parent_class; +}; + +struct _MainWindow { + GtkWindow parent_instance; + MainWindowPrivate * priv; +}; + +struct _MainWindowClass { + GtkWindowClass parent_class; +}; + +struct _UnitJobLink { + guint32 id; + char* path; +}; + +struct _UnitIface { + GTypeInterface parent_iface; + char* (*start) (Unit* self, const gchar* mode, GError** error); + char* (*stop) (Unit* self, const gchar* mode, GError** error); + char* (*reload) (Unit* self, const gchar* mode, GError** error); + char* (*restart) (Unit* self, const gchar* mode, GError** error); + char* (*try_restart) (Unit* self, const gchar* mode, GError** error); + char* (*reload_or_restart) (Unit* self, const gchar* mode, GError** error); + char* (*reload_or_try_restart) (Unit* self, const gchar* mode, GError** error); + void (*reset_failed) (Unit* self, GError** error); + gchar* (*get_id) (Unit* self); + gchar** (*get_names) (Unit* self, int* result_length1); + gchar* (*get_following) (Unit* self); + gchar** (*get_requires) (Unit* self, int* result_length1); + gchar** (*get_requires_overridable) (Unit* self, int* result_length1); + gchar** (*get_requisite) (Unit* self, int* result_length1); + gchar** (*get_requisite_overridable) (Unit* self, int* result_length1); + gchar** (*get_wants) (Unit* self, int* result_length1); + gchar** (*get_required_by) (Unit* self, int* result_length1); + gchar** (*get_required_by_overridable) (Unit* self, int* result_length1); + gchar** (*get_wanted_by) (Unit* self, int* result_length1); + gchar** (*get_conflicts) (Unit* self, int* result_length1); + gchar** (*get_conflicted_by) (Unit* self, int* result_length1); + gchar** (*get_before) (Unit* self, int* result_length1); + gchar** (*get_after) (Unit* self, int* result_length1); + gchar** (*get_on_failure) (Unit* self, int* result_length1); + gchar* (*get_description) (Unit* self); + gchar* (*get_load_state) (Unit* self); + gchar* (*get_active_state) (Unit* self); + gchar* (*get_sub_state) (Unit* self); + gchar* (*get_fragment_path) (Unit* self); + guint64 (*get_inactive_exit_timestamp) (Unit* self); + guint64 (*get_active_enter_timestamp) (Unit* self); + guint64 (*get_active_exit_timestamp) (Unit* self); + guint64 (*get_inactive_enter_timestamp) (Unit* self); + gboolean (*get_can_start) (Unit* self); + gboolean (*get_can_stop) (Unit* self); + gboolean (*get_can_reload) (Unit* self); + void (*get_job) (Unit* self, UnitJobLink* value); + gboolean (*get_recursive_stop) (Unit* self); + gboolean (*get_stop_when_unneeded) (Unit* self); + gboolean (*get_refuse_manual_start) (Unit* self); + gboolean (*get_refuse_manual_stop) (Unit* self); + gboolean (*get_default_dependencies) (Unit* self); + gchar* (*get_default_control_group) (Unit* self); + gchar** (*get_control_groups) (Unit* self, int* result_length1); + gboolean (*get_need_daemon_reload) (Unit* self); + guint64 (*get_job_timeout_usec) (Unit* self); +}; + +struct _ManagerUnitInfo { + gchar* id; + gchar* description; + gchar* load_state; + gchar* active_state; + gchar* sub_state; + gchar* following; + char* unit_path; + guint32 job_id; + gchar* job_type; + char* job_path; +}; + +struct _ManagerJobInfo { + guint32 id; + gchar* name; + gchar* type; + gchar* state; + char* job_path; + char* unit_path; +}; + +struct _ManagerIface { + GTypeInterface parent_iface; + ManagerUnitInfo* (*list_units) (Manager* self, int* result_length1, GError** error); + ManagerJobInfo* (*list_jobs) (Manager* self, int* result_length1, GError** error); + char* (*get_unit) (Manager* self, const gchar* name, GError** error); + char* (*get_unit_by_pid) (Manager* self, guint32 pid, GError** error); + char* (*load_unit) (Manager* self, const gchar* name, GError** error); + char* (*get_job) (Manager* self, guint32 id, GError** error); + char* (*start_unit) (Manager* self, const gchar* name, const gchar* mode, GError** error); + char* (*stop_unit) (Manager* self, const gchar* name, const gchar* mode, GError** error); + char* (*reload_unit) (Manager* self, const gchar* name, const gchar* mode, GError** error); + char* (*restart_unit) (Manager* self, const gchar* name, const gchar* mode, GError** error); + char* (*try_restart_unit) (Manager* self, const gchar* name, const gchar* mode, GError** error); + char* (*reload_or_restart_unit) (Manager* self, const gchar* name, const gchar* mode, GError** error); + char* (*reload_or_try_restart_unit) (Manager* self, const gchar* name, const gchar* mode, GError** error); + void (*reset_failed_unit) (Manager* self, const gchar* name, GError** error); + void (*clear_jobs) (Manager* self, GError** error); + void (*subscribe) (Manager* self, GError** error); + void (*unsubscribe) (Manager* self, GError** error); + gchar* (*dump) (Manager* self, GError** error); + void (*reload) (Manager* self, GError** error); + void (*reexecute) (Manager* self, GError** error); + void (*exit) (Manager* self, GError** error); + void (*halt) (Manager* self, GError** error); + void (*power_off) (Manager* self, GError** error); + void (*reboot) (Manager* self, GError** error); + void (*kexec) (Manager* self, GError** error); + char* (*create_snapshot) (Manager* self, const gchar* name, gboolean cleanup, GError** error); + void (*set_environment) (Manager* self, gchar** names, int names_length1, GError** error); + void (*unset_environment) (Manager* self, gchar** names, int names_length1, GError** error); + gchar** (*get_environment) (Manager* self, int* result_length1); +}; + +struct _MainWindowPrivate { + gchar* current_unit_id; + guint32 current_job_id; + GtkTreeView* unit_view; + GtkTreeView* job_view; + GtkListStore* unit_model; + GtkListStore* job_model; + GeeHashMap* unit_map; + GtkButton* start_button; + GtkButton* stop_button; + GtkButton* restart_button; + GtkButton* reload_button; + GtkButton* cancel_button; + GtkEntry* unit_load_entry; + GtkButton* unit_load_button; + GtkButton* server_snapshot_button; + GtkButton* server_reload_button; + Manager* manager; + RightLabel* unit_id_label; + RightLabel* unit_dependency_label; + RightLabel* unit_description_label; + RightLabel* unit_load_state_label; + RightLabel* unit_active_state_label; + RightLabel* unit_sub_state_label; + RightLabel* unit_fragment_path_label; + RightLabel* unit_active_enter_timestamp_label; + RightLabel* unit_active_exit_timestamp_label; + RightLabel* unit_can_start_label; + RightLabel* unit_can_reload_label; + RightLabel* unit_cgroup_label; + RightLabel* job_id_label; + RightLabel* job_state_label; + RightLabel* job_type_label; + GtkComboBox* unit_type_combo_box; + GtkCheckButton* inactive_checkbox; +}; + +struct _JobUnitLink { + gchar* id; + char* path; +}; + +struct _JobIface { + GTypeInterface parent_iface; + void (*cancel) (Job* self, GError** error); + guint32 (*get_id) (Job* self); + gchar* (*get_state) (Job* self); + gchar* (*get_job_type) (Job* self); + void (*get_unit) (Job* self, JobUnitLink* value); +}; + +struct _PropertiesIface { + GTypeInterface parent_iface; + GVariant* (*get) (Properties* self, const gchar* iface, const gchar* property, GError** error); +}; + + +extern gboolean user; +gboolean user = FALSE; +static gpointer left_label_parent_class = NULL; +static gpointer right_label_parent_class = NULL; +static gpointer main_window_parent_class = NULL; + +gchar* format_time (guint64 time_ns); +void new_column (GtkTreeView* view, gint column_id, const gchar* title); +GType left_label_get_type (void) G_GNUC_CONST; +enum { + LEFT_LABEL_DUMMY_PROPERTY +}; +LeftLabel* left_label_new (const gchar* text); +LeftLabel* left_label_construct (GType object_type, const gchar* text); +GType wrap_label_get_type (void) G_GNUC_CONST; +GType right_label_get_type (void) G_GNUC_CONST; +enum { + RIGHT_LABEL_DUMMY_PROPERTY +}; +RightLabel* right_label_new (const gchar* text); +RightLabel* right_label_construct (GType object_type, const gchar* text); +WrapLabel* wrap_label_new (const gchar* text); +WrapLabel* wrap_label_construct (GType object_type, const gchar* text); +void right_label_set_text_or_na (RightLabel* self, const gchar* text); +void wrap_label_set_markup (WrapLabel* self, const gchar* str); +void wrap_label_set_text (WrapLabel* self, const gchar* str); +void right_label_set_markup_or_na (RightLabel* self, const gchar* text); +GType main_window_get_type (void) G_GNUC_CONST; +GType unit_proxy_get_type (void) G_GNUC_CONST; +guint unit_register_object (void* object, GDBusConnection* connection, const gchar* path, GError** error); +GType unit_job_link_get_type (void) G_GNUC_CONST; +UnitJobLink* unit_job_link_dup (const UnitJobLink* self); +void unit_job_link_free (UnitJobLink* self); +void unit_job_link_copy (const UnitJobLink* self, UnitJobLink* dest); +void unit_job_link_destroy (UnitJobLink* self); +GType unit_get_type (void) G_GNUC_CONST; +GType manager_proxy_get_type (void) G_GNUC_CONST; +guint manager_register_object (void* object, GDBusConnection* connection, const gchar* path, GError** error); +GType manager_unit_info_get_type (void) G_GNUC_CONST; +ManagerUnitInfo* manager_unit_info_dup (const ManagerUnitInfo* self); +void manager_unit_info_free (ManagerUnitInfo* self); +void manager_unit_info_copy (const ManagerUnitInfo* self, ManagerUnitInfo* dest); +void manager_unit_info_destroy (ManagerUnitInfo* self); +GType manager_job_info_get_type (void) G_GNUC_CONST; +ManagerJobInfo* manager_job_info_dup (const ManagerJobInfo* self); +void manager_job_info_free (ManagerJobInfo* self); +void manager_job_info_copy (const ManagerJobInfo* self, ManagerJobInfo* dest); +void manager_job_info_destroy (ManagerJobInfo* self); +GType manager_get_type (void) G_GNUC_CONST; +#define MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_MAIN_WINDOW, MainWindowPrivate)) +enum { + MAIN_WINDOW_DUMMY_PROPERTY +}; +MainWindow* main_window_new (GError** error); +MainWindow* main_window_construct (GType object_type, GError** error); +static void _gtk_main_quit_gtk_object_destroy (GtkObject* _sender, gpointer self); +void main_window_unit_type_changed (MainWindow* self); +static void _main_window_unit_type_changed_gtk_combo_box_changed (GtkComboBox* _sender, gpointer self); +static void _main_window_unit_type_changed_gtk_toggle_button_toggled (GtkToggleButton* _sender, gpointer self); +void main_window_on_unit_load_entry_changed (MainWindow* self); +static void _main_window_on_unit_load_entry_changed_gtk_editable_changed (GtkEditable* _sender, gpointer self); +void main_window_on_unit_load (MainWindow* self); +static void _main_window_on_unit_load_gtk_entry_activate (GtkEntry* _sender, gpointer self); +static void _main_window_on_unit_load_gtk_button_clicked (GtkButton* _sender, gpointer self); +void main_window_on_server_snapshot (MainWindow* self); +static void _main_window_on_server_snapshot_gtk_button_clicked (GtkButton* _sender, gpointer self); +void main_window_on_server_reload (MainWindow* self); +static void _main_window_on_server_reload_gtk_button_clicked (GtkButton* _sender, gpointer self); +GType job_proxy_get_type (void) G_GNUC_CONST; +guint job_register_object (void* object, GDBusConnection* connection, const gchar* path, GError** error); +GType job_unit_link_get_type (void) G_GNUC_CONST; +JobUnitLink* job_unit_link_dup (const JobUnitLink* self); +void job_unit_link_free (JobUnitLink* self); +void job_unit_link_copy (const JobUnitLink* self, JobUnitLink* dest); +void job_unit_link_destroy (JobUnitLink* self); +GType job_get_type (void) G_GNUC_CONST; +gboolean main_window_unit_filter (MainWindow* self, GtkTreeModel* model, GtkTreeIter* iter); +static gboolean _main_window_unit_filter_gtk_tree_model_filter_visible_func (GtkTreeModel* model, GtkTreeIter* iter, gpointer self); +void main_window_unit_changed (MainWindow* self); +static void _main_window_unit_changed_gtk_tree_view_cursor_changed (GtkTreeView* _sender, gpointer self); +void main_window_job_changed (MainWindow* self); +static void _main_window_job_changed_gtk_tree_view_cursor_changed (GtkTreeView* _sender, gpointer self); +gboolean main_window_on_activate_link (MainWindow* self, const gchar* uri); +static gboolean _main_window_on_activate_link_gtk_label_activate_link (GtkLabel* _sender, const gchar* uri, gpointer self); +void main_window_on_start (MainWindow* self); +static void _main_window_on_start_gtk_button_clicked (GtkButton* _sender, gpointer self); +void main_window_on_stop (MainWindow* self); +static void _main_window_on_stop_gtk_button_clicked (GtkButton* _sender, gpointer self); +void main_window_on_reload (MainWindow* self); +static void _main_window_on_reload_gtk_button_clicked (GtkButton* _sender, gpointer self); +void main_window_on_restart (MainWindow* self); +static void _main_window_on_restart_gtk_button_clicked (GtkButton* _sender, gpointer self); +void main_window_on_cancel (MainWindow* self); +static void _main_window_on_cancel_gtk_button_clicked (GtkButton* _sender, gpointer self); +void main_window_on_unit_new (MainWindow* self, const gchar* id, const char* path); +static void _main_window_on_unit_new_manager_unit_new (Manager* _sender, const gchar* id, const char* path, gpointer self); +void main_window_on_job_new (MainWindow* self, guint32 id, const char* path); +static void _main_window_on_job_new_manager_job_new (Manager* _sender, guint32 id, const char* path, gpointer self); +void main_window_on_unit_removed (MainWindow* self, const gchar* id, const char* path); +static void _main_window_on_unit_removed_manager_unit_removed (Manager* _sender, const gchar* id, const char* path, gpointer self); +void main_window_on_job_removed (MainWindow* self, guint32 id, const char* path, const gchar* res); +static void _main_window_on_job_removed_manager_job_removed (Manager* _sender, guint32 id, const char* path, const gchar* res, gpointer self); +void manager_subscribe (Manager* self, GError** error); +void main_window_clear_unit (MainWindow* self); +void main_window_clear_job (MainWindow* self); +void main_window_populate_unit_model (MainWindow* self, GError** error); +void main_window_populate_job_model (MainWindow* self, GError** error); +ManagerUnitInfo* manager_list_units (Manager* self, int* result_length1, GError** error); +GType properties_proxy_get_type (void) G_GNUC_CONST; +guint properties_register_object (void* object, GDBusConnection* connection, const gchar* path, GError** error); +GType properties_get_type (void) G_GNUC_CONST; +static void _vala_ManagerUnitInfo_array_free (ManagerUnitInfo* array, gint array_length); +void main_window_on_unit_changed (MainWindow* self, Properties* p, const gchar* iface, GHashTable* changed_properties, gchar** invalidated_properties, int invalidated_properties_length1); +static void _main_window_on_unit_changed_properties_properties_changed (Properties* _sender, const gchar* iface, GHashTable* changed_properties, gchar** invalidated_properties, int invalidated_properties_length1, gpointer self); +ManagerJobInfo* manager_list_jobs (Manager* self, int* result_length1, GError** error); +static void _vala_ManagerJobInfo_array_free (ManagerJobInfo* array, gint array_length); +void main_window_on_job_changed (MainWindow* self, Properties* p, const gchar* iface, GHashTable* changed_properties, gchar** invalidated_properties, int invalidated_properties_length1); +static void _main_window_on_job_changed_properties_properties_changed (Properties* _sender, const gchar* iface, GHashTable* changed_properties, gchar** invalidated_properties, int invalidated_properties_length1, gpointer self); +Unit* main_window_get_current_unit (MainWindow* self); +Unit* main_window_get_unit (MainWindow* self, const gchar* id); +void main_window_show_unit (MainWindow* self, Unit* unit); +gchar* main_window_format_unit_link (MainWindow* self, const gchar* i, gboolean link); +gchar* unit_get_sub_state (Unit* self); +gchar* main_window_make_dependency_string (MainWindow* self, const gchar* prefix, const gchar* word, gchar** dependencies, int dependencies_length1); +gchar* unit_get_id (Unit* self); +gchar** unit_get_names (Unit* self, int* result_length1); +gchar** unit_get_requires (Unit* self, int* result_length1); +gchar** unit_get_requires_overridable (Unit* self, int* result_length1); +gchar** unit_get_requisite (Unit* self, int* result_length1); +gchar** unit_get_requisite_overridable (Unit* self, int* result_length1); +gchar** unit_get_wants (Unit* self, int* result_length1); +gchar** unit_get_required_by (Unit* self, int* result_length1); +gchar** unit_get_required_by_overridable (Unit* self, int* result_length1); +gchar** unit_get_wanted_by (Unit* self, int* result_length1); +gchar** unit_get_conflicts (Unit* self, int* result_length1); +gchar** unit_get_before (Unit* self, int* result_length1); +gchar** unit_get_after (Unit* self, int* result_length1); +gchar* unit_get_description (Unit* self); +gchar* unit_get_load_state (Unit* self); +gchar* unit_get_active_state (Unit* self); +gchar* unit_get_fragment_path (Unit* self); +guint64 unit_get_active_enter_timestamp (Unit* self); +guint64 unit_get_active_exit_timestamp (Unit* self); +gboolean unit_get_can_start (Unit* self); +gboolean unit_get_can_reload (Unit* self); +gchar* unit_get_default_control_group (Unit* self); +Job* main_window_get_current_job (MainWindow* self); +void main_window_show_job (MainWindow* self, Job* job); +guint32 job_get_id (Job* self); +gchar* job_get_state (Job* self); +gchar* job_get_job_type (Job* self); +char* unit_start (Unit* self, const gchar* mode, GError** error); +void main_window_show_error (MainWindow* self, const gchar* e); +char* unit_stop (Unit* self, const gchar* mode, GError** error); +char* unit_reload (Unit* self, const gchar* mode, GError** error); +char* unit_restart (Unit* self, const gchar* mode, GError** error); +void job_cancel (Job* self, GError** error); +void main_window_update_unit_iter (MainWindow* self, GtkTreeIter* iter, const gchar* id, Unit* u); +void unit_get_job (Unit* self, UnitJobLink* result); +void main_window_update_job_iter (MainWindow* self, GtkTreeIter* iter, guint32 id, Job* j); +void job_get_unit (Job* self, JobUnitLink* result); +void manager_reload (Manager* self, GError** error); +char* manager_create_snapshot (Manager* self, const gchar* name, gboolean cleanup, GError** error); +char* manager_load_unit (Manager* self, const gchar* name, GError** error); +char* manager_get_unit (Manager* self, const gchar* name, GError** error); +static void main_window_finalize (GObject* obj); +void show_error (const gchar* e); +gint _vala_main (gchar** args, int args_length1); +static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func); +static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func); + +const GOptionEntry entries[3] = {{"user", (gchar) 0, 0, G_OPTION_ARG_NONE, &user, "Connect to user service manager", NULL}, {"system", (gchar) 0, (gint) G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &user, "Connect to system manager", NULL}, {NULL}}; + +static void g_time_local (time_t time, struct tm* result) { + struct tm _result_ = {0}; + struct tm _tmp0_ = {0}; +#line 2491 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + localtime_r (&time, &_tmp0_); +#line 2491 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + _result_ = _tmp0_; +#line 2492 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + *result = _result_; +#line 2492 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + return; +#line 506 "systemadm.c" +} + + +static gchar* g_time_format (struct tm *self, const gchar* format) { + gchar* result = NULL; + gchar* _tmp0_ = NULL; + gchar* buffer; + gint buffer_length1; + gint _buffer_size_; + gchar* _tmp1_; + gint _tmp1__length1; + const gchar* _tmp2_; + gchar* _tmp3_; + gint _tmp3__length1; + gchar* _tmp4_; +#line 2499 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + g_return_val_if_fail (format != NULL, NULL); +#line 2500 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + _tmp0_ = g_new0 (gchar, 64); +#line 2500 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + buffer = _tmp0_; +#line 2500 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + buffer_length1 = 64; +#line 2500 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + _buffer_size_ = buffer_length1; +#line 2501 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + _tmp1_ = buffer; +#line 2501 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + _tmp1__length1 = buffer_length1; +#line 2501 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + _tmp2_ = format; +#line 2501 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + strftime (_tmp1_, _tmp1__length1, _tmp2_, &(*self)); +#line 2502 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + _tmp3_ = buffer; +#line 2502 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + _tmp3__length1 = buffer_length1; +#line 2502 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + _tmp4_ = g_strdup ((const gchar*) _tmp3_); +#line 2502 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + result = _tmp4_; +#line 2502 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + buffer = (g_free (buffer), NULL); +#line 2502 "/usr/share/vala-0.16/vapi/glib-2.0.vapi" + return result; +#line 552 "systemadm.c" +} + + +gchar* format_time (guint64 time_ns) { + gchar* result = NULL; + guint64 _tmp0_; + guint64 _tmp2_; + struct tm _tmp3_ = {0}; + struct tm timestamp; + gchar* _tmp4_ = NULL; +#line 27 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = time_ns; +#line 27 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp0_ <= ((guint64) 0)) { +#line 567 "systemadm.c" + gchar* _tmp1_; +#line 28 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = g_strdup (""); +#line 28 "/home/lennart/projects/systemd/src/systemadm.vala" + result = _tmp1_; +#line 28 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 575 "systemadm.c" + } +#line 29 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = time_ns; +#line 29 "/home/lennart/projects/systemd/src/systemadm.vala" + g_time_local ((time_t) (_tmp2_ / 1000000), &_tmp3_); +#line 29 "/home/lennart/projects/systemd/src/systemadm.vala" + timestamp = _tmp3_; +#line 30 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = g_time_format (×tamp, "%a, %d %b %Y %H:%M:%S"); +#line 30 "/home/lennart/projects/systemd/src/systemadm.vala" + result = _tmp4_; +#line 30 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 589 "systemadm.c" +} + + +void new_column (GtkTreeView* view, gint column_id, const gchar* title) { + GtkTreeViewColumn* col = NULL; + const gchar* _tmp0_; + GtkCellRendererText* _tmp1_; + GtkCellRendererText* _tmp2_; + gint _tmp3_; + GtkTreeViewColumn* _tmp4_; + GtkTreeViewColumn* _tmp5_; + gint _tmp6_; + GtkTreeView* _tmp7_; +#line 33 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (view != NULL); +#line 33 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (title != NULL); +#line 35 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = title; +#line 35 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = (GtkCellRendererText*) gtk_cell_renderer_text_new (); +#line 35 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = g_object_ref_sink (_tmp1_); +#line 35 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = column_id; +#line 35 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = gtk_tree_view_column_new_with_attributes (_tmp0_, (GtkCellRenderer*) _tmp2_, "text", _tmp3_, NULL); +#line 35 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = g_object_ref_sink (_tmp4_); +#line 35 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (col); +#line 35 "/home/lennart/projects/systemd/src/systemadm.vala" + col = _tmp5_; +#line 35 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp2_); +#line 36 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = column_id; +#line 36 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_view_column_set_sort_column_id (col, _tmp6_); +#line 37 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = view; +#line 37 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_view_insert_column (_tmp7_, col, -1); +#line 33 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (col); +#line 635 "systemadm.c" +} + + +LeftLabel* left_label_construct (GType object_type, const gchar* text) { + LeftLabel * self = NULL; + const gchar* _tmp0_; +#line 41 "/home/lennart/projects/systemd/src/systemadm.vala" + self = (LeftLabel*) g_object_new (object_type, NULL); +#line 42 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = text; +#line 42 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp0_ != NULL) { +#line 648 "systemadm.c" + const gchar* _tmp1_; + gchar* _tmp2_ = NULL; + gchar* _tmp3_; +#line 43 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = text; +#line 43 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = g_strdup_printf ("%s", _tmp1_); +#line 43 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = _tmp2_; +#line 43 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_label_set_markup ((GtkLabel*) self, _tmp3_); +#line 43 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp3_); +#line 662 "systemadm.c" + } +#line 44 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_misc_set_alignment ((GtkMisc*) self, (gfloat) 0, (gfloat) 0); +#line 45 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_misc_set_padding ((GtkMisc*) self, 6, 0); +#line 41 "/home/lennart/projects/systemd/src/systemadm.vala" + return self; +#line 670 "systemadm.c" +} + + +LeftLabel* left_label_new (const gchar* text) { +#line 41 "/home/lennart/projects/systemd/src/systemadm.vala" + return left_label_construct (TYPE_LEFT_LABEL, text); +#line 677 "systemadm.c" +} + + +static void left_label_class_init (LeftLabelClass * klass) { +#line 40 "/home/lennart/projects/systemd/src/systemadm.vala" + left_label_parent_class = g_type_class_peek_parent (klass); +#line 684 "systemadm.c" +} + + +static void left_label_instance_init (LeftLabel * self) { +} + + +GType left_label_get_type (void) { + static volatile gsize left_label_type_id__volatile = 0; + if (g_once_init_enter (&left_label_type_id__volatile)) { + static const GTypeInfo g_define_type_info = { sizeof (LeftLabelClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) left_label_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (LeftLabel), 0, (GInstanceInitFunc) left_label_instance_init, NULL }; + GType left_label_type_id; + left_label_type_id = g_type_register_static (GTK_TYPE_LABEL, "LeftLabel", &g_define_type_info, 0); + g_once_init_leave (&left_label_type_id__volatile, left_label_type_id); + } + return left_label_type_id__volatile; +} + + +RightLabel* right_label_construct (GType object_type, const gchar* text) { + RightLabel * self = NULL; + const gchar* _tmp0_; +#line 51 "/home/lennart/projects/systemd/src/systemadm.vala" + self = (RightLabel*) wrap_label_construct (object_type, NULL); +#line 52 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_label_set_selectable ((GtkLabel*) self, TRUE); +#line 53 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = text; +#line 53 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (self, _tmp0_); +#line 51 "/home/lennart/projects/systemd/src/systemadm.vala" + return self; +#line 717 "systemadm.c" +} + + +RightLabel* right_label_new (const gchar* text) { +#line 51 "/home/lennart/projects/systemd/src/systemadm.vala" + return right_label_construct (TYPE_RIGHT_LABEL, text); +#line 724 "systemadm.c" +} + + +void right_label_set_text_or_na (RightLabel* self, const gchar* text) { + gboolean _tmp0_ = FALSE; + const gchar* _tmp1_; + gboolean _tmp3_; +#line 56 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 57 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = text; +#line 57 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp1_ == NULL) { +#line 57 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = TRUE; +#line 740 "systemadm.c" + } else { + const gchar* _tmp2_; +#line 57 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = text; +#line 57 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = g_strcmp0 (_tmp2_, "") == 0; +#line 747 "systemadm.c" + } +#line 57 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = _tmp0_; +#line 57 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp3_) { +#line 58 "/home/lennart/projects/systemd/src/systemadm.vala" + wrap_label_set_markup ((WrapLabel*) self, "n/a"); +#line 755 "systemadm.c" + } else { + const gchar* _tmp4_; +#line 60 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = text; +#line 60 "/home/lennart/projects/systemd/src/systemadm.vala" + wrap_label_set_text ((WrapLabel*) self, _tmp4_); +#line 762 "systemadm.c" + } +} + + +void right_label_set_markup_or_na (RightLabel* self, const gchar* text) { + gboolean _tmp0_ = FALSE; + const gchar* _tmp1_; + gboolean _tmp3_; +#line 63 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 64 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = text; +#line 64 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp1_ == NULL) { +#line 64 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = TRUE; +#line 779 "systemadm.c" + } else { + const gchar* _tmp2_; +#line 64 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = text; +#line 64 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = g_strcmp0 (_tmp2_, "") == 0; +#line 786 "systemadm.c" + } +#line 64 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = _tmp0_; +#line 64 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp3_) { +#line 65 "/home/lennart/projects/systemd/src/systemadm.vala" + wrap_label_set_markup ((WrapLabel*) self, "n/a"); +#line 794 "systemadm.c" + } else { + const gchar* _tmp4_; +#line 67 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = text; +#line 67 "/home/lennart/projects/systemd/src/systemadm.vala" + wrap_label_set_markup ((WrapLabel*) self, _tmp4_); +#line 801 "systemadm.c" + } +} + + +static void right_label_class_init (RightLabelClass * klass) { +#line 49 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_parent_class = g_type_class_peek_parent (klass); +#line 809 "systemadm.c" +} + + +static void right_label_instance_init (RightLabel * self) { +} + + +GType right_label_get_type (void) { + static volatile gsize right_label_type_id__volatile = 0; + if (g_once_init_enter (&right_label_type_id__volatile)) { + static const GTypeInfo g_define_type_info = { sizeof (RightLabelClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) right_label_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RightLabel), 0, (GInstanceInitFunc) right_label_instance_init, NULL }; + GType right_label_type_id; + right_label_type_id = g_type_register_static (TYPE_WRAP_LABEL, "RightLabel", &g_define_type_info, 0); + g_once_init_leave (&right_label_type_id__volatile, right_label_type_id); + } + return right_label_type_id__volatile; +} + + +static void _gtk_main_quit_gtk_object_destroy (GtkObject* _sender, gpointer self) { +#line 123 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_main_quit (); +#line 832 "systemadm.c" +} + + +static void _main_window_unit_type_changed_gtk_combo_box_changed (GtkComboBox* _sender, gpointer self) { +#line 153 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_unit_type_changed (self); +#line 839 "systemadm.c" +} + + +static void _main_window_unit_type_changed_gtk_toggle_button_toggled (GtkToggleButton* _sender, gpointer self) { +#line 156 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_unit_type_changed (self); +#line 846 "systemadm.c" +} + + +static void _main_window_on_unit_load_entry_changed_gtk_editable_changed (GtkEditable* _sender, gpointer self) { +#line 163 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_unit_load_entry_changed (self); +#line 853 "systemadm.c" +} + + +static void _main_window_on_unit_load_gtk_entry_activate (GtkEntry* _sender, gpointer self) { +#line 164 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_unit_load (self); +#line 860 "systemadm.c" +} + + +static void _main_window_on_unit_load_gtk_button_clicked (GtkButton* _sender, gpointer self) { +#line 165 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_unit_load (self); +#line 867 "systemadm.c" +} + + +static void _main_window_on_server_snapshot_gtk_button_clicked (GtkButton* _sender, gpointer self) { +#line 174 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_server_snapshot (self); +#line 874 "systemadm.c" +} + + +static void _main_window_on_server_reload_gtk_button_clicked (GtkButton* _sender, gpointer self) { +#line 175 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_server_reload (self); +#line 881 "systemadm.c" +} + + +static gboolean _main_window_unit_filter_gtk_tree_model_filter_visible_func (GtkTreeModel* model, GtkTreeIter* iter, gpointer self) { + gboolean result; + result = main_window_unit_filter (self, model, iter); +#line 188 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 890 "systemadm.c" +} + + +static void _main_window_unit_changed_gtk_tree_view_cursor_changed (GtkTreeView* _sender, gpointer self) { +#line 195 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_unit_changed (self); +#line 897 "systemadm.c" +} + + +static void _main_window_job_changed_gtk_tree_view_cursor_changed (GtkTreeView* _sender, gpointer self) { +#line 196 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_job_changed (self); +#line 904 "systemadm.c" +} + + +static gboolean _main_window_on_activate_link_gtk_label_activate_link (GtkLabel* _sender, const gchar* uri, gpointer self) { + gboolean result; + result = main_window_on_activate_link (self, uri); +#line 240 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 913 "systemadm.c" +} + + +static void _main_window_on_start_gtk_button_clicked (GtkButton* _sender, gpointer self) { +#line 299 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_start (self); +#line 920 "systemadm.c" +} + + +static void _main_window_on_stop_gtk_button_clicked (GtkButton* _sender, gpointer self) { +#line 300 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_stop (self); +#line 927 "systemadm.c" +} + + +static void _main_window_on_reload_gtk_button_clicked (GtkButton* _sender, gpointer self) { +#line 301 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_reload (self); +#line 934 "systemadm.c" +} + + +static void _main_window_on_restart_gtk_button_clicked (GtkButton* _sender, gpointer self) { +#line 302 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_restart (self); +#line 941 "systemadm.c" +} + + +static void _main_window_on_cancel_gtk_button_clicked (GtkButton* _sender, gpointer self) { +#line 316 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_cancel (self); +#line 948 "systemadm.c" +} + + +static void _main_window_on_unit_new_manager_unit_new (Manager* _sender, const gchar* id, const char* path, gpointer self) { +#line 325 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_unit_new (self, id, path); +#line 955 "systemadm.c" +} + + +static void _main_window_on_job_new_manager_job_new (Manager* _sender, guint32 id, const char* path, gpointer self) { +#line 326 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_job_new (self, id, path); +#line 962 "systemadm.c" +} + + +static void _main_window_on_unit_removed_manager_unit_removed (Manager* _sender, const gchar* id, const char* path, gpointer self) { +#line 327 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_unit_removed (self, id, path); +#line 969 "systemadm.c" +} + + +static void _main_window_on_job_removed_manager_job_removed (Manager* _sender, guint32 id, const char* path, const gchar* res, gpointer self) { +#line 328 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_job_removed (self, id, path, res); +#line 976 "systemadm.c" +} + + +MainWindow* main_window_construct (GType object_type, GError** error) { + MainWindow * self = NULL; + const gchar* _tmp0_ = NULL; + gboolean _tmp1_; + const gchar* _tmp2_; + GtkNotebook* _tmp3_; + GtkNotebook* _tmp4_; + GtkNotebook* notebook; + GtkNotebook* _tmp5_; + GtkVBox* _tmp6_; + GtkBox* _tmp7_; + GtkBox* unit_vbox; + GtkNotebook* _tmp8_; + GtkBox* _tmp9_; + GtkLabel* _tmp10_; + GtkLabel* _tmp11_; + GtkBox* _tmp12_; + GtkVBox* _tmp13_; + GtkBox* _tmp14_; + GtkBox* job_vbox; + GtkNotebook* _tmp15_; + GtkBox* _tmp16_; + GtkLabel* _tmp17_; + GtkLabel* _tmp18_; + GtkBox* _tmp19_; + GtkComboBox* _tmp20_; + GtkComboBox* _tmp21_; + GtkHBox* _tmp22_; + GtkBox* _tmp23_; + GtkBox* type_hbox; + GtkBox* _tmp24_; + GtkComboBox* _tmp25_; + GtkBox* _tmp26_; + GtkBox* _tmp27_; + GtkComboBox* _tmp28_; + GtkComboBox* _tmp29_; + GtkComboBox* _tmp30_; + GtkComboBox* _tmp31_; + GtkComboBox* _tmp32_; + GtkComboBox* _tmp33_; + GtkComboBox* _tmp34_; + GtkComboBox* _tmp35_; + GtkComboBox* _tmp36_; + GtkComboBox* _tmp37_; + GtkComboBox* _tmp38_; + GtkComboBox* _tmp39_; + GtkComboBox* _tmp40_; + GtkCheckButton* _tmp41_; + GtkCheckButton* _tmp42_; + GtkCheckButton* _tmp43_; + GtkBox* _tmp44_; + GtkCheckButton* _tmp45_; + GtkEntry* _tmp46_; + GtkEntry* _tmp47_; + GtkButton* _tmp48_; + GtkButton* _tmp49_; + GtkButton* _tmp50_; + GtkEntry* _tmp51_; + GtkEntry* _tmp52_; + GtkButton* _tmp53_; + GtkHBox* _tmp54_; + GtkBox* _tmp55_; + GtkBox* unit_load_hbox; + GtkBox* _tmp56_; + GtkEntry* _tmp57_; + GtkBox* _tmp58_; + GtkButton* _tmp59_; + GtkButton* _tmp60_; + GtkButton* _tmp61_; + GtkButton* _tmp62_; + GtkButton* _tmp63_; + GtkButton* _tmp64_; + GtkButton* _tmp65_; + GtkBox* _tmp66_; + GtkButton* _tmp67_; + GtkBox* _tmp68_; + GtkButton* _tmp69_; + GtkBox* _tmp70_; + GtkBox* _tmp71_; + GtkListStore* _tmp72_; + GtkListStore* _tmp73_; + GeeHashMap* _tmp74_; + GtkTreeModelFilter* unit_model_filter = NULL; + GtkListStore* _tmp75_; + GtkTreeModelFilter* _tmp76_; + GtkTreeModelFilter* _tmp77_; + GtkTreeModelFilter* _tmp78_; + GtkTreeModelSort* _tmp79_; + GtkTreeModelSort* unit_model_sort; + GtkTreeModelSort* _tmp80_; + GtkTreeView* _tmp81_; + GtkTreeView* _tmp82_; + GtkListStore* _tmp83_; + GtkTreeView* _tmp84_; + GtkTreeView* _tmp85_; + GtkTreeView* _tmp86_; + GtkTreeView* _tmp87_; + GtkTreeView* _tmp88_; + GtkTreeView* _tmp89_; + GtkTreeView* _tmp90_; + GtkTreeView* _tmp91_; + GtkTreeView* _tmp92_; + GtkTreeView* _tmp93_; + GtkTreeView* _tmp94_; + GtkTreeView* _tmp95_; + GtkTreeView* _tmp96_; + GtkScrolledWindow* _tmp97_; + GtkScrolledWindow* _tmp98_; + GtkScrolledWindow* scroll; + GtkScrolledWindow* _tmp99_; + GtkScrolledWindow* _tmp100_; + GtkScrolledWindow* _tmp101_; + GtkTreeView* _tmp102_; + GtkBox* _tmp103_; + GtkScrolledWindow* _tmp104_; + GtkScrolledWindow* _tmp105_; + GtkScrolledWindow* _tmp106_; + GtkScrolledWindow* _tmp107_; + GtkScrolledWindow* _tmp108_; + GtkScrolledWindow* _tmp109_; + GtkTreeView* _tmp110_; + GtkBox* _tmp111_; + GtkScrolledWindow* _tmp112_; + RightLabel* _tmp113_; + RightLabel* _tmp114_; + RightLabel* _tmp115_; + RightLabel* _tmp116_; + RightLabel* _tmp117_; + RightLabel* _tmp118_; + RightLabel* _tmp119_; + RightLabel* _tmp120_; + RightLabel* _tmp121_; + RightLabel* _tmp122_; + RightLabel* _tmp123_; + RightLabel* _tmp124_; + RightLabel* _tmp125_; + RightLabel* _tmp126_; + RightLabel* _tmp127_; + RightLabel* _tmp128_; + RightLabel* _tmp129_; + RightLabel* _tmp130_; + RightLabel* _tmp131_; + RightLabel* _tmp132_; + RightLabel* _tmp133_; + RightLabel* _tmp134_; + RightLabel* _tmp135_; + RightLabel* _tmp136_; + RightLabel* _tmp137_; + RightLabel* _tmp138_; + RightLabel* _tmp139_; + RightLabel* _tmp140_; + RightLabel* _tmp141_; + RightLabel* _tmp142_; + RightLabel* _tmp143_; + RightLabel* _tmp144_; + RightLabel* _tmp145_; + RightLabel* _tmp146_; + GtkTable* _tmp147_; + GtkTable* _tmp148_; + GtkTable* unit_table; + GtkTable* _tmp149_; + GtkTable* _tmp150_; + GtkBox* _tmp151_; + GtkTable* _tmp152_; + GtkTable* _tmp153_; + GtkTable* _tmp154_; + GtkTable* job_table; + GtkTable* _tmp155_; + GtkTable* _tmp156_; + GtkBox* _tmp157_; + GtkTable* _tmp158_; + GtkTable* _tmp159_; + LeftLabel* _tmp160_; + LeftLabel* _tmp161_; + GtkTable* _tmp162_; + RightLabel* _tmp163_; + GtkTable* _tmp164_; + LeftLabel* _tmp165_; + LeftLabel* _tmp166_; + GtkTable* _tmp167_; + RightLabel* _tmp168_; + GtkTable* _tmp169_; + LeftLabel* _tmp170_; + LeftLabel* _tmp171_; + GtkTable* _tmp172_; + RightLabel* _tmp173_; + GtkTable* _tmp174_; + LeftLabel* _tmp175_; + LeftLabel* _tmp176_; + GtkTable* _tmp177_; + RightLabel* _tmp178_; + GtkTable* _tmp179_; + LeftLabel* _tmp180_; + LeftLabel* _tmp181_; + GtkTable* _tmp182_; + RightLabel* _tmp183_; + GtkTable* _tmp184_; + LeftLabel* _tmp185_; + LeftLabel* _tmp186_; + GtkTable* _tmp187_; + RightLabel* _tmp188_; + GtkTable* _tmp189_; + LeftLabel* _tmp190_; + LeftLabel* _tmp191_; + GtkTable* _tmp192_; + RightLabel* _tmp193_; + GtkTable* _tmp194_; + LeftLabel* _tmp195_; + LeftLabel* _tmp196_; + GtkTable* _tmp197_; + RightLabel* _tmp198_; + GtkTable* _tmp199_; + LeftLabel* _tmp200_; + LeftLabel* _tmp201_; + GtkTable* _tmp202_; + RightLabel* _tmp203_; + GtkTable* _tmp204_; + LeftLabel* _tmp205_; + LeftLabel* _tmp206_; + GtkTable* _tmp207_; + RightLabel* _tmp208_; + GtkTable* _tmp209_; + LeftLabel* _tmp210_; + LeftLabel* _tmp211_; + GtkTable* _tmp212_; + RightLabel* _tmp213_; + GtkTable* _tmp214_; + LeftLabel* _tmp215_; + LeftLabel* _tmp216_; + GtkTable* _tmp217_; + RightLabel* _tmp218_; + GtkTable* _tmp219_; + LeftLabel* _tmp220_; + LeftLabel* _tmp221_; + GtkTable* _tmp222_; + RightLabel* _tmp223_; + GtkTable* _tmp224_; + LeftLabel* _tmp225_; + LeftLabel* _tmp226_; + GtkTable* _tmp227_; + RightLabel* _tmp228_; + GtkTable* _tmp229_; + LeftLabel* _tmp230_; + LeftLabel* _tmp231_; + GtkTable* _tmp232_; + RightLabel* _tmp233_; + GtkHButtonBox* _tmp234_; + GtkButtonBox* _tmp235_; + GtkButtonBox* bbox; + GtkButtonBox* _tmp236_; + GtkButtonBox* _tmp237_; + GtkBox* _tmp238_; + GtkButtonBox* _tmp239_; + GtkButton* _tmp240_; + GtkButton* _tmp241_; + GtkButton* _tmp242_; + GtkButton* _tmp243_; + GtkButton* _tmp244_; + GtkButton* _tmp245_; + GtkButton* _tmp246_; + GtkButton* _tmp247_; + GtkButton* _tmp248_; + GtkButton* _tmp249_; + GtkButton* _tmp250_; + GtkButton* _tmp251_; + GtkButtonBox* _tmp252_; + GtkButton* _tmp253_; + GtkButtonBox* _tmp254_; + GtkButton* _tmp255_; + GtkButtonBox* _tmp256_; + GtkButton* _tmp257_; + GtkButtonBox* _tmp258_; + GtkButton* _tmp259_; + GtkHButtonBox* _tmp260_; + GtkButtonBox* _tmp261_; + GtkButtonBox* _tmp262_; + GtkButtonBox* _tmp263_; + GtkBox* _tmp264_; + GtkButtonBox* _tmp265_; + GtkButton* _tmp266_; + GtkButton* _tmp267_; + GtkButton* _tmp268_; + GtkButtonBox* _tmp269_; + GtkButton* _tmp270_; + GBusType _tmp271_ = 0; + gboolean _tmp272_; + GBusType _tmp273_; + Manager* _tmp274_ = NULL; + Manager* _tmp275_; + Manager* _tmp276_; + Manager* _tmp277_; + Manager* _tmp278_; + Manager* _tmp279_; + Manager* _tmp280_; + GError * _inner_error_ = NULL; +#line 118 "/home/lennart/projects/systemd/src/systemadm.vala" + self = (MainWindow*) g_object_new (object_type, NULL); +#line 119 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = user; +#line 119 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp1_) { +#line 119 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = "systemd User Service Manager"; +#line 1283 "systemadm.c" + } else { +#line 119 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = "systemd System Manager"; +#line 1287 "systemadm.c" + } +#line 119 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = _tmp0_; +#line 119 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_window_set_title ((GtkWindow*) self, _tmp2_); +#line 120 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_window_set_position ((GtkWindow*) self, GTK_WIN_POS_CENTER); +#line 121 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_window_set_default_size ((GtkWindow*) self, 1000, 700); +#line 122 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_container_set_border_width ((GtkContainer*) self, (guint) 12); +#line 123 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect ((GtkObject*) self, "destroy", (GCallback) _gtk_main_quit_gtk_object_destroy, NULL); +#line 125 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = (GtkNotebook*) gtk_notebook_new (); +#line 125 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = g_object_ref_sink (_tmp3_); +#line 125 "/home/lennart/projects/systemd/src/systemadm.vala" + notebook = _tmp4_; +#line 126 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = notebook; +#line 126 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_container_add ((GtkContainer*) self, (GtkWidget*) _tmp5_); +#line 128 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = (GtkVBox*) gtk_vbox_new (FALSE, 12); +#line 128 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = (GtkBox*) g_object_ref_sink (_tmp6_); +#line 128 "/home/lennart/projects/systemd/src/systemadm.vala" + unit_vbox = _tmp7_; +#line 129 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = notebook; +#line 129 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = unit_vbox; +#line 129 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = (GtkLabel*) gtk_label_new ("Units"); +#line 129 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = g_object_ref_sink (_tmp10_); +#line 129 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_notebook_append_page (_tmp8_, (GtkWidget*) _tmp9_, (GtkWidget*) _tmp11_); +#line 129 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp11_); +#line 130 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = unit_vbox; +#line 130 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_container_set_border_width ((GtkContainer*) _tmp12_, (guint) 12); +#line 132 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = (GtkVBox*) gtk_vbox_new (FALSE, 12); +#line 132 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = (GtkBox*) g_object_ref_sink (_tmp13_); +#line 132 "/home/lennart/projects/systemd/src/systemadm.vala" + job_vbox = _tmp14_; +#line 133 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = notebook; +#line 133 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = job_vbox; +#line 133 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = (GtkLabel*) gtk_label_new ("Jobs"); +#line 133 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp18_ = g_object_ref_sink (_tmp17_); +#line 133 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_notebook_append_page (_tmp15_, (GtkWidget*) _tmp16_, (GtkWidget*) _tmp18_); +#line 133 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp18_); +#line 134 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp19_ = job_vbox; +#line 134 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_container_set_border_width ((GtkContainer*) _tmp19_, (guint) 12); +#line 136 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp20_ = (GtkComboBox*) gtk_combo_box_new_text (); +#line 136 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp21_ = g_object_ref_sink (_tmp20_); +#line 136 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_type_combo_box); +#line 136 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_type_combo_box = _tmp21_; +#line 137 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp22_ = (GtkHBox*) gtk_hbox_new (FALSE, 6); +#line 137 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp23_ = (GtkBox*) g_object_ref_sink (_tmp22_); +#line 137 "/home/lennart/projects/systemd/src/systemadm.vala" + type_hbox = _tmp23_; +#line 138 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp24_ = type_hbox; +#line 138 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp25_ = self->priv->unit_type_combo_box; +#line 138 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start (_tmp24_, (GtkWidget*) _tmp25_, FALSE, FALSE, (guint) 0); +#line 139 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp26_ = unit_vbox; +#line 139 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp27_ = type_hbox; +#line 139 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start (_tmp26_, (GtkWidget*) _tmp27_, FALSE, FALSE, (guint) 0); +#line 141 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp28_ = self->priv->unit_type_combo_box; +#line 141 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_combo_box_append_text (_tmp28_, "All unit types"); +#line 142 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp29_ = self->priv->unit_type_combo_box; +#line 142 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_combo_box_append_text (_tmp29_, "Targets"); +#line 143 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp30_ = self->priv->unit_type_combo_box; +#line 143 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_combo_box_append_text (_tmp30_, "Services"); +#line 144 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp31_ = self->priv->unit_type_combo_box; +#line 144 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_combo_box_append_text (_tmp31_, "Devices"); +#line 145 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp32_ = self->priv->unit_type_combo_box; +#line 145 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_combo_box_append_text (_tmp32_, "Mounts"); +#line 146 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp33_ = self->priv->unit_type_combo_box; +#line 146 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_combo_box_append_text (_tmp33_, "Automounts"); +#line 147 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp34_ = self->priv->unit_type_combo_box; +#line 147 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_combo_box_append_text (_tmp34_, "Swaps"); +#line 148 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp35_ = self->priv->unit_type_combo_box; +#line 148 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_combo_box_append_text (_tmp35_, "Sockets"); +#line 149 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp36_ = self->priv->unit_type_combo_box; +#line 149 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_combo_box_append_text (_tmp36_, "Paths"); +#line 150 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp37_ = self->priv->unit_type_combo_box; +#line 150 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_combo_box_append_text (_tmp37_, "Timers"); +#line 151 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp38_ = self->priv->unit_type_combo_box; +#line 151 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_combo_box_append_text (_tmp38_, "Snapshots"); +#line 152 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp39_ = self->priv->unit_type_combo_box; +#line 152 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_combo_box_set_active (_tmp39_, 0); +#line 153 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp40_ = self->priv->unit_type_combo_box; +#line 153 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp40_, "changed", (GCallback) _main_window_unit_type_changed_gtk_combo_box_changed, self, 0); +#line 155 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp41_ = (GtkCheckButton*) gtk_check_button_new_with_label ("inactive too"); +#line 155 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp42_ = g_object_ref_sink (_tmp41_); +#line 155 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->inactive_checkbox); +#line 155 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->inactive_checkbox = _tmp42_; +#line 156 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp43_ = self->priv->inactive_checkbox; +#line 156 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object ((GtkToggleButton*) _tmp43_, "toggled", (GCallback) _main_window_unit_type_changed_gtk_toggle_button_toggled, self, 0); +#line 157 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp44_ = type_hbox; +#line 157 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp45_ = self->priv->inactive_checkbox; +#line 157 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start (_tmp44_, (GtkWidget*) _tmp45_, FALSE, FALSE, (guint) 0); +#line 159 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp46_ = (GtkEntry*) gtk_entry_new (); +#line 159 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp47_ = g_object_ref_sink (_tmp46_); +#line 159 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_load_entry); +#line 159 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_load_entry = _tmp47_; +#line 160 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp48_ = (GtkButton*) gtk_button_new_with_mnemonic ("_Load"); +#line 160 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp49_ = g_object_ref_sink (_tmp48_); +#line 160 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_load_button); +#line 160 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_load_button = _tmp49_; +#line 161 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp50_ = self->priv->unit_load_button; +#line 161 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_widget_set_sensitive ((GtkWidget*) _tmp50_, FALSE); +#line 163 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp51_ = self->priv->unit_load_entry; +#line 163 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object ((GtkEditable*) _tmp51_, "changed", (GCallback) _main_window_on_unit_load_entry_changed_gtk_editable_changed, self, 0); +#line 164 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp52_ = self->priv->unit_load_entry; +#line 164 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp52_, "activate", (GCallback) _main_window_on_unit_load_gtk_entry_activate, self, 0); +#line 165 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp53_ = self->priv->unit_load_button; +#line 165 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp53_, "clicked", (GCallback) _main_window_on_unit_load_gtk_button_clicked, self, 0); +#line 167 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp54_ = (GtkHBox*) gtk_hbox_new (FALSE, 6); +#line 167 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp55_ = (GtkBox*) g_object_ref_sink (_tmp54_); +#line 167 "/home/lennart/projects/systemd/src/systemadm.vala" + unit_load_hbox = _tmp55_; +#line 168 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp56_ = unit_load_hbox; +#line 168 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp57_ = self->priv->unit_load_entry; +#line 168 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start (_tmp56_, (GtkWidget*) _tmp57_, FALSE, TRUE, (guint) 0); +#line 169 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp58_ = unit_load_hbox; +#line 169 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp59_ = self->priv->unit_load_button; +#line 169 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start (_tmp58_, (GtkWidget*) _tmp59_, FALSE, TRUE, (guint) 0); +#line 171 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp60_ = (GtkButton*) gtk_button_new_with_mnemonic ("Take S_napshot"); +#line 171 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp61_ = g_object_ref_sink (_tmp60_); +#line 171 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->server_snapshot_button); +#line 171 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->server_snapshot_button = _tmp61_; +#line 172 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp62_ = (GtkButton*) gtk_button_new_with_mnemonic ("Reload _Configuration"); +#line 172 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp63_ = g_object_ref_sink (_tmp62_); +#line 172 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->server_reload_button); +#line 172 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->server_reload_button = _tmp63_; +#line 174 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp64_ = self->priv->server_snapshot_button; +#line 174 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp64_, "clicked", (GCallback) _main_window_on_server_snapshot_gtk_button_clicked, self, 0); +#line 175 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp65_ = self->priv->server_reload_button; +#line 175 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp65_, "clicked", (GCallback) _main_window_on_server_reload_gtk_button_clicked, self, 0); +#line 177 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp66_ = type_hbox; +#line 177 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp67_ = self->priv->server_snapshot_button; +#line 177 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_end (_tmp66_, (GtkWidget*) _tmp67_, FALSE, TRUE, (guint) 0); +#line 178 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp68_ = type_hbox; +#line 178 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp69_ = self->priv->server_reload_button; +#line 178 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_end (_tmp68_, (GtkWidget*) _tmp69_, FALSE, TRUE, (guint) 0); +#line 179 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp70_ = type_hbox; +#line 179 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp71_ = unit_load_hbox; +#line 179 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_end (_tmp70_, (GtkWidget*) _tmp71_, FALSE, TRUE, (guint) 24); +#line 181 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp72_ = gtk_list_store_new (7, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, TYPE_UNIT); +#line 181 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_model); +#line 181 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_model = _tmp72_; +#line 182 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp73_ = gtk_list_store_new (6, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, TYPE_JOB, G_TYPE_UINT); +#line 182 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->job_model); +#line 182 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->job_model = _tmp73_; +#line 184 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp74_ = gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, TYPE_UNIT, (GBoxedCopyFunc) g_object_ref, g_object_unref, NULL, NULL, NULL); +#line 184 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_map); +#line 184 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_map = _tmp74_; +#line 187 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp75_ = self->priv->unit_model; +#line 187 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp76_ = (GtkTreeModelFilter*) gtk_tree_model_filter_new ((GtkTreeModel*) _tmp75_, NULL); +#line 187 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_filter); +#line 187 "/home/lennart/projects/systemd/src/systemadm.vala" + unit_model_filter = _tmp76_; +#line 188 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp77_ = unit_model_filter; +#line 188 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_model_filter_set_visible_func (_tmp77_, _main_window_unit_filter_gtk_tree_model_filter_visible_func, g_object_ref (self), g_object_unref); +#line 190 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp78_ = unit_model_filter; +#line 190 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp79_ = (GtkTreeModelSort*) gtk_tree_model_sort_new_with_model ((GtkTreeModel*) _tmp78_); +#line 190 "/home/lennart/projects/systemd/src/systemadm.vala" + unit_model_sort = _tmp79_; +#line 192 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp80_ = unit_model_sort; +#line 192 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp81_ = (GtkTreeView*) gtk_tree_view_new_with_model ((GtkTreeModel*) _tmp80_); +#line 192 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp82_ = g_object_ref_sink (_tmp81_); +#line 192 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_view); +#line 192 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_view = _tmp82_; +#line 193 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp83_ = self->priv->job_model; +#line 193 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp84_ = (GtkTreeView*) gtk_tree_view_new_with_model ((GtkTreeModel*) _tmp83_); +#line 193 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp85_ = g_object_ref_sink (_tmp84_); +#line 193 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->job_view); +#line 193 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->job_view = _tmp85_; +#line 195 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp86_ = self->priv->unit_view; +#line 195 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp86_, "cursor-changed", (GCallback) _main_window_unit_changed_gtk_tree_view_cursor_changed, self, 0); +#line 196 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp87_ = self->priv->job_view; +#line 196 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp87_, "cursor-changed", (GCallback) _main_window_job_changed_gtk_tree_view_cursor_changed, self, 0); +#line 198 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp88_ = self->priv->unit_view; +#line 198 "/home/lennart/projects/systemd/src/systemadm.vala" + new_column (_tmp88_, 2, "Load State"); +#line 199 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp89_ = self->priv->unit_view; +#line 199 "/home/lennart/projects/systemd/src/systemadm.vala" + new_column (_tmp89_, 3, "Active State"); +#line 200 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp90_ = self->priv->unit_view; +#line 200 "/home/lennart/projects/systemd/src/systemadm.vala" + new_column (_tmp90_, 4, "Unit State"); +#line 201 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp91_ = self->priv->unit_view; +#line 201 "/home/lennart/projects/systemd/src/systemadm.vala" + new_column (_tmp91_, 0, "Unit"); +#line 202 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp92_ = self->priv->unit_view; +#line 202 "/home/lennart/projects/systemd/src/systemadm.vala" + new_column (_tmp92_, 5, "Job"); +#line 204 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp93_ = self->priv->job_view; +#line 204 "/home/lennart/projects/systemd/src/systemadm.vala" + new_column (_tmp93_, 0, "Job"); +#line 205 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp94_ = self->priv->job_view; +#line 205 "/home/lennart/projects/systemd/src/systemadm.vala" + new_column (_tmp94_, 1, "Unit"); +#line 206 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp95_ = self->priv->job_view; +#line 206 "/home/lennart/projects/systemd/src/systemadm.vala" + new_column (_tmp95_, 2, "Type"); +#line 207 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp96_ = self->priv->job_view; +#line 207 "/home/lennart/projects/systemd/src/systemadm.vala" + new_column (_tmp96_, 3, "State"); +#line 209 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp97_ = (GtkScrolledWindow*) gtk_scrolled_window_new (NULL, NULL); +#line 209 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp98_ = g_object_ref_sink (_tmp97_); +#line 209 "/home/lennart/projects/systemd/src/systemadm.vala" + scroll = _tmp98_; +#line 210 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp99_ = scroll; +#line 210 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_scrolled_window_set_policy (_tmp99_, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); +#line 211 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp100_ = scroll; +#line 211 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_scrolled_window_set_shadow_type (_tmp100_, GTK_SHADOW_IN); +#line 212 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp101_ = scroll; +#line 212 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp102_ = self->priv->unit_view; +#line 212 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_container_add ((GtkContainer*) _tmp101_, (GtkWidget*) _tmp102_); +#line 213 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp103_ = unit_vbox; +#line 213 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp104_ = scroll; +#line 213 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start (_tmp103_, (GtkWidget*) _tmp104_, TRUE, TRUE, (guint) 0); +#line 215 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp105_ = (GtkScrolledWindow*) gtk_scrolled_window_new (NULL, NULL); +#line 215 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp106_ = g_object_ref_sink (_tmp105_); +#line 215 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (scroll); +#line 215 "/home/lennart/projects/systemd/src/systemadm.vala" + scroll = _tmp106_; +#line 216 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp107_ = scroll; +#line 216 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_scrolled_window_set_policy (_tmp107_, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); +#line 217 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp108_ = scroll; +#line 217 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_scrolled_window_set_shadow_type (_tmp108_, GTK_SHADOW_IN); +#line 218 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp109_ = scroll; +#line 218 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp110_ = self->priv->job_view; +#line 218 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_container_add ((GtkContainer*) _tmp109_, (GtkWidget*) _tmp110_); +#line 219 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp111_ = job_vbox; +#line 219 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp112_ = scroll; +#line 219 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start (_tmp111_, (GtkWidget*) _tmp112_, TRUE, TRUE, (guint) 0); +#line 221 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp113_ = right_label_new (NULL); +#line 221 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp114_ = g_object_ref_sink (_tmp113_); +#line 221 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_id_label); +#line 221 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_id_label = _tmp114_; +#line 222 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp115_ = right_label_new (NULL); +#line 222 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp116_ = g_object_ref_sink (_tmp115_); +#line 222 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_dependency_label); +#line 222 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_dependency_label = _tmp116_; +#line 223 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp117_ = right_label_new (NULL); +#line 223 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp118_ = g_object_ref_sink (_tmp117_); +#line 223 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_description_label); +#line 223 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_description_label = _tmp118_; +#line 224 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp119_ = right_label_new (NULL); +#line 224 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp120_ = g_object_ref_sink (_tmp119_); +#line 224 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_load_state_label); +#line 224 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_load_state_label = _tmp120_; +#line 225 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp121_ = right_label_new (NULL); +#line 225 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp122_ = g_object_ref_sink (_tmp121_); +#line 225 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_active_state_label); +#line 225 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_active_state_label = _tmp122_; +#line 226 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp123_ = right_label_new (NULL); +#line 226 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp124_ = g_object_ref_sink (_tmp123_); +#line 226 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_sub_state_label); +#line 226 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_sub_state_label = _tmp124_; +#line 227 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp125_ = right_label_new (NULL); +#line 227 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp126_ = g_object_ref_sink (_tmp125_); +#line 227 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_fragment_path_label); +#line 227 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_fragment_path_label = _tmp126_; +#line 228 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp127_ = right_label_new (NULL); +#line 228 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp128_ = g_object_ref_sink (_tmp127_); +#line 228 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_active_enter_timestamp_label); +#line 228 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_active_enter_timestamp_label = _tmp128_; +#line 229 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp129_ = right_label_new (NULL); +#line 229 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp130_ = g_object_ref_sink (_tmp129_); +#line 229 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_active_exit_timestamp_label); +#line 229 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_active_exit_timestamp_label = _tmp130_; +#line 230 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp131_ = right_label_new (NULL); +#line 230 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp132_ = g_object_ref_sink (_tmp131_); +#line 230 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_can_start_label); +#line 230 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_can_start_label = _tmp132_; +#line 231 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp133_ = right_label_new (NULL); +#line 231 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp134_ = g_object_ref_sink (_tmp133_); +#line 231 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_can_reload_label); +#line 231 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_can_reload_label = _tmp134_; +#line 232 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp135_ = right_label_new (NULL); +#line 232 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp136_ = g_object_ref_sink (_tmp135_); +#line 232 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_cgroup_label); +#line 232 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->unit_cgroup_label = _tmp136_; +#line 234 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp137_ = right_label_new (NULL); +#line 234 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp138_ = g_object_ref_sink (_tmp137_); +#line 234 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->job_id_label); +#line 234 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->job_id_label = _tmp138_; +#line 235 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp139_ = right_label_new (NULL); +#line 235 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp140_ = g_object_ref_sink (_tmp139_); +#line 235 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->job_state_label); +#line 235 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->job_state_label = _tmp140_; +#line 236 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp141_ = right_label_new (NULL); +#line 236 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp142_ = g_object_ref_sink (_tmp141_); +#line 236 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->job_type_label); +#line 236 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->job_type_label = _tmp142_; +#line 238 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp143_ = self->priv->unit_dependency_label; +#line 238 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_label_set_track_visited_links ((GtkLabel*) _tmp143_, FALSE); +#line 239 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp144_ = self->priv->unit_dependency_label; +#line 239 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_label_set_selectable ((GtkLabel*) _tmp144_, TRUE); +#line 240 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp145_ = self->priv->unit_dependency_label; +#line 240 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object ((GtkLabel*) _tmp145_, "activate-link", (GCallback) _main_window_on_activate_link_gtk_label_activate_link, self, 0); +#line 242 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp146_ = self->priv->unit_fragment_path_label; +#line 242 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_label_set_track_visited_links ((GtkLabel*) _tmp146_, FALSE); +#line 244 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp147_ = (GtkTable*) gtk_table_new ((guint) 8, (guint) 6, FALSE); +#line 244 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp148_ = g_object_ref_sink (_tmp147_); +#line 244 "/home/lennart/projects/systemd/src/systemadm.vala" + unit_table = _tmp148_; +#line 245 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp149_ = unit_table; +#line 245 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_set_row_spacings (_tmp149_, (guint) 6); +#line 246 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp150_ = unit_table; +#line 246 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_container_set_border_width ((GtkContainer*) _tmp150_, (guint) 0); +#line 247 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp151_ = unit_vbox; +#line 247 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp152_ = unit_table; +#line 247 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start (_tmp151_, (GtkWidget*) _tmp152_, FALSE, TRUE, (guint) 0); +#line 249 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp153_ = (GtkTable*) gtk_table_new ((guint) 2, (guint) 2, FALSE); +#line 249 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp154_ = g_object_ref_sink (_tmp153_); +#line 249 "/home/lennart/projects/systemd/src/systemadm.vala" + job_table = _tmp154_; +#line 250 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp155_ = job_table; +#line 250 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_set_row_spacings (_tmp155_, (guint) 6); +#line 251 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp156_ = job_table; +#line 251 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_container_set_border_width ((GtkContainer*) _tmp156_, (guint) 0); +#line 252 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp157_ = job_vbox; +#line 252 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp158_ = job_table; +#line 252 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start (_tmp157_, (GtkWidget*) _tmp158_, FALSE, TRUE, (guint) 0); +#line 254 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp159_ = unit_table; +#line 254 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp160_ = left_label_new ("Id:"); +#line 254 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp161_ = g_object_ref_sink (_tmp160_); +#line 254 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp159_, (GtkWidget*) _tmp161_, (guint) 0, (guint) 1, (guint) 0, (guint) 1, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 254 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp161_); +#line 255 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp162_ = unit_table; +#line 255 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp163_ = self->priv->unit_id_label; +#line 255 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp162_, (GtkWidget*) _tmp163_, (guint) 1, (guint) 6, (guint) 0, (guint) 1, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 256 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp164_ = unit_table; +#line 256 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp165_ = left_label_new ("Description:"); +#line 256 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp166_ = g_object_ref_sink (_tmp165_); +#line 256 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp164_, (GtkWidget*) _tmp166_, (guint) 0, (guint) 1, (guint) 1, (guint) 2, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 256 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp166_); +#line 257 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp167_ = unit_table; +#line 257 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp168_ = self->priv->unit_description_label; +#line 257 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp167_, (GtkWidget*) _tmp168_, (guint) 1, (guint) 6, (guint) 1, (guint) 2, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 258 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp169_ = unit_table; +#line 258 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp170_ = left_label_new ("Dependencies:"); +#line 258 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp171_ = g_object_ref_sink (_tmp170_); +#line 258 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp169_, (GtkWidget*) _tmp171_, (guint) 0, (guint) 1, (guint) 2, (guint) 3, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 258 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp171_); +#line 259 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp172_ = unit_table; +#line 259 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp173_ = self->priv->unit_dependency_label; +#line 259 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp172_, (GtkWidget*) _tmp173_, (guint) 1, (guint) 6, (guint) 2, (guint) 3, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 260 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp174_ = unit_table; +#line 260 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp175_ = left_label_new ("Fragment Path:"); +#line 260 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp176_ = g_object_ref_sink (_tmp175_); +#line 260 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp174_, (GtkWidget*) _tmp176_, (guint) 0, (guint) 1, (guint) 3, (guint) 4, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 260 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp176_); +#line 261 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp177_ = unit_table; +#line 261 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp178_ = self->priv->unit_fragment_path_label; +#line 261 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp177_, (GtkWidget*) _tmp178_, (guint) 1, (guint) 6, (guint) 3, (guint) 4, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 262 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp179_ = unit_table; +#line 262 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp180_ = left_label_new ("Control Group:"); +#line 262 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp181_ = g_object_ref_sink (_tmp180_); +#line 262 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp179_, (GtkWidget*) _tmp181_, (guint) 0, (guint) 1, (guint) 4, (guint) 5, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 262 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp181_); +#line 263 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp182_ = unit_table; +#line 263 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp183_ = self->priv->unit_cgroup_label; +#line 263 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp182_, (GtkWidget*) _tmp183_, (guint) 1, (guint) 6, (guint) 4, (guint) 5, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 265 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp184_ = unit_table; +#line 265 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp185_ = left_label_new ("Load State:"); +#line 265 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp186_ = g_object_ref_sink (_tmp185_); +#line 265 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp184_, (GtkWidget*) _tmp186_, (guint) 0, (guint) 1, (guint) 5, (guint) 6, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 265 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp186_); +#line 266 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp187_ = unit_table; +#line 266 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp188_ = self->priv->unit_load_state_label; +#line 266 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp187_, (GtkWidget*) _tmp188_, (guint) 1, (guint) 2, (guint) 5, (guint) 6, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 267 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp189_ = unit_table; +#line 267 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp190_ = left_label_new ("Active State:"); +#line 267 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp191_ = g_object_ref_sink (_tmp190_); +#line 267 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp189_, (GtkWidget*) _tmp191_, (guint) 0, (guint) 1, (guint) 6, (guint) 7, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 267 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp191_); +#line 268 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp192_ = unit_table; +#line 268 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp193_ = self->priv->unit_active_state_label; +#line 268 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp192_, (GtkWidget*) _tmp193_, (guint) 1, (guint) 2, (guint) 6, (guint) 7, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 269 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp194_ = unit_table; +#line 269 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp195_ = left_label_new ("Unit State:"); +#line 269 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp196_ = g_object_ref_sink (_tmp195_); +#line 269 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp194_, (GtkWidget*) _tmp196_, (guint) 0, (guint) 1, (guint) 7, (guint) 8, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 269 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp196_); +#line 270 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp197_ = unit_table; +#line 270 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp198_ = self->priv->unit_sub_state_label; +#line 270 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp197_, (GtkWidget*) _tmp198_, (guint) 1, (guint) 2, (guint) 7, (guint) 8, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 272 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp199_ = unit_table; +#line 272 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp200_ = left_label_new ("Activated:"); +#line 272 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp201_ = g_object_ref_sink (_tmp200_); +#line 272 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp199_, (GtkWidget*) _tmp201_, (guint) 2, (guint) 3, (guint) 6, (guint) 7, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 272 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp201_); +#line 273 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp202_ = unit_table; +#line 273 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp203_ = self->priv->unit_active_enter_timestamp_label; +#line 273 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp202_, (GtkWidget*) _tmp203_, (guint) 3, (guint) 4, (guint) 6, (guint) 7, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 274 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp204_ = unit_table; +#line 274 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp205_ = left_label_new ("Deactivated:"); +#line 274 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp206_ = g_object_ref_sink (_tmp205_); +#line 274 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp204_, (GtkWidget*) _tmp206_, (guint) 2, (guint) 3, (guint) 7, (guint) 8, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 274 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp206_); +#line 275 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp207_ = unit_table; +#line 275 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp208_ = self->priv->unit_active_exit_timestamp_label; +#line 275 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp207_, (GtkWidget*) _tmp208_, (guint) 3, (guint) 4, (guint) 7, (guint) 8, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 277 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp209_ = unit_table; +#line 277 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp210_ = left_label_new ("Can Start/Stop:"); +#line 277 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp211_ = g_object_ref_sink (_tmp210_); +#line 277 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp209_, (GtkWidget*) _tmp211_, (guint) 4, (guint) 5, (guint) 6, (guint) 7, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 277 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp211_); +#line 278 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp212_ = unit_table; +#line 278 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp213_ = self->priv->unit_can_start_label; +#line 278 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp212_, (GtkWidget*) _tmp213_, (guint) 5, (guint) 6, (guint) 6, (guint) 7, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 279 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp214_ = unit_table; +#line 279 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp215_ = left_label_new ("Can Reload:"); +#line 279 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp216_ = g_object_ref_sink (_tmp215_); +#line 279 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp214_, (GtkWidget*) _tmp216_, (guint) 4, (guint) 5, (guint) 7, (guint) 8, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 279 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp216_); +#line 280 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp217_ = unit_table; +#line 280 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp218_ = self->priv->unit_can_reload_label; +#line 280 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp217_, (GtkWidget*) _tmp218_, (guint) 5, (guint) 6, (guint) 7, (guint) 8, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 282 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp219_ = job_table; +#line 282 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp220_ = left_label_new ("Id:"); +#line 282 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp221_ = g_object_ref_sink (_tmp220_); +#line 282 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp219_, (GtkWidget*) _tmp221_, (guint) 0, (guint) 1, (guint) 0, (guint) 1, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 282 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp221_); +#line 283 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp222_ = job_table; +#line 283 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp223_ = self->priv->job_id_label; +#line 283 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp222_, (GtkWidget*) _tmp223_, (guint) 1, (guint) 2, (guint) 0, (guint) 1, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 284 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp224_ = job_table; +#line 284 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp225_ = left_label_new ("State:"); +#line 284 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp226_ = g_object_ref_sink (_tmp225_); +#line 284 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp224_, (GtkWidget*) _tmp226_, (guint) 0, (guint) 1, (guint) 1, (guint) 2, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 284 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp226_); +#line 285 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp227_ = job_table; +#line 285 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp228_ = self->priv->job_state_label; +#line 285 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp227_, (GtkWidget*) _tmp228_, (guint) 1, (guint) 2, (guint) 1, (guint) 2, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 286 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp229_ = job_table; +#line 286 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp230_ = left_label_new ("Type:"); +#line 286 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp231_ = g_object_ref_sink (_tmp230_); +#line 286 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp229_, (GtkWidget*) _tmp231_, (guint) 0, (guint) 1, (guint) 2, (guint) 3, GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 286 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_tmp231_); +#line 287 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp232_ = job_table; +#line 287 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp233_ = self->priv->job_type_label; +#line 287 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_table_attach (_tmp232_, (GtkWidget*) _tmp233_, (guint) 1, (guint) 2, (guint) 2, (guint) 3, GTK_EXPAND | GTK_FILL, GTK_FILL, (guint) 0, (guint) 0); +#line 289 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp234_ = (GtkHButtonBox*) gtk_hbutton_box_new (); +#line 289 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp235_ = (GtkButtonBox*) g_object_ref_sink (_tmp234_); +#line 289 "/home/lennart/projects/systemd/src/systemadm.vala" + bbox = _tmp235_; +#line 290 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp236_ = bbox; +#line 290 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_button_box_set_layout (_tmp236_, GTK_BUTTONBOX_START); +#line 291 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp237_ = bbox; +#line 291 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_set_spacing ((GtkBox*) _tmp237_, 6); +#line 292 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp238_ = unit_vbox; +#line 292 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp239_ = bbox; +#line 292 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start (_tmp238_, (GtkWidget*) _tmp239_, FALSE, TRUE, (guint) 0); +#line 294 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp240_ = (GtkButton*) gtk_button_new_with_mnemonic ("_Start"); +#line 294 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp241_ = g_object_ref_sink (_tmp240_); +#line 294 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->start_button); +#line 294 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->start_button = _tmp241_; +#line 295 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp242_ = (GtkButton*) gtk_button_new_with_mnemonic ("Sto_p"); +#line 295 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp243_ = g_object_ref_sink (_tmp242_); +#line 295 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->stop_button); +#line 295 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->stop_button = _tmp243_; +#line 296 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp244_ = (GtkButton*) gtk_button_new_with_mnemonic ("_Reload"); +#line 296 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp245_ = g_object_ref_sink (_tmp244_); +#line 296 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->reload_button); +#line 296 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->reload_button = _tmp245_; +#line 297 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp246_ = (GtkButton*) gtk_button_new_with_mnemonic ("Res_tart"); +#line 297 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp247_ = g_object_ref_sink (_tmp246_); +#line 297 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->restart_button); +#line 297 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->restart_button = _tmp247_; +#line 299 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp248_ = self->priv->start_button; +#line 299 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp248_, "clicked", (GCallback) _main_window_on_start_gtk_button_clicked, self, 0); +#line 300 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp249_ = self->priv->stop_button; +#line 300 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp249_, "clicked", (GCallback) _main_window_on_stop_gtk_button_clicked, self, 0); +#line 301 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp250_ = self->priv->reload_button; +#line 301 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp250_, "clicked", (GCallback) _main_window_on_reload_gtk_button_clicked, self, 0); +#line 302 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp251_ = self->priv->restart_button; +#line 302 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp251_, "clicked", (GCallback) _main_window_on_restart_gtk_button_clicked, self, 0); +#line 304 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp252_ = bbox; +#line 304 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp253_ = self->priv->start_button; +#line 304 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start ((GtkBox*) _tmp252_, (GtkWidget*) _tmp253_, FALSE, TRUE, (guint) 0); +#line 305 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp254_ = bbox; +#line 305 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp255_ = self->priv->stop_button; +#line 305 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start ((GtkBox*) _tmp254_, (GtkWidget*) _tmp255_, FALSE, TRUE, (guint) 0); +#line 306 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp256_ = bbox; +#line 306 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp257_ = self->priv->restart_button; +#line 306 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start ((GtkBox*) _tmp256_, (GtkWidget*) _tmp257_, FALSE, TRUE, (guint) 0); +#line 307 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp258_ = bbox; +#line 307 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp259_ = self->priv->reload_button; +#line 307 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start ((GtkBox*) _tmp258_, (GtkWidget*) _tmp259_, FALSE, TRUE, (guint) 0); +#line 309 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp260_ = (GtkHButtonBox*) gtk_hbutton_box_new (); +#line 309 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp261_ = (GtkButtonBox*) g_object_ref_sink (_tmp260_); +#line 309 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (bbox); +#line 309 "/home/lennart/projects/systemd/src/systemadm.vala" + bbox = _tmp261_; +#line 310 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp262_ = bbox; +#line 310 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_button_box_set_layout (_tmp262_, GTK_BUTTONBOX_START); +#line 311 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp263_ = bbox; +#line 311 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_set_spacing ((GtkBox*) _tmp263_, 6); +#line 312 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp264_ = job_vbox; +#line 312 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp265_ = bbox; +#line 312 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start (_tmp264_, (GtkWidget*) _tmp265_, FALSE, TRUE, (guint) 0); +#line 314 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp266_ = (GtkButton*) gtk_button_new_with_mnemonic ("_Cancel"); +#line 314 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp267_ = g_object_ref_sink (_tmp266_); +#line 314 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->cancel_button); +#line 314 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->cancel_button = _tmp267_; +#line 316 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp268_ = self->priv->cancel_button; +#line 316 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp268_, "clicked", (GCallback) _main_window_on_cancel_gtk_button_clicked, self, 0); +#line 318 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp269_ = bbox; +#line 318 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp270_ = self->priv->cancel_button; +#line 318 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_box_pack_start ((GtkBox*) _tmp269_, (GtkWidget*) _tmp270_, FALSE, TRUE, (guint) 0); +#line 321 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp272_ = user; +#line 321 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp272_) { +#line 321 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp271_ = G_BUS_TYPE_SESSION; +#line 2251 "systemadm.c" + } else { +#line 321 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp271_ = G_BUS_TYPE_SYSTEM; +#line 2255 "systemadm.c" + } +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp273_ = _tmp271_; +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp274_ = g_initable_new (TYPE_MANAGER_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.freedesktop.systemd1", "g-bus-type", _tmp273_, "g-object-path", "/org/freedesktop/systemd1", "g-interface-name", "org.freedesktop.systemd1.Manager", NULL); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp275_ = (Manager*) _tmp274_; +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_->domain == G_IO_ERROR) { +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + g_propagate_error (error, _inner_error_); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (bbox); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_table); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_table); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (scroll); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_sort); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_filter); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_load_hbox); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (type_hbox); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_vbox); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_vbox); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (notebook); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + return NULL; +#line 2295 "systemadm.c" + } else { +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (bbox); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_table); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_table); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (scroll); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_sort); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_filter); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_load_hbox); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (type_hbox); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_vbox); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_vbox); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (notebook); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + return NULL; +#line 2325 "systemadm.c" + } + } +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->manager); +#line 320 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->manager = _tmp275_; +#line 325 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp276_ = self->priv->manager; +#line 325 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp276_, "unit-new", (GCallback) _main_window_on_unit_new_manager_unit_new, self, 0); +#line 326 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp277_ = self->priv->manager; +#line 326 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp277_, "job-new", (GCallback) _main_window_on_job_new_manager_job_new, self, 0); +#line 327 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp278_ = self->priv->manager; +#line 327 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp278_, "unit-removed", (GCallback) _main_window_on_unit_removed_manager_unit_removed, self, 0); +#line 328 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp279_ = self->priv->manager; +#line 328 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp279_, "job-removed", (GCallback) _main_window_on_job_removed_manager_job_removed, self, 0); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp280_ = self->priv->manager; +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_subscribe (_tmp280_, &_inner_error_); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_->domain == G_IO_ERROR) { +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + g_propagate_error (error, _inner_error_); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (bbox); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_table); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_table); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (scroll); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_sort); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_filter); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_load_hbox); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (type_hbox); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_vbox); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_vbox); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (notebook); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + return NULL; +#line 2384 "systemadm.c" + } else { +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (bbox); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_table); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_table); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (scroll); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_sort); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_filter); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_load_hbox); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (type_hbox); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_vbox); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_vbox); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (notebook); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 330 "/home/lennart/projects/systemd/src/systemadm.vala" + return NULL; +#line 2414 "systemadm.c" + } + } +#line 332 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_clear_unit (self); +#line 333 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_clear_job (self); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_populate_unit_model (self, &_inner_error_); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_->domain == G_IO_ERROR) { +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + g_propagate_error (error, _inner_error_); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (bbox); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_table); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_table); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (scroll); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_sort); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_filter); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_load_hbox); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (type_hbox); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_vbox); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_vbox); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (notebook); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + return NULL; +#line 2455 "systemadm.c" + } else { +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (bbox); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_table); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_table); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (scroll); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_sort); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_filter); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_load_hbox); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (type_hbox); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_vbox); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_vbox); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (notebook); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 334 "/home/lennart/projects/systemd/src/systemadm.vala" + return NULL; +#line 2485 "systemadm.c" + } + } +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_populate_job_model (self, &_inner_error_); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_->domain == G_IO_ERROR) { +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + g_propagate_error (error, _inner_error_); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (bbox); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_table); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_table); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (scroll); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_sort); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_filter); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_load_hbox); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (type_hbox); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_vbox); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_vbox); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (notebook); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + return NULL; +#line 2522 "systemadm.c" + } else { +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (bbox); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_table); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_table); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (scroll); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_sort); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_filter); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_load_hbox); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (type_hbox); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_vbox); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_vbox); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (notebook); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 335 "/home/lennart/projects/systemd/src/systemadm.vala" + return NULL; +#line 2552 "systemadm.c" + } + } +#line 118 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (bbox); +#line 118 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_table); +#line 118 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_table); +#line 118 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (scroll); +#line 118 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_sort); +#line 118 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_model_filter); +#line 118 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_load_hbox); +#line 118 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (type_hbox); +#line 118 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (job_vbox); +#line 118 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (unit_vbox); +#line 118 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (notebook); +#line 118 "/home/lennart/projects/systemd/src/systemadm.vala" + return self; +#line 2579 "systemadm.c" +} + + +MainWindow* main_window_new (GError** error) { +#line 118 "/home/lennart/projects/systemd/src/systemadm.vala" + return main_window_construct (TYPE_MAIN_WINDOW, error); +#line 2586 "systemadm.c" +} + + +static void _vala_ManagerUnitInfo_array_free (ManagerUnitInfo* array, gint array_length) { +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + if (array != NULL) { +#line 2593 "systemadm.c" + int i; +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + for (i = 0; i < array_length; i = i + 1) { +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_unit_info_destroy (&array[i]); +#line 2599 "systemadm.c" + } + } +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + g_free (array); +#line 2604 "systemadm.c" +} + + +static void _main_window_on_unit_changed_properties_properties_changed (Properties* _sender, const gchar* iface, GHashTable* changed_properties, gchar** invalidated_properties, int invalidated_properties_length1, gpointer self) { +#line 351 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_unit_changed (self, _sender, iface, changed_properties, invalidated_properties, invalidated_properties_length1); +#line 2611 "systemadm.c" +} + + +void main_window_populate_unit_model (MainWindow* self, GError** error) { + GtkListStore* _tmp0_; + Manager* _tmp1_; + gint _tmp2_ = 0; + ManagerUnitInfo* _tmp3_ = NULL; + ManagerUnitInfo* list; + gint list_length1; + gint _list_size_; + ManagerUnitInfo* _tmp4_; + gint _tmp4__length1; + GError * _inner_error_ = NULL; +#line 338 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 339 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->unit_model; +#line 339 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_list_store_clear (_tmp0_); +#line 341 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = self->priv->manager; +#line 341 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = manager_list_units (_tmp1_, &_tmp2_, &_inner_error_); +#line 341 "/home/lennart/projects/systemd/src/systemadm.vala" + list = _tmp3_; +#line 341 "/home/lennart/projects/systemd/src/systemadm.vala" + list_length1 = _tmp2_; +#line 341 "/home/lennart/projects/systemd/src/systemadm.vala" + _list_size_ = list_length1; +#line 341 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 341 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_->domain == G_IO_ERROR) { +#line 341 "/home/lennart/projects/systemd/src/systemadm.vala" + g_propagate_error (error, _inner_error_); +#line 341 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 2650 "systemadm.c" + } else { +#line 341 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 341 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 341 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 2658 "systemadm.c" + } + } +#line 343 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = list; +#line 343 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4__length1 = list_length1; +#line 2665 "systemadm.c" + { + ManagerUnitInfo* i_collection = NULL; + gint i_collection_length1 = 0; + gint _i_collection_size_ = 0; + gint i_it = 0; +#line 343 "/home/lennart/projects/systemd/src/systemadm.vala" + i_collection = _tmp4_; +#line 343 "/home/lennart/projects/systemd/src/systemadm.vala" + i_collection_length1 = _tmp4__length1; +#line 343 "/home/lennart/projects/systemd/src/systemadm.vala" + for (i_it = 0; i_it < _tmp4__length1; i_it = i_it + 1) { +#line 2677 "systemadm.c" + ManagerUnitInfo _tmp5_ = {0}; + ManagerUnitInfo i = {0}; +#line 343 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_unit_info_copy (&i_collection[i_it], &_tmp5_); +#line 343 "/home/lennart/projects/systemd/src/systemadm.vala" + i = _tmp5_; +#line 2684 "systemadm.c" + { + GtkTreeIter iter = {0}; + GBusType _tmp6_ = 0; + gboolean _tmp7_; + GBusType _tmp8_; + ManagerUnitInfo _tmp9_; + const char* _tmp10_; + Properties* _tmp11_ = NULL; + Properties* p; + Properties* _tmp12_; + GBusType _tmp13_ = 0; + gboolean _tmp14_; + GBusType _tmp15_; + ManagerUnitInfo _tmp16_; + const char* _tmp17_; + Unit* _tmp18_ = NULL; + Unit* u; + GeeHashMap* _tmp19_; + ManagerUnitInfo _tmp20_; + const gchar* _tmp21_; + Unit* _tmp22_; + GtkListStore* _tmp23_; + GtkTreeIter _tmp24_ = {0}; + gchar* _tmp25_ = NULL; + ManagerUnitInfo _tmp26_; + const gchar* _tmp27_; + GtkListStore* _tmp32_; + GtkTreeIter _tmp33_; + ManagerUnitInfo _tmp34_; + const gchar* _tmp35_; + ManagerUnitInfo _tmp36_; + const gchar* _tmp37_; + ManagerUnitInfo _tmp38_; + const gchar* _tmp39_; + ManagerUnitInfo _tmp40_; + const gchar* _tmp41_; + ManagerUnitInfo _tmp42_; + const gchar* _tmp43_; + const gchar* _tmp44_; + Unit* _tmp45_; +#line 347 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = user; +#line 347 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp7_) { +#line 347 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = G_BUS_TYPE_SESSION; +#line 2731 "systemadm.c" + } else { +#line 347 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = G_BUS_TYPE_SYSTEM; +#line 2735 "systemadm.c" + } +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = _tmp6_; +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = i; +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = _tmp9_.unit_path; +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = g_initable_new (TYPE_PROPERTIES_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.freedesktop.systemd1", "g-bus-type", _tmp8_, "g-object-path", (const gchar*) _tmp10_, "g-interface-name", "org.freedesktop.Properties", NULL); +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + p = (Properties*) _tmp11_; +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_->domain == G_IO_ERROR) { +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + g_propagate_error (error, _inner_error_); +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_unit_info_destroy (&i); +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + list = (_vala_ManagerUnitInfo_array_free (list, list_length1), NULL); +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 2759 "systemadm.c" + } else { +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_unit_info_destroy (&i); +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + list = (_vala_ManagerUnitInfo_array_free (list, list_length1), NULL); +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 346 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 2771 "systemadm.c" + } + } +#line 351 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = p; +#line 351 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp12_, "properties-changed", (GCallback) _main_window_on_unit_changed_properties_properties_changed, self, 0); +#line 354 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = user; +#line 354 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp14_) { +#line 354 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = G_BUS_TYPE_SESSION; +#line 2784 "systemadm.c" + } else { +#line 354 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = G_BUS_TYPE_SYSTEM; +#line 2788 "systemadm.c" + } +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = _tmp13_; +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = i; +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = _tmp16_.unit_path; +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp18_ = g_initable_new (TYPE_UNIT_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.freedesktop.systemd1", "g-bus-type", _tmp15_, "g-object-path", (const gchar*) _tmp17_, "g-interface-name", "org.freedesktop.systemd1.Unit", NULL); +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + u = (Unit*) _tmp18_; +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_->domain == G_IO_ERROR) { +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + g_propagate_error (error, _inner_error_); +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (p); +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_unit_info_destroy (&i); +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + list = (_vala_ManagerUnitInfo_array_free (list, list_length1), NULL); +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 2814 "systemadm.c" + } else { +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (p); +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_unit_info_destroy (&i); +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + list = (_vala_ManagerUnitInfo_array_free (list, list_length1), NULL); +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 353 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 2828 "systemadm.c" + } + } +#line 358 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp19_ = self->priv->unit_map; +#line 358 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp20_ = i; +#line 358 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp21_ = _tmp20_.id; +#line 358 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp22_ = u; +#line 358 "/home/lennart/projects/systemd/src/systemadm.vala" + gee_abstract_map_set ((GeeAbstractMap*) _tmp19_, _tmp21_, _tmp22_); +#line 360 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp23_ = self->priv->unit_model; +#line 360 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_list_store_append (_tmp23_, &_tmp24_); +#line 360 "/home/lennart/projects/systemd/src/systemadm.vala" + iter = _tmp24_; +#line 367 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp26_ = i; +#line 367 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp27_ = _tmp26_.job_type; +#line 367 "/home/lennart/projects/systemd/src/systemadm.vala" + if (g_strcmp0 (_tmp27_, "") != 0) { +#line 2853 "systemadm.c" + ManagerUnitInfo _tmp28_; + const gchar* _tmp29_; + gchar* _tmp30_ = NULL; +#line 367 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp28_ = i; +#line 367 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp29_ = _tmp28_.job_type; +#line 367 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp30_ = g_strdup_printf ("→ %s", _tmp29_); +#line 367 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp25_); +#line 367 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp25_ = _tmp30_; +#line 2867 "systemadm.c" + } else { + gchar* _tmp31_; +#line 367 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp31_ = g_strdup (""); +#line 367 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp25_); +#line 367 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp25_ = _tmp31_; +#line 2876 "systemadm.c" + } +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp32_ = self->priv->unit_model; +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp33_ = iter; +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp34_ = i; +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp35_ = _tmp34_.id; +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp36_ = i; +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp37_ = _tmp36_.description; +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp38_ = i; +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp39_ = _tmp38_.load_state; +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp40_ = i; +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp41_ = _tmp40_.active_state; +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp42_ = i; +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp43_ = _tmp42_.sub_state; +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp44_ = _tmp25_; +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp45_ = u; +#line 361 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_list_store_set (_tmp32_, &_tmp33_, 0, _tmp35_, 1, _tmp37_, 2, _tmp39_, 3, _tmp41_, 4, _tmp43_, 5, _tmp44_, 6, _tmp45_, -1); +#line 343 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp25_); +#line 343 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 343 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (p); +#line 343 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_unit_info_destroy (&i); +#line 2916 "systemadm.c" + } + } + } +#line 338 "/home/lennart/projects/systemd/src/systemadm.vala" + list = (_vala_ManagerUnitInfo_array_free (list, list_length1), NULL); +#line 2922 "systemadm.c" +} + + +static void _vala_ManagerJobInfo_array_free (ManagerJobInfo* array, gint array_length) { +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + if (array != NULL) { +#line 2929 "systemadm.c" + int i; +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + for (i = 0; i < array_length; i = i + 1) { +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_job_info_destroy (&array[i]); +#line 2935 "systemadm.c" + } + } +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + g_free (array); +#line 2940 "systemadm.c" +} + + +static void _main_window_on_job_changed_properties_properties_changed (Properties* _sender, const gchar* iface, GHashTable* changed_properties, gchar** invalidated_properties, int invalidated_properties_length1, gpointer self) { +#line 385 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_on_job_changed (self, _sender, iface, changed_properties, invalidated_properties, invalidated_properties_length1); +#line 2947 "systemadm.c" +} + + +void main_window_populate_job_model (MainWindow* self, GError** error) { + GtkListStore* _tmp0_; + Manager* _tmp1_; + gint _tmp2_ = 0; + ManagerJobInfo* _tmp3_ = NULL; + ManagerJobInfo* list; + gint list_length1; + gint _list_size_; + ManagerJobInfo* _tmp4_; + gint _tmp4__length1; + GError * _inner_error_ = NULL; +#line 372 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 373 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->job_model; +#line 373 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_list_store_clear (_tmp0_); +#line 375 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = self->priv->manager; +#line 375 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = manager_list_jobs (_tmp1_, &_tmp2_, &_inner_error_); +#line 375 "/home/lennart/projects/systemd/src/systemadm.vala" + list = _tmp3_; +#line 375 "/home/lennart/projects/systemd/src/systemadm.vala" + list_length1 = _tmp2_; +#line 375 "/home/lennart/projects/systemd/src/systemadm.vala" + _list_size_ = list_length1; +#line 375 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 375 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_->domain == G_IO_ERROR) { +#line 375 "/home/lennart/projects/systemd/src/systemadm.vala" + g_propagate_error (error, _inner_error_); +#line 375 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 2986 "systemadm.c" + } else { +#line 375 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 375 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 375 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 2994 "systemadm.c" + } + } +#line 377 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = list; +#line 377 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4__length1 = list_length1; +#line 3001 "systemadm.c" + { + ManagerJobInfo* i_collection = NULL; + gint i_collection_length1 = 0; + gint _i_collection_size_ = 0; + gint i_it = 0; +#line 377 "/home/lennart/projects/systemd/src/systemadm.vala" + i_collection = _tmp4_; +#line 377 "/home/lennart/projects/systemd/src/systemadm.vala" + i_collection_length1 = _tmp4__length1; +#line 377 "/home/lennart/projects/systemd/src/systemadm.vala" + for (i_it = 0; i_it < _tmp4__length1; i_it = i_it + 1) { +#line 3013 "systemadm.c" + ManagerJobInfo _tmp5_ = {0}; + ManagerJobInfo i = {0}; +#line 377 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_job_info_copy (&i_collection[i_it], &_tmp5_); +#line 377 "/home/lennart/projects/systemd/src/systemadm.vala" + i = _tmp5_; +#line 3020 "systemadm.c" + { + GtkTreeIter iter = {0}; + GBusType _tmp6_ = 0; + gboolean _tmp7_; + GBusType _tmp8_; + ManagerJobInfo _tmp9_; + const char* _tmp10_; + Properties* _tmp11_ = NULL; + Properties* p; + Properties* _tmp12_; + GBusType _tmp13_ = 0; + gboolean _tmp14_; + GBusType _tmp15_; + ManagerJobInfo _tmp16_; + const char* _tmp17_; + Job* _tmp18_ = NULL; + Job* j; + GtkListStore* _tmp19_; + GtkTreeIter _tmp20_ = {0}; + GtkListStore* _tmp21_; + GtkTreeIter _tmp22_; + ManagerJobInfo _tmp23_; + guint32 _tmp24_; + gchar* _tmp25_ = NULL; + gchar* _tmp26_; + ManagerJobInfo _tmp27_; + const gchar* _tmp28_; + ManagerJobInfo _tmp29_; + const gchar* _tmp30_; + gchar* _tmp31_ = NULL; + gchar* _tmp32_; + ManagerJobInfo _tmp33_; + const gchar* _tmp34_; + Job* _tmp35_; + ManagerJobInfo _tmp36_; + guint32 _tmp37_; +#line 381 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = user; +#line 381 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp7_) { +#line 381 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = G_BUS_TYPE_SESSION; +#line 3063 "systemadm.c" + } else { +#line 381 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = G_BUS_TYPE_SYSTEM; +#line 3067 "systemadm.c" + } +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = _tmp6_; +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = i; +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = _tmp9_.job_path; +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = g_initable_new (TYPE_PROPERTIES_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.freedesktop.systemd1", "g-bus-type", _tmp8_, "g-object-path", (const gchar*) _tmp10_, "g-interface-name", "org.freedesktop.Properties", NULL); +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + p = (Properties*) _tmp11_; +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_->domain == G_IO_ERROR) { +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + g_propagate_error (error, _inner_error_); +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_job_info_destroy (&i); +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + list = (_vala_ManagerJobInfo_array_free (list, list_length1), NULL); +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 3091 "systemadm.c" + } else { +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_job_info_destroy (&i); +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + list = (_vala_ManagerJobInfo_array_free (list, list_length1), NULL); +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 380 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 3103 "systemadm.c" + } + } +#line 385 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = p; +#line 385 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp12_, "properties-changed", (GCallback) _main_window_on_job_changed_properties_properties_changed, self, 0); +#line 388 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = user; +#line 388 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp14_) { +#line 388 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = G_BUS_TYPE_SESSION; +#line 3116 "systemadm.c" + } else { +#line 388 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = G_BUS_TYPE_SYSTEM; +#line 3120 "systemadm.c" + } +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = _tmp13_; +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = i; +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = _tmp16_.job_path; +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp18_ = g_initable_new (TYPE_JOB_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.freedesktop.systemd1", "g-bus-type", _tmp15_, "g-object-path", (const gchar*) _tmp17_, "g-interface-name", "org.freedesktop.systemd1.Job", NULL); +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + j = (Job*) _tmp18_; +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_->domain == G_IO_ERROR) { +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + g_propagate_error (error, _inner_error_); +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (p); +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_job_info_destroy (&i); +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + list = (_vala_ManagerJobInfo_array_free (list, list_length1), NULL); +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 3146 "systemadm.c" + } else { +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (p); +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_job_info_destroy (&i); +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + list = (_vala_ManagerJobInfo_array_free (list, list_length1), NULL); +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 387 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 3160 "systemadm.c" + } + } +#line 392 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp19_ = self->priv->job_model; +#line 392 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_list_store_append (_tmp19_, &_tmp20_); +#line 392 "/home/lennart/projects/systemd/src/systemadm.vala" + iter = _tmp20_; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp21_ = self->priv->job_model; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp22_ = iter; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp23_ = i; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp24_ = _tmp23_.id; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp25_ = g_strdup_printf ("%u", (guint) _tmp24_); +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp26_ = _tmp25_; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp27_ = i; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp28_ = _tmp27_.name; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp29_ = i; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp30_ = _tmp29_.type; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp31_ = g_strdup_printf ("→ %s", _tmp30_); +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp32_ = _tmp31_; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp33_ = i; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp34_ = _tmp33_.state; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp35_ = j; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp36_ = i; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp37_ = _tmp36_.id; +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_list_store_set (_tmp21_, &_tmp22_, 0, _tmp26_, 1, _tmp28_, 2, _tmp32_, 3, _tmp34_, 4, _tmp35_, 5, _tmp37_, -1); +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp32_); +#line 393 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp26_); +#line 377 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (j); +#line 377 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (p); +#line 377 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_job_info_destroy (&i); +#line 3215 "systemadm.c" + } + } + } +#line 372 "/home/lennart/projects/systemd/src/systemadm.vala" + list = (_vala_ManagerJobInfo_array_free (list, list_length1), NULL); +#line 3221 "systemadm.c" +} + + +static gpointer _g_object_ref0 (gpointer self) { +#line 410 "/home/lennart/projects/systemd/src/systemadm.vala" + return self ? g_object_ref (self) : NULL; +#line 3228 "systemadm.c" +} + + +Unit* main_window_get_current_unit (MainWindow* self) { + Unit* result = NULL; + GtkTreePath* p = NULL; + GtkTreeView* _tmp0_; + GtkTreePath* _tmp1_ = NULL; + GtkTreePath* _tmp2_; + GtkTreeView* _tmp3_; + GtkTreeModel* _tmp4_ = NULL; + GtkTreeModel* _tmp5_; + GtkTreeModel* model; + GtkTreeIter iter = {0}; + Unit* u = NULL; + GtkTreeModel* _tmp6_; + GtkTreePath* _tmp7_; + GtkTreeIter _tmp8_ = {0}; + GtkTreeModel* _tmp9_; + GtkTreeIter _tmp10_; +#line 403 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 405 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->unit_view; +#line 405 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_view_get_cursor (_tmp0_, &_tmp1_, NULL); +#line 405 "/home/lennart/projects/systemd/src/systemadm.vala" + _gtk_tree_path_free0 (p); +#line 405 "/home/lennart/projects/systemd/src/systemadm.vala" + p = _tmp1_; +#line 407 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = p; +#line 407 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp2_ == NULL) { +#line 408 "/home/lennart/projects/systemd/src/systemadm.vala" + result = NULL; +#line 408 "/home/lennart/projects/systemd/src/systemadm.vala" + _gtk_tree_path_free0 (p); +#line 408 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 3269 "systemadm.c" + } +#line 410 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = self->priv->unit_view; +#line 410 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = gtk_tree_view_get_model (_tmp3_); +#line 410 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = _g_object_ref0 (_tmp4_); +#line 410 "/home/lennart/projects/systemd/src/systemadm.vala" + model = _tmp5_; +#line 414 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = model; +#line 414 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = p; +#line 414 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_model_get_iter (_tmp6_, &_tmp8_, _tmp7_); +#line 414 "/home/lennart/projects/systemd/src/systemadm.vala" + iter = _tmp8_; +#line 415 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = model; +#line 415 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = iter; +#line 415 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_model_get (_tmp9_, &_tmp10_, 6, &u, -1); +#line 417 "/home/lennart/projects/systemd/src/systemadm.vala" + result = u; +#line 417 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (model); +#line 417 "/home/lennart/projects/systemd/src/systemadm.vala" + _gtk_tree_path_free0 (p); +#line 417 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 3301 "systemadm.c" +} + + +Unit* main_window_get_unit (MainWindow* self, const gchar* id) { + Unit* result = NULL; + GeeHashMap* _tmp0_; + const gchar* _tmp1_; + gpointer _tmp2_ = NULL; +#line 420 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 420 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_val_if_fail (id != NULL, NULL); +#line 421 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->unit_map; +#line 421 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = id; +#line 421 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp0_, _tmp1_); +#line 421 "/home/lennart/projects/systemd/src/systemadm.vala" + result = (Unit*) _tmp2_; +#line 421 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 3324 "systemadm.c" +} + + +void main_window_unit_changed (MainWindow* self) { + Unit* _tmp0_ = NULL; + Unit* u; + Unit* _tmp1_; +#line 424 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 425 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = main_window_get_current_unit (self); +#line 425 "/home/lennart/projects/systemd/src/systemadm.vala" + u = _tmp0_; +#line 427 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = u; +#line 427 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp1_ == NULL) { +#line 428 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_clear_unit (self); +#line 3344 "systemadm.c" + } else { + Unit* _tmp2_; +#line 430 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = u; +#line 430 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_unit (self, _tmp2_); +#line 3351 "systemadm.c" + } +#line 424 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 3355 "systemadm.c" +} + + +void main_window_clear_unit (MainWindow* self) { + GtkButton* _tmp0_; + GtkButton* _tmp1_; + GtkButton* _tmp2_; + GtkButton* _tmp3_; + RightLabel* _tmp4_; + RightLabel* _tmp5_; + RightLabel* _tmp6_; + RightLabel* _tmp7_; + RightLabel* _tmp8_; + RightLabel* _tmp9_; + RightLabel* _tmp10_; + RightLabel* _tmp11_; + RightLabel* _tmp12_; + RightLabel* _tmp13_; + RightLabel* _tmp14_; + RightLabel* _tmp15_; +#line 433 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 434 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (self->priv->current_unit_id); +#line 434 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->current_unit_id = NULL; +#line 436 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->start_button; +#line 436 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_widget_set_sensitive ((GtkWidget*) _tmp0_, FALSE); +#line 437 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = self->priv->stop_button; +#line 437 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_widget_set_sensitive ((GtkWidget*) _tmp1_, FALSE); +#line 438 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = self->priv->reload_button; +#line 438 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_widget_set_sensitive ((GtkWidget*) _tmp2_, FALSE); +#line 439 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = self->priv->restart_button; +#line 439 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_widget_set_sensitive ((GtkWidget*) _tmp3_, FALSE); +#line 441 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = self->priv->unit_id_label; +#line 441 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp4_, NULL); +#line 442 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = self->priv->unit_description_label; +#line 442 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp5_, NULL); +#line 443 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = self->priv->unit_description_label; +#line 443 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp6_, NULL); +#line 444 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = self->priv->unit_load_state_label; +#line 444 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp7_, NULL); +#line 445 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = self->priv->unit_active_state_label; +#line 445 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp8_, NULL); +#line 446 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = self->priv->unit_sub_state_label; +#line 446 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp9_, NULL); +#line 447 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = self->priv->unit_fragment_path_label; +#line 447 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp10_, NULL); +#line 448 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = self->priv->unit_active_enter_timestamp_label; +#line 448 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp11_, NULL); +#line 449 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = self->priv->unit_active_exit_timestamp_label; +#line 449 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp12_, NULL); +#line 450 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = self->priv->unit_can_reload_label; +#line 450 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp13_, NULL); +#line 451 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = self->priv->unit_can_start_label; +#line 451 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp14_, NULL); +#line 452 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = self->priv->unit_cgroup_label; +#line 452 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp15_, NULL); +#line 3446 "systemadm.c" +} + + +gchar* main_window_format_unit_link (MainWindow* self, const gchar* i, gboolean link) { + gchar* result = NULL; + const gchar* _tmp0_; + Unit* _tmp1_ = NULL; + Unit* u; + Unit* _tmp2_; + gchar* color = NULL; + Unit* _tmp8_; + gchar* _tmp9_; + gchar* _tmp10_; + gchar* _tmp11_; + GQuark _tmp13_ = 0U; +#line 461 "/home/lennart/projects/systemd/src/systemadm.vala" + static GQuark _tmp12_label0 = 0; +#line 461 "/home/lennart/projects/systemd/src/systemadm.vala" + static GQuark _tmp12_label1 = 0; +#line 461 "/home/lennart/projects/systemd/src/systemadm.vala" + static GQuark _tmp12_label2 = 0; +#line 3468 "systemadm.c" + const gchar* _tmp18_; + gchar* _tmp19_; + gchar* _tmp20_; + gchar* _tmp21_; + gchar* _tmp22_; + const gchar* _tmp23_; + gchar* _tmp24_; + gchar* _tmp25_; + gchar* _tmp26_; + gchar* _tmp27_; + Unit* _tmp28_; + gchar* _tmp29_; + gchar* _tmp30_; + gchar* _tmp31_; + gchar* _tmp32_; + gchar* _tmp33_; + gchar* _tmp34_; + gchar* _tmp35_; + gchar* _tmp36_; + gchar* _tmp37_; + gchar* span; + gboolean _tmp38_; +#line 455 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 455 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_val_if_fail (i != NULL, NULL); +#line 456 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = i; +#line 456 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = main_window_get_unit (self, _tmp0_); +#line 456 "/home/lennart/projects/systemd/src/systemadm.vala" + u = _tmp1_; +#line 457 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = u; +#line 457 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp2_ == NULL) { +#line 3505 "systemadm.c" + const gchar* _tmp3_; + gchar* _tmp4_; + gchar* _tmp5_; + gchar* _tmp6_; + gchar* _tmp7_; +#line 458 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = i; +#line 458 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = g_strconcat ("", _tmp3_, NULL); +#line 458 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = _tmp4_; +#line 458 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = g_strconcat (_tmp5_, "", NULL); +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp22_ = _tmp21_; +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp23_ = i; +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp24_ = g_strconcat (_tmp22_, _tmp23_, NULL); +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp25_ = _tmp24_; +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp26_ = g_strconcat (_tmp25_, "(", NULL); +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp27_ = _tmp26_; +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp28_ = u; +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp29_ = unit_get_sub_state (_tmp28_); +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp30_ = _tmp29_; +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp31_ = _tmp30_; +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp32_ = g_strconcat (_tmp27_, _tmp31_, NULL); +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp33_ = _tmp32_; +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp34_ = g_strconcat (_tmp33_, ")", NULL); +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp35_ = _tmp34_; +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp36_ = g_strconcat (_tmp35_, "", NULL); +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp37_ = _tmp36_; +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp35_); +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp33_); +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp31_); +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp27_); +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp25_); +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp22_); +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp20_); +#line 467 "/home/lennart/projects/systemd/src/systemadm.vala" + span = _tmp37_; +#line 470 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp38_ = link; +#line 470 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp38_) { +#line 3677 "systemadm.c" + const gchar* _tmp39_; + gchar* _tmp40_; + gchar* _tmp41_; + gchar* _tmp42_; + gchar* _tmp43_; + const gchar* _tmp44_; + gchar* _tmp45_; + gchar* _tmp46_; + gchar* _tmp47_; + gchar* _tmp48_; +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp39_ = i; +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp40_ = g_strconcat (" ", NULL); +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp43_ = _tmp42_; +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp44_ = span; +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp45_ = g_strconcat (_tmp43_, _tmp44_, NULL); +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp46_ = _tmp45_; +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp47_ = g_strconcat (_tmp46_, "", NULL); +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp48_ = _tmp47_; +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp46_); +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp43_); +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp41_); +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + result = _tmp48_; +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (span); +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (color); +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 471 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 3724 "systemadm.c" + } else { +#line 473 "/home/lennart/projects/systemd/src/systemadm.vala" + result = span; +#line 473 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (color); +#line 473 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 473 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 3734 "systemadm.c" + } +#line 455 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (span); +#line 455 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (color); +#line 455 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 3742 "systemadm.c" +} + + +gchar* main_window_make_dependency_string (MainWindow* self, const gchar* prefix, const gchar* word, gchar** dependencies, int dependencies_length1) { + gchar* result = NULL; + GeeTreeSet* _tmp0_; + GeeCollection* sorted; + gchar** _tmp1_; + gint _tmp1__length1; + gboolean first; + gchar* r = NULL; + const gchar* _tmp5_; +#line 477 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 477 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_val_if_fail (word != NULL, NULL); +#line 478 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = gee_tree_set_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL); +#line 478 "/home/lennart/projects/systemd/src/systemadm.vala" + sorted = (GeeCollection*) _tmp0_; +#line 479 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = dependencies; +#line 479 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1__length1 = dependencies_length1; +#line 3767 "systemadm.c" + { + gchar** i_collection = NULL; + gint i_collection_length1 = 0; + gint _i_collection_size_ = 0; + gint i_it = 0; +#line 479 "/home/lennart/projects/systemd/src/systemadm.vala" + i_collection = _tmp1_; +#line 479 "/home/lennart/projects/systemd/src/systemadm.vala" + i_collection_length1 = _tmp1__length1; +#line 479 "/home/lennart/projects/systemd/src/systemadm.vala" + for (i_it = 0; i_it < _tmp1__length1; i_it = i_it + 1) { +#line 3779 "systemadm.c" + gchar* _tmp2_; + gchar* i = NULL; +#line 479 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = g_strdup (i_collection[i_it]); +#line 479 "/home/lennart/projects/systemd/src/systemadm.vala" + i = _tmp2_; +#line 3786 "systemadm.c" + { + GeeCollection* _tmp3_; + const gchar* _tmp4_; +#line 480 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = sorted; +#line 480 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = i; +#line 480 "/home/lennart/projects/systemd/src/systemadm.vala" + gee_collection_add (_tmp3_, _tmp4_); +#line 479 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (i); +#line 3798 "systemadm.c" + } + } + } +#line 482 "/home/lennart/projects/systemd/src/systemadm.vala" + first = TRUE; +#line 485 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = prefix; +#line 485 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp5_ == NULL) { +#line 3808 "systemadm.c" + gchar* _tmp6_; +#line 486 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = g_strdup (""); +#line 486 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (r); +#line 486 "/home/lennart/projects/systemd/src/systemadm.vala" + r = _tmp6_; +#line 3816 "systemadm.c" + } else { + const gchar* _tmp7_; + gchar* _tmp8_; +#line 488 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = prefix; +#line 488 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = g_strdup (_tmp7_); +#line 488 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (r); +#line 488 "/home/lennart/projects/systemd/src/systemadm.vala" + r = _tmp8_; +#line 3828 "systemadm.c" + } + { + GeeCollection* _tmp9_; + GeeIterator* _tmp10_ = NULL; + GeeIterator* _i_it; +#line 490 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = sorted; +#line 490 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = gee_iterable_iterator ((GeeIterable*) _tmp9_); +#line 490 "/home/lennart/projects/systemd/src/systemadm.vala" + _i_it = _tmp10_; +#line 490 "/home/lennart/projects/systemd/src/systemadm.vala" + while (TRUE) { +#line 3842 "systemadm.c" + GeeIterator* _tmp11_; + gboolean _tmp12_ = FALSE; + GeeIterator* _tmp13_; + gpointer _tmp14_ = NULL; + gchar* _tmp15_; + gchar* i; + const gchar* _tmp16_; + gboolean _tmp22_; + const gchar* _tmp30_; + const gchar* _tmp31_; + gchar* _tmp32_ = NULL; + gchar* _tmp33_; + gchar* _tmp34_; +#line 490 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = _i_it; +#line 490 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = gee_iterator_next (_tmp11_); +#line 490 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp12_) { +#line 490 "/home/lennart/projects/systemd/src/systemadm.vala" + break; +#line 3864 "systemadm.c" + } +#line 490 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = _i_it; +#line 490 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = gee_iterator_get (_tmp13_); +#line 490 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = g_strdup ((const gchar*) _tmp14_); +#line 490 "/home/lennart/projects/systemd/src/systemadm.vala" + i = _tmp15_; +#line 491 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = r; +#line 491 "/home/lennart/projects/systemd/src/systemadm.vala" + if (g_strcmp0 (_tmp16_, "") != 0) { +#line 3878 "systemadm.c" + const gchar* _tmp17_ = NULL; + gboolean _tmp18_; + const gchar* _tmp19_; + const gchar* _tmp20_; + gchar* _tmp21_; +#line 492 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp18_ = first; +#line 492 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp18_) { +#line 492 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = "\n"; +#line 3890 "systemadm.c" + } else { +#line 492 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = ","; +#line 3894 "systemadm.c" + } +#line 492 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp19_ = r; +#line 492 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp20_ = _tmp17_; +#line 492 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp21_ = g_strconcat (_tmp19_, _tmp20_, NULL); +#line 492 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (r); +#line 492 "/home/lennart/projects/systemd/src/systemadm.vala" + r = _tmp21_; +#line 3906 "systemadm.c" + } +#line 494 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp22_ = first; +#line 494 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp22_) { +#line 3912 "systemadm.c" + const gchar* _tmp23_; + const gchar* _tmp24_; + gchar* _tmp25_; + gchar* _tmp26_; + gchar* _tmp27_; + gchar* _tmp28_; + gchar* _tmp29_; +#line 495 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp23_ = r; +#line 495 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp24_ = word; +#line 495 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp25_ = g_strconcat ("", _tmp24_, NULL); +#line 495 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp26_ = _tmp25_; +#line 495 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp27_ = g_strconcat (_tmp26_, ":", NULL); +#line 495 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp28_ = _tmp27_; +#line 495 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp29_ = g_strconcat (_tmp23_, _tmp28_, NULL); +#line 495 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (r); +#line 495 "/home/lennart/projects/systemd/src/systemadm.vala" + r = _tmp29_; +#line 495 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp28_); +#line 495 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp26_); +#line 496 "/home/lennart/projects/systemd/src/systemadm.vala" + first = FALSE; +#line 3944 "systemadm.c" + } +#line 499 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp30_ = r; +#line 499 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp31_ = i; +#line 499 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp32_ = main_window_format_unit_link (self, _tmp31_, TRUE); +#line 499 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp33_ = _tmp32_; +#line 499 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp34_ = g_strconcat (_tmp30_, _tmp33_, NULL); +#line 499 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (r); +#line 499 "/home/lennart/projects/systemd/src/systemadm.vala" + r = _tmp34_; +#line 499 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp33_); +#line 490 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (i); +#line 3964 "systemadm.c" + } +#line 490 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (_i_it); +#line 3968 "systemadm.c" + } +#line 502 "/home/lennart/projects/systemd/src/systemadm.vala" + result = r; +#line 502 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (sorted); +#line 502 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 3976 "systemadm.c" +} + + +void main_window_show_unit (MainWindow* self, Unit* unit) { + Unit* _tmp0_; + gchar* _tmp1_; + gchar* _tmp2_; + const gchar* _tmp3_; + gchar* _tmp4_ = NULL; + gchar* id_display; + gboolean has_alias; + Unit* _tmp5_; + gchar** _tmp6_; + gint _tmp6__length1; + gchar** _tmp7_; + gint _tmp7__length1; + gboolean _tmp19_; + RightLabel* _tmp22_; + const gchar* _tmp23_; + Unit* _tmp24_; + gchar** _tmp25_; + gint _tmp25__length1; + gchar** _tmp26_; + gint _tmp26__length1; + gchar** requires; + gint requires_length1; + gint _requires_size_; + Unit* _tmp27_; + gchar** _tmp28_; + gint _tmp28__length1; + gchar** _tmp29_; + gint _tmp29__length1; + gchar** requires_overridable; + gint requires_overridable_length1; + gint _requires_overridable_size_; + Unit* _tmp30_; + gchar** _tmp31_; + gint _tmp31__length1; + gchar** _tmp32_; + gint _tmp32__length1; + gchar** requisite; + gint requisite_length1; + gint _requisite_size_; + Unit* _tmp33_; + gchar** _tmp34_; + gint _tmp34__length1; + gchar** _tmp35_; + gint _tmp35__length1; + gchar** requisite_overridable; + gint requisite_overridable_length1; + gint _requisite_overridable_size_; + Unit* _tmp36_; + gchar** _tmp37_; + gint _tmp37__length1; + gchar** _tmp38_; + gint _tmp38__length1; + gchar** wants; + gint wants_length1; + gint _wants_size_; + Unit* _tmp39_; + gchar** _tmp40_; + gint _tmp40__length1; + gchar** _tmp41_; + gint _tmp41__length1; + gchar** required_by; + gint required_by_length1; + gint _required_by_size_; + Unit* _tmp42_; + gchar** _tmp43_; + gint _tmp43__length1; + gchar** _tmp44_; + gint _tmp44__length1; + gchar** required_by_overridable; + gint required_by_overridable_length1; + gint _required_by_overridable_size_; + Unit* _tmp45_; + gchar** _tmp46_; + gint _tmp46__length1; + gchar** _tmp47_; + gint _tmp47__length1; + gchar** wanted_by; + gint wanted_by_length1; + gint _wanted_by_size_; + Unit* _tmp48_; + gchar** _tmp49_; + gint _tmp49__length1; + gchar** _tmp50_; + gint _tmp50__length1; + gchar** conflicts; + gint conflicts_length1; + gint _conflicts_size_; + Unit* _tmp51_; + gchar** _tmp52_; + gint _tmp52__length1; + gchar** _tmp53_; + gint _tmp53__length1; + gchar** before; + gint before_length1; + gint _before_size_; + Unit* _tmp54_; + gchar** _tmp55_; + gint _tmp55__length1; + gchar** _tmp56_; + gint _tmp56__length1; + gchar** after; + gint after_length1; + gint _after_size_; + RightLabel* _tmp57_; + gchar** _tmp58_; + gint _tmp58__length1; + gchar* _tmp59_ = NULL; + gchar* _tmp60_; + gchar** _tmp61_; + gint _tmp61__length1; + gchar* _tmp62_ = NULL; + gchar* _tmp63_; + gchar** _tmp64_; + gint _tmp64__length1; + gchar* _tmp65_ = NULL; + gchar* _tmp66_; + gchar** _tmp67_; + gint _tmp67__length1; + gchar* _tmp68_ = NULL; + gchar* _tmp69_; + gchar** _tmp70_; + gint _tmp70__length1; + gchar* _tmp71_ = NULL; + gchar* _tmp72_; + gchar** _tmp73_; + gint _tmp73__length1; + gchar* _tmp74_ = NULL; + gchar* _tmp75_; + gchar** _tmp76_; + gint _tmp76__length1; + gchar* _tmp77_ = NULL; + gchar* _tmp78_; + gchar** _tmp79_; + gint _tmp79__length1; + gchar* _tmp80_ = NULL; + gchar* _tmp81_; + gchar** _tmp82_; + gint _tmp82__length1; + gchar* _tmp83_ = NULL; + gchar* _tmp84_; + gchar** _tmp85_; + gint _tmp85__length1; + gchar* _tmp86_ = NULL; + gchar* _tmp87_; + gchar** _tmp88_; + gint _tmp88__length1; + gchar* _tmp89_ = NULL; + gchar* _tmp90_; + RightLabel* _tmp91_; + Unit* _tmp92_; + gchar* _tmp93_; + gchar* _tmp94_; + gchar* _tmp95_; + RightLabel* _tmp96_; + Unit* _tmp97_; + gchar* _tmp98_; + gchar* _tmp99_; + gchar* _tmp100_; + RightLabel* _tmp101_; + Unit* _tmp102_; + gchar* _tmp103_; + gchar* _tmp104_; + gchar* _tmp105_; + RightLabel* _tmp106_; + Unit* _tmp107_; + gchar* _tmp108_; + gchar* _tmp109_; + gchar* _tmp110_; + Unit* _tmp111_; + gchar* _tmp112_; + gchar* _tmp113_; + gchar* fp; + const gchar* _tmp114_; + RightLabel* _tmp129_; + Unit* _tmp130_; + guint64 _tmp131_; + guint64 _tmp132_; + gchar* _tmp133_ = NULL; + gchar* _tmp134_; + RightLabel* _tmp135_; + Unit* _tmp136_; + guint64 _tmp137_; + guint64 _tmp138_; + gchar* _tmp139_ = NULL; + gchar* _tmp140_; + Unit* _tmp141_; + gboolean _tmp142_; + gboolean _tmp143_; + gboolean b; + GtkButton* _tmp144_; + gboolean _tmp145_; + GtkButton* _tmp146_; + gboolean _tmp147_; + GtkButton* _tmp148_; + gboolean _tmp149_; + const gchar* _tmp150_ = NULL; + gboolean _tmp151_; + RightLabel* _tmp152_; + const gchar* _tmp153_; + Unit* _tmp154_; + gboolean _tmp155_; + gboolean _tmp156_; + GtkButton* _tmp157_; + gboolean _tmp158_; + const gchar* _tmp159_ = NULL; + gboolean _tmp160_; + RightLabel* _tmp161_; + const gchar* _tmp162_; + RightLabel* _tmp163_; + Unit* _tmp164_; + gchar* _tmp165_; + gchar* _tmp166_; + gchar* _tmp167_; +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (unit != NULL); +#line 506 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = unit; +#line 506 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = unit_get_id (_tmp0_); +#line 506 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = _tmp1_; +#line 506 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (self->priv->current_unit_id); +#line 506 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->current_unit_id = _tmp2_; +#line 508 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = self->priv->current_unit_id; +#line 508 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = main_window_format_unit_link (self, _tmp3_, FALSE); +#line 508 "/home/lennart/projects/systemd/src/systemadm.vala" + id_display = _tmp4_; +#line 509 "/home/lennart/projects/systemd/src/systemadm.vala" + has_alias = FALSE; +#line 510 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = unit; +#line 510 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = unit_get_names (_tmp5_, &_tmp6__length1); +#line 510 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = _tmp6_; +#line 510 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7__length1 = _tmp6__length1; +#line 4224 "systemadm.c" + { + gchar** i_collection = NULL; + gint i_collection_length1 = 0; + gint _i_collection_size_ = 0; + gint i_it = 0; +#line 510 "/home/lennart/projects/systemd/src/systemadm.vala" + i_collection = _tmp7_; +#line 510 "/home/lennart/projects/systemd/src/systemadm.vala" + i_collection_length1 = _tmp7__length1; +#line 510 "/home/lennart/projects/systemd/src/systemadm.vala" + for (i_it = 0; i_it < _tmp7__length1; i_it = i_it + 1) { +#line 4236 "systemadm.c" + gchar* _tmp8_; + gchar* i = NULL; +#line 510 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = g_strdup (i_collection[i_it]); +#line 510 "/home/lennart/projects/systemd/src/systemadm.vala" + i = _tmp8_; +#line 4243 "systemadm.c" + { + const gchar* _tmp9_; + const gchar* _tmp10_; + gboolean _tmp11_; + const gchar* _tmp14_; + const gchar* _tmp15_; + gchar* _tmp16_; + gchar* _tmp17_; + gchar* _tmp18_; +#line 511 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = i; +#line 511 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = self->priv->current_unit_id; +#line 511 "/home/lennart/projects/systemd/src/systemadm.vala" + if (g_strcmp0 (_tmp9_, _tmp10_) == 0) { +#line 512 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (i); +#line 512 "/home/lennart/projects/systemd/src/systemadm.vala" + continue; +#line 4263 "systemadm.c" + } +#line 514 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = has_alias; +#line 514 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp11_) { +#line 4269 "systemadm.c" + const gchar* _tmp12_; + gchar* _tmp13_; +#line 515 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = id_display; +#line 515 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = g_strconcat (_tmp12_, " (aliases:", NULL); +#line 515 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id_display); +#line 515 "/home/lennart/projects/systemd/src/systemadm.vala" + id_display = _tmp13_; +#line 516 "/home/lennart/projects/systemd/src/systemadm.vala" + has_alias = TRUE; +#line 4282 "systemadm.c" + } +#line 519 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = id_display; +#line 519 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = i; +#line 519 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = g_strconcat (" ", _tmp15_, NULL); +#line 519 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = _tmp16_; +#line 519 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp18_ = g_strconcat (_tmp14_, _tmp17_, NULL); +#line 519 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id_display); +#line 519 "/home/lennart/projects/systemd/src/systemadm.vala" + id_display = _tmp18_; +#line 519 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp17_); +#line 510 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (i); +#line 4302 "systemadm.c" + } + } +#line 510 "/home/lennart/projects/systemd/src/systemadm.vala" + i_collection = (_vala_array_free (i_collection, i_collection_length1, (GDestroyNotify) g_free), NULL); +#line 4307 "systemadm.c" + } +#line 521 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp19_ = has_alias; +#line 521 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp19_) { +#line 4313 "systemadm.c" + const gchar* _tmp20_; + gchar* _tmp21_; +#line 522 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp20_ = id_display; +#line 522 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp21_ = g_strconcat (_tmp20_, ")", NULL); +#line 522 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id_display); +#line 522 "/home/lennart/projects/systemd/src/systemadm.vala" + id_display = _tmp21_; +#line 4324 "systemadm.c" + } +#line 524 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp22_ = self->priv->unit_id_label; +#line 524 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp23_ = id_display; +#line 524 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_markup_or_na (_tmp22_, _tmp23_); +#line 527 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp24_ = unit; +#line 527 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp25_ = unit_get_requires (_tmp24_, &_tmp25__length1); +#line 527 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp26_ = _tmp25_; +#line 527 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp26__length1 = _tmp25__length1; +#line 527 "/home/lennart/projects/systemd/src/systemadm.vala" + requires = _tmp26_; +#line 527 "/home/lennart/projects/systemd/src/systemadm.vala" + requires_length1 = _tmp26__length1; +#line 527 "/home/lennart/projects/systemd/src/systemadm.vala" + _requires_size_ = requires_length1; +#line 528 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp27_ = unit; +#line 528 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp28_ = unit_get_requires_overridable (_tmp27_, &_tmp28__length1); +#line 528 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp29_ = _tmp28_; +#line 528 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp29__length1 = _tmp28__length1; +#line 528 "/home/lennart/projects/systemd/src/systemadm.vala" + requires_overridable = _tmp29_; +#line 528 "/home/lennart/projects/systemd/src/systemadm.vala" + requires_overridable_length1 = _tmp29__length1; +#line 528 "/home/lennart/projects/systemd/src/systemadm.vala" + _requires_overridable_size_ = requires_overridable_length1; +#line 529 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp30_ = unit; +#line 529 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp31_ = unit_get_requisite (_tmp30_, &_tmp31__length1); +#line 529 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp32_ = _tmp31_; +#line 529 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp32__length1 = _tmp31__length1; +#line 529 "/home/lennart/projects/systemd/src/systemadm.vala" + requisite = _tmp32_; +#line 529 "/home/lennart/projects/systemd/src/systemadm.vala" + requisite_length1 = _tmp32__length1; +#line 529 "/home/lennart/projects/systemd/src/systemadm.vala" + _requisite_size_ = requisite_length1; +#line 530 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp33_ = unit; +#line 530 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp34_ = unit_get_requisite_overridable (_tmp33_, &_tmp34__length1); +#line 530 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp35_ = _tmp34_; +#line 530 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp35__length1 = _tmp34__length1; +#line 530 "/home/lennart/projects/systemd/src/systemadm.vala" + requisite_overridable = _tmp35_; +#line 530 "/home/lennart/projects/systemd/src/systemadm.vala" + requisite_overridable_length1 = _tmp35__length1; +#line 530 "/home/lennart/projects/systemd/src/systemadm.vala" + _requisite_overridable_size_ = requisite_overridable_length1; +#line 531 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp36_ = unit; +#line 531 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp37_ = unit_get_wants (_tmp36_, &_tmp37__length1); +#line 531 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp38_ = _tmp37_; +#line 531 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp38__length1 = _tmp37__length1; +#line 531 "/home/lennart/projects/systemd/src/systemadm.vala" + wants = _tmp38_; +#line 531 "/home/lennart/projects/systemd/src/systemadm.vala" + wants_length1 = _tmp38__length1; +#line 531 "/home/lennart/projects/systemd/src/systemadm.vala" + _wants_size_ = wants_length1; +#line 532 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp39_ = unit; +#line 532 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp40_ = unit_get_required_by (_tmp39_, &_tmp40__length1); +#line 532 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp41_ = _tmp40_; +#line 532 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp41__length1 = _tmp40__length1; +#line 532 "/home/lennart/projects/systemd/src/systemadm.vala" + required_by = _tmp41_; +#line 532 "/home/lennart/projects/systemd/src/systemadm.vala" + required_by_length1 = _tmp41__length1; +#line 532 "/home/lennart/projects/systemd/src/systemadm.vala" + _required_by_size_ = required_by_length1; +#line 533 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp42_ = unit; +#line 533 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp43_ = unit_get_required_by_overridable (_tmp42_, &_tmp43__length1); +#line 533 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp44_ = _tmp43_; +#line 533 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp44__length1 = _tmp43__length1; +#line 533 "/home/lennart/projects/systemd/src/systemadm.vala" + required_by_overridable = _tmp44_; +#line 533 "/home/lennart/projects/systemd/src/systemadm.vala" + required_by_overridable_length1 = _tmp44__length1; +#line 533 "/home/lennart/projects/systemd/src/systemadm.vala" + _required_by_overridable_size_ = required_by_overridable_length1; +#line 534 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp45_ = unit; +#line 534 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp46_ = unit_get_wanted_by (_tmp45_, &_tmp46__length1); +#line 534 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp47_ = _tmp46_; +#line 534 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp47__length1 = _tmp46__length1; +#line 534 "/home/lennart/projects/systemd/src/systemadm.vala" + wanted_by = _tmp47_; +#line 534 "/home/lennart/projects/systemd/src/systemadm.vala" + wanted_by_length1 = _tmp47__length1; +#line 534 "/home/lennart/projects/systemd/src/systemadm.vala" + _wanted_by_size_ = wanted_by_length1; +#line 535 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp48_ = unit; +#line 535 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp49_ = unit_get_conflicts (_tmp48_, &_tmp49__length1); +#line 535 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp50_ = _tmp49_; +#line 535 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp50__length1 = _tmp49__length1; +#line 535 "/home/lennart/projects/systemd/src/systemadm.vala" + conflicts = _tmp50_; +#line 535 "/home/lennart/projects/systemd/src/systemadm.vala" + conflicts_length1 = _tmp50__length1; +#line 535 "/home/lennart/projects/systemd/src/systemadm.vala" + _conflicts_size_ = conflicts_length1; +#line 536 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp51_ = unit; +#line 536 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp52_ = unit_get_before (_tmp51_, &_tmp52__length1); +#line 536 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp53_ = _tmp52_; +#line 536 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp53__length1 = _tmp52__length1; +#line 536 "/home/lennart/projects/systemd/src/systemadm.vala" + before = _tmp53_; +#line 536 "/home/lennart/projects/systemd/src/systemadm.vala" + before_length1 = _tmp53__length1; +#line 536 "/home/lennart/projects/systemd/src/systemadm.vala" + _before_size_ = before_length1; +#line 537 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp54_ = unit; +#line 537 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp55_ = unit_get_after (_tmp54_, &_tmp55__length1); +#line 537 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp56_ = _tmp55_; +#line 537 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp56__length1 = _tmp55__length1; +#line 537 "/home/lennart/projects/systemd/src/systemadm.vala" + after = _tmp56_; +#line 537 "/home/lennart/projects/systemd/src/systemadm.vala" + after_length1 = _tmp56__length1; +#line 537 "/home/lennart/projects/systemd/src/systemadm.vala" + _after_size_ = after_length1; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp57_ = self->priv->unit_dependency_label; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp58_ = requires; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp58__length1 = requires_length1; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp59_ = main_window_make_dependency_string (self, NULL, "requires", _tmp58_, _tmp58__length1); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp60_ = _tmp59_; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp61_ = requires_overridable; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp61__length1 = requires_overridable_length1; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp62_ = main_window_make_dependency_string (self, _tmp60_, "overridable requires", _tmp61_, _tmp61__length1); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp63_ = _tmp62_; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp64_ = requisite; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp64__length1 = requisite_length1; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp65_ = main_window_make_dependency_string (self, _tmp63_, "requisite", _tmp64_, _tmp64__length1); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp66_ = _tmp65_; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp67_ = requisite_overridable; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp67__length1 = requisite_overridable_length1; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp68_ = main_window_make_dependency_string (self, _tmp66_, "overridable requisite", _tmp67_, _tmp67__length1); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp69_ = _tmp68_; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp70_ = wants; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp70__length1 = wants_length1; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp71_ = main_window_make_dependency_string (self, _tmp69_, "wants", _tmp70_, _tmp70__length1); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp72_ = _tmp71_; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp73_ = conflicts; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp73__length1 = conflicts_length1; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp74_ = main_window_make_dependency_string (self, _tmp72_, "conflicts", _tmp73_, _tmp73__length1); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp75_ = _tmp74_; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp76_ = required_by; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp76__length1 = required_by_length1; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp77_ = main_window_make_dependency_string (self, _tmp75_, "required by", _tmp76_, _tmp76__length1); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp78_ = _tmp77_; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp79_ = required_by_overridable; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp79__length1 = required_by_overridable_length1; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp80_ = main_window_make_dependency_string (self, _tmp78_, "overridable required by", _tmp79_, _tmp79__length1); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp81_ = _tmp80_; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp82_ = wanted_by; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp82__length1 = wanted_by_length1; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp83_ = main_window_make_dependency_string (self, _tmp81_, "wanted by", _tmp82_, _tmp82__length1); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp84_ = _tmp83_; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp85_ = after; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp85__length1 = after_length1; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp86_ = main_window_make_dependency_string (self, _tmp84_, "after", _tmp85_, _tmp85__length1); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp87_ = _tmp86_; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp88_ = before; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp88__length1 = before_length1; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp89_ = main_window_make_dependency_string (self, _tmp87_, "before", _tmp88_, _tmp88__length1); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp90_ = _tmp89_; +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_markup_or_na (_tmp57_, _tmp90_); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp90_); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp87_); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp84_); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp81_); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp78_); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp75_); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp72_); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp69_); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp66_); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp63_); +#line 539 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp60_); +#line 563 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp91_ = self->priv->unit_description_label; +#line 563 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp92_ = unit; +#line 563 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp93_ = unit_get_description (_tmp92_); +#line 563 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp94_ = _tmp93_; +#line 563 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp95_ = _tmp94_; +#line 563 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp91_, _tmp95_); +#line 563 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp95_); +#line 564 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp96_ = self->priv->unit_load_state_label; +#line 564 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp97_ = unit; +#line 564 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp98_ = unit_get_load_state (_tmp97_); +#line 564 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp99_ = _tmp98_; +#line 564 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp100_ = _tmp99_; +#line 564 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp96_, _tmp100_); +#line 564 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp100_); +#line 565 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp101_ = self->priv->unit_active_state_label; +#line 565 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp102_ = unit; +#line 565 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp103_ = unit_get_active_state (_tmp102_); +#line 565 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp104_ = _tmp103_; +#line 565 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp105_ = _tmp104_; +#line 565 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp101_, _tmp105_); +#line 565 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp105_); +#line 566 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp106_ = self->priv->unit_sub_state_label; +#line 566 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp107_ = unit; +#line 566 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp108_ = unit_get_sub_state (_tmp107_); +#line 566 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp109_ = _tmp108_; +#line 566 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp110_ = _tmp109_; +#line 566 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp106_, _tmp110_); +#line 566 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp110_); +#line 568 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp111_ = unit; +#line 568 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp112_ = unit_get_fragment_path (_tmp111_); +#line 568 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp113_ = _tmp112_; +#line 568 "/home/lennart/projects/systemd/src/systemadm.vala" + fp = _tmp113_; +#line 569 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp114_ = fp; +#line 569 "/home/lennart/projects/systemd/src/systemadm.vala" + if (g_strcmp0 (_tmp114_, "") != 0) { +#line 4668 "systemadm.c" + RightLabel* _tmp115_; + const gchar* _tmp116_; + gchar* _tmp117_; + gchar* _tmp118_; + gchar* _tmp119_; + gchar* _tmp120_; + gchar* _tmp121_; + gchar* _tmp122_; + const gchar* _tmp123_; + gchar* _tmp124_; + gchar* _tmp125_; + gchar* _tmp126_; + gchar* _tmp127_; +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp115_ = self->priv->unit_fragment_path_label; +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp116_ = fp; +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp117_ = g_strconcat ("", NULL); +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp120_ = _tmp119_; +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp121_ = g_strconcat (_tmp120_, "", NULL); +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp122_ = _tmp121_; +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp123_ = fp; +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp124_ = g_strconcat (_tmp122_, _tmp123_, NULL); +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp125_ = _tmp124_; +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp126_ = g_strconcat (_tmp125_, "", NULL); +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp127_ = _tmp126_; +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_markup_or_na (_tmp115_, _tmp127_); +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp127_); +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp125_); +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp122_); +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp120_); +#line 570 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp118_); +#line 4720 "systemadm.c" + } else { + RightLabel* _tmp128_; +#line 574 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp128_ = self->priv->unit_fragment_path_label; +#line 574 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp128_, NULL); +#line 4727 "systemadm.c" + } +#line 577 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp129_ = self->priv->unit_active_enter_timestamp_label; +#line 577 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp130_ = unit; +#line 577 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp131_ = unit_get_active_enter_timestamp (_tmp130_); +#line 577 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp132_ = _tmp131_; +#line 577 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp133_ = format_time (_tmp132_); +#line 577 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp134_ = _tmp133_; +#line 577 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp129_, _tmp134_); +#line 577 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp134_); +#line 579 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp135_ = self->priv->unit_active_exit_timestamp_label; +#line 579 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp136_ = unit; +#line 579 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp137_ = unit_get_active_exit_timestamp (_tmp136_); +#line 579 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp138_ = _tmp137_; +#line 579 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp139_ = format_time (_tmp138_); +#line 579 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp140_ = _tmp139_; +#line 579 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp135_, _tmp140_); +#line 579 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp140_); +#line 581 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp141_ = unit; +#line 581 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp142_ = unit_get_can_start (_tmp141_); +#line 581 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp143_ = _tmp142_; +#line 581 "/home/lennart/projects/systemd/src/systemadm.vala" + b = _tmp143_; +#line 582 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp144_ = self->priv->start_button; +#line 582 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp145_ = b; +#line 582 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_widget_set_sensitive ((GtkWidget*) _tmp144_, _tmp145_); +#line 583 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp146_ = self->priv->stop_button; +#line 583 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp147_ = b; +#line 583 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_widget_set_sensitive ((GtkWidget*) _tmp146_, _tmp147_); +#line 584 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp148_ = self->priv->restart_button; +#line 584 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp149_ = b; +#line 584 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_widget_set_sensitive ((GtkWidget*) _tmp148_, _tmp149_); +#line 585 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp151_ = b; +#line 585 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp151_) { +#line 585 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp150_ = "Yes"; +#line 4793 "systemadm.c" + } else { +#line 585 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp150_ = "No"; +#line 4797 "systemadm.c" + } +#line 585 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp152_ = self->priv->unit_can_start_label; +#line 585 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp153_ = _tmp150_; +#line 585 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp152_, _tmp153_); +#line 587 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp154_ = unit; +#line 587 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp155_ = unit_get_can_reload (_tmp154_); +#line 587 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp156_ = _tmp155_; +#line 587 "/home/lennart/projects/systemd/src/systemadm.vala" + b = _tmp156_; +#line 588 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp157_ = self->priv->reload_button; +#line 588 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp158_ = b; +#line 588 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_widget_set_sensitive ((GtkWidget*) _tmp157_, _tmp158_); +#line 589 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp160_ = b; +#line 589 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp160_) { +#line 589 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp159_ = "Yes"; +#line 4825 "systemadm.c" + } else { +#line 589 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp159_ = "No"; +#line 4829 "systemadm.c" + } +#line 589 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp161_ = self->priv->unit_can_reload_label; +#line 589 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp162_ = _tmp159_; +#line 589 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp161_, _tmp162_); +#line 591 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp163_ = self->priv->unit_cgroup_label; +#line 591 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp164_ = unit; +#line 591 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp165_ = unit_get_default_control_group (_tmp164_); +#line 591 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp166_ = _tmp165_; +#line 591 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp167_ = _tmp166_; +#line 591 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp163_, _tmp167_); +#line 591 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp167_); +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (fp); +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + after = (_vala_array_free (after, after_length1, (GDestroyNotify) g_free), NULL); +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + before = (_vala_array_free (before, before_length1, (GDestroyNotify) g_free), NULL); +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + conflicts = (_vala_array_free (conflicts, conflicts_length1, (GDestroyNotify) g_free), NULL); +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + wanted_by = (_vala_array_free (wanted_by, wanted_by_length1, (GDestroyNotify) g_free), NULL); +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + required_by_overridable = (_vala_array_free (required_by_overridable, required_by_overridable_length1, (GDestroyNotify) g_free), NULL); +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + required_by = (_vala_array_free (required_by, required_by_length1, (GDestroyNotify) g_free), NULL); +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + wants = (_vala_array_free (wants, wants_length1, (GDestroyNotify) g_free), NULL); +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + requisite_overridable = (_vala_array_free (requisite_overridable, requisite_overridable_length1, (GDestroyNotify) g_free), NULL); +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + requisite = (_vala_array_free (requisite, requisite_length1, (GDestroyNotify) g_free), NULL); +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + requires_overridable = (_vala_array_free (requires_overridable, requires_overridable_length1, (GDestroyNotify) g_free), NULL); +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + requires = (_vala_array_free (requires, requires_length1, (GDestroyNotify) g_free), NULL); +#line 505 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id_display); +#line 4877 "systemadm.c" +} + + +Job* main_window_get_current_job (MainWindow* self) { + Job* result = NULL; + GtkTreePath* p = NULL; + GtkTreeView* _tmp0_; + GtkTreePath* _tmp1_ = NULL; + GtkTreePath* _tmp2_; + GtkTreeIter iter = {0}; + GtkTreeView* _tmp3_; + GtkTreeModel* _tmp4_ = NULL; + GtkTreeModel* _tmp5_; + GtkTreeModel* model; + Job* j = NULL; + GtkTreeModel* _tmp6_; + GtkTreePath* _tmp7_; + GtkTreeIter _tmp8_ = {0}; + GtkTreeModel* _tmp9_; + GtkTreeIter _tmp10_; + Job* _tmp11_; + Job* _tmp12_; +#line 594 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 596 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->job_view; +#line 596 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_view_get_cursor (_tmp0_, &_tmp1_, NULL); +#line 596 "/home/lennart/projects/systemd/src/systemadm.vala" + _gtk_tree_path_free0 (p); +#line 596 "/home/lennart/projects/systemd/src/systemadm.vala" + p = _tmp1_; +#line 598 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = p; +#line 598 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp2_ == NULL) { +#line 599 "/home/lennart/projects/systemd/src/systemadm.vala" + result = NULL; +#line 599 "/home/lennart/projects/systemd/src/systemadm.vala" + _gtk_tree_path_free0 (p); +#line 599 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 4920 "systemadm.c" + } +#line 602 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = self->priv->job_view; +#line 602 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = gtk_tree_view_get_model (_tmp3_); +#line 602 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = _g_object_ref0 (_tmp4_); +#line 602 "/home/lennart/projects/systemd/src/systemadm.vala" + model = _tmp5_; +#line 605 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = model; +#line 605 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = p; +#line 605 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_model_get_iter (_tmp6_, &_tmp8_, _tmp7_); +#line 605 "/home/lennart/projects/systemd/src/systemadm.vala" + iter = _tmp8_; +#line 606 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = model; +#line 606 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = iter; +#line 606 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_model_get (_tmp9_, &_tmp10_, 4, &j, -1); +#line 608 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = j; +#line 608 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = _g_object_ref0 (_tmp11_); +#line 608 "/home/lennart/projects/systemd/src/systemadm.vala" + result = _tmp12_; +#line 608 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (model); +#line 608 "/home/lennart/projects/systemd/src/systemadm.vala" + _gtk_tree_path_free0 (p); +#line 608 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 4956 "systemadm.c" +} + + +void main_window_job_changed (MainWindow* self) { + Job* _tmp0_ = NULL; + Job* j; + Job* _tmp1_; +#line 611 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 612 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = main_window_get_current_job (self); +#line 612 "/home/lennart/projects/systemd/src/systemadm.vala" + j = _tmp0_; +#line 614 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = j; +#line 614 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp1_ == NULL) { +#line 615 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_clear_job (self); +#line 4976 "systemadm.c" + } else { + Job* _tmp2_; +#line 617 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = j; +#line 617 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_job (self, _tmp2_); +#line 4983 "systemadm.c" + } +#line 611 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (j); +#line 4987 "systemadm.c" +} + + +void main_window_clear_job (MainWindow* self) { + RightLabel* _tmp0_; + RightLabel* _tmp1_; + RightLabel* _tmp2_; + GtkButton* _tmp3_; +#line 620 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 621 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->current_job_id = (guint32) 0; +#line 623 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->job_id_label; +#line 623 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp0_, NULL); +#line 624 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = self->priv->job_state_label; +#line 624 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp1_, NULL); +#line 625 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = self->priv->job_type_label; +#line 625 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp2_, NULL); +#line 627 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = self->priv->cancel_button; +#line 627 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_widget_set_sensitive ((GtkWidget*) _tmp3_, FALSE); +#line 5016 "systemadm.c" +} + + +void main_window_show_job (MainWindow* self, Job* job) { + Job* _tmp0_; + guint32 _tmp1_; + guint32 _tmp2_; + RightLabel* _tmp3_; + guint32 _tmp4_; + gchar* _tmp5_ = NULL; + gchar* _tmp6_; + RightLabel* _tmp7_; + Job* _tmp8_; + gchar* _tmp9_; + gchar* _tmp10_; + gchar* _tmp11_; + RightLabel* _tmp12_; + Job* _tmp13_; + gchar* _tmp14_; + gchar* _tmp15_; + gchar* _tmp16_; + GtkButton* _tmp17_; +#line 630 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 630 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (job != NULL); +#line 631 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = job; +#line 631 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = job_get_id (_tmp0_); +#line 631 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = _tmp1_; +#line 631 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv->current_job_id = _tmp2_; +#line 633 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = self->priv->job_id_label; +#line 633 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = self->priv->current_job_id; +#line 633 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = g_strdup_printf ("%u", (guint) _tmp4_); +#line 633 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = _tmp5_; +#line 633 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp3_, _tmp6_); +#line 633 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp6_); +#line 634 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = self->priv->job_state_label; +#line 634 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = job; +#line 634 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = job_get_state (_tmp8_); +#line 634 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = _tmp9_; +#line 634 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = _tmp10_; +#line 634 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp7_, _tmp11_); +#line 634 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp11_); +#line 635 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = self->priv->job_type_label; +#line 635 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = job; +#line 635 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = job_get_job_type (_tmp13_); +#line 635 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = _tmp14_; +#line 635 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = _tmp15_; +#line 635 "/home/lennart/projects/systemd/src/systemadm.vala" + right_label_set_text_or_na (_tmp12_, _tmp16_); +#line 635 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp16_); +#line 637 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = self->priv->cancel_button; +#line 637 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_widget_set_sensitive ((GtkWidget*) _tmp17_, TRUE); +#line 5095 "systemadm.c" +} + + +void main_window_on_start (MainWindow* self) { + Unit* _tmp0_ = NULL; + Unit* u; + Unit* _tmp1_; + GError * _inner_error_ = NULL; +#line 640 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 641 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = main_window_get_current_unit (self); +#line 641 "/home/lennart/projects/systemd/src/systemadm.vala" + u = _tmp0_; +#line 643 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = u; +#line 643 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp1_ == NULL) { +#line 644 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 644 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 5118 "systemadm.c" + } + { + Unit* _tmp2_; + char* _tmp3_ = NULL; + char* _tmp4_; +#line 647 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = u; +#line 647 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = unit_start (_tmp2_, "replace", &_inner_error_); +#line 647 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = _tmp3_; +#line 647 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp4_); +#line 647 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 5134 "systemadm.c" + goto __catch0_g_error; + } + } + goto __finally0; + __catch0_g_error: + { + GError* e = NULL; + GError* _tmp5_; + const gchar* _tmp6_; +#line 646 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 646 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 649 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = e; +#line 649 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = _tmp5_->message; +#line 649 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_error (self, _tmp6_); +#line 646 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 5156 "systemadm.c" + } + __finally0: +#line 646 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 646 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 646 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 646 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 646 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 5169 "systemadm.c" + } +#line 640 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 5173 "systemadm.c" +} + + +void main_window_on_stop (MainWindow* self) { + Unit* _tmp0_ = NULL; + Unit* u; + Unit* _tmp1_; + GError * _inner_error_ = NULL; +#line 653 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 654 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = main_window_get_current_unit (self); +#line 654 "/home/lennart/projects/systemd/src/systemadm.vala" + u = _tmp0_; +#line 656 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = u; +#line 656 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp1_ == NULL) { +#line 657 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 657 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 5196 "systemadm.c" + } + { + Unit* _tmp2_; + char* _tmp3_ = NULL; + char* _tmp4_; +#line 660 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = u; +#line 660 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = unit_stop (_tmp2_, "replace", &_inner_error_); +#line 660 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = _tmp3_; +#line 660 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp4_); +#line 660 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 5212 "systemadm.c" + goto __catch1_g_error; + } + } + goto __finally1; + __catch1_g_error: + { + GError* e = NULL; + GError* _tmp5_; + const gchar* _tmp6_; +#line 659 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 659 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 662 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = e; +#line 662 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = _tmp5_->message; +#line 662 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_error (self, _tmp6_); +#line 659 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 5234 "systemadm.c" + } + __finally1: +#line 659 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 659 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 659 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 659 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 659 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 5247 "systemadm.c" + } +#line 653 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 5251 "systemadm.c" +} + + +void main_window_on_reload (MainWindow* self) { + Unit* _tmp0_ = NULL; + Unit* u; + Unit* _tmp1_; + GError * _inner_error_ = NULL; +#line 666 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 667 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = main_window_get_current_unit (self); +#line 667 "/home/lennart/projects/systemd/src/systemadm.vala" + u = _tmp0_; +#line 669 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = u; +#line 669 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp1_ == NULL) { +#line 670 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 670 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 5274 "systemadm.c" + } + { + Unit* _tmp2_; + char* _tmp3_ = NULL; + char* _tmp4_; +#line 673 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = u; +#line 673 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = unit_reload (_tmp2_, "replace", &_inner_error_); +#line 673 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = _tmp3_; +#line 673 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp4_); +#line 673 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 5290 "systemadm.c" + goto __catch2_g_error; + } + } + goto __finally2; + __catch2_g_error: + { + GError* e = NULL; + GError* _tmp5_; + const gchar* _tmp6_; +#line 672 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 672 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 675 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = e; +#line 675 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = _tmp5_->message; +#line 675 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_error (self, _tmp6_); +#line 672 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 5312 "systemadm.c" + } + __finally2: +#line 672 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 672 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 672 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 672 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 672 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 5325 "systemadm.c" + } +#line 666 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 5329 "systemadm.c" +} + + +void main_window_on_restart (MainWindow* self) { + Unit* _tmp0_ = NULL; + Unit* u; + Unit* _tmp1_; + GError * _inner_error_ = NULL; +#line 679 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 680 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = main_window_get_current_unit (self); +#line 680 "/home/lennart/projects/systemd/src/systemadm.vala" + u = _tmp0_; +#line 682 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = u; +#line 682 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp1_ == NULL) { +#line 683 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 683 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 5352 "systemadm.c" + } + { + Unit* _tmp2_; + char* _tmp3_ = NULL; + char* _tmp4_; +#line 686 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = u; +#line 686 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = unit_restart (_tmp2_, "replace", &_inner_error_); +#line 686 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = _tmp3_; +#line 686 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp4_); +#line 686 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 5368 "systemadm.c" + goto __catch3_g_error; + } + } + goto __finally3; + __catch3_g_error: + { + GError* e = NULL; + GError* _tmp5_; + const gchar* _tmp6_; +#line 685 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 685 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 688 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = e; +#line 688 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = _tmp5_->message; +#line 688 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_error (self, _tmp6_); +#line 685 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 5390 "systemadm.c" + } + __finally3: +#line 685 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 685 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 685 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 685 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 685 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 5403 "systemadm.c" + } +#line 679 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 5407 "systemadm.c" +} + + +void main_window_on_cancel (MainWindow* self) { + Job* _tmp0_ = NULL; + Job* j; + Job* _tmp1_; + GError * _inner_error_ = NULL; +#line 692 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 693 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = main_window_get_current_job (self); +#line 693 "/home/lennart/projects/systemd/src/systemadm.vala" + j = _tmp0_; +#line 695 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = j; +#line 695 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp1_ == NULL) { +#line 696 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (j); +#line 696 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 5430 "systemadm.c" + } + { + Job* _tmp2_; +#line 699 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = j; +#line 699 "/home/lennart/projects/systemd/src/systemadm.vala" + job_cancel (_tmp2_, &_inner_error_); +#line 699 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 5440 "systemadm.c" + goto __catch4_g_error; + } + } + goto __finally4; + __catch4_g_error: + { + GError* e = NULL; + GError* _tmp3_; + const gchar* _tmp4_; +#line 698 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 698 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 701 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = e; +#line 701 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = _tmp3_->message; +#line 701 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_error (self, _tmp4_); +#line 698 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 5462 "systemadm.c" + } + __finally4: +#line 698 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 698 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (j); +#line 698 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 698 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 698 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 5475 "systemadm.c" + } +#line 692 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (j); +#line 5479 "systemadm.c" +} + + +void main_window_update_unit_iter (MainWindow* self, GtkTreeIter* iter, const gchar* id, Unit* u) { + GError * _inner_error_ = NULL; +#line 705 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 705 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (iter != NULL); +#line 705 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (id != NULL); +#line 705 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (u != NULL); +#line 5493 "systemadm.c" + { + gchar* _tmp0_; + gchar* t; + Unit* _tmp1_; + UnitJobLink _tmp2_; + UnitJobLink _tmp3_; + UnitJobLink jl; + UnitJobLink _tmp4_; + guint32 _tmp5_; + gchar* _tmp15_ = NULL; + const gchar* _tmp16_; + GtkListStore* _tmp20_; + GtkTreeIter _tmp21_; + const gchar* _tmp22_; + Unit* _tmp23_; + gchar* _tmp24_; + gchar* _tmp25_; + gchar* _tmp26_; + Unit* _tmp27_; + gchar* _tmp28_; + gchar* _tmp29_; + gchar* _tmp30_; + Unit* _tmp31_; + gchar* _tmp32_; + gchar* _tmp33_; + gchar* _tmp34_; + Unit* _tmp35_; + gchar* _tmp36_; + gchar* _tmp37_; + gchar* _tmp38_; + const gchar* _tmp39_; + Unit* _tmp40_; +#line 708 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = g_strdup (""); +#line 708 "/home/lennart/projects/systemd/src/systemadm.vala" + t = _tmp0_; +#line 709 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = u; +#line 709 "/home/lennart/projects/systemd/src/systemadm.vala" + unit_get_job (_tmp1_, &_tmp2_); +#line 709 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = _tmp2_; +#line 709 "/home/lennart/projects/systemd/src/systemadm.vala" + jl = _tmp3_; +#line 711 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = jl; +#line 711 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = _tmp4_.id; +#line 711 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp5_ != ((guint32) 0)) { +#line 5544 "systemadm.c" + GBusType _tmp6_ = 0; + gboolean _tmp7_; + GBusType _tmp8_; + UnitJobLink _tmp9_; + const char* _tmp10_; + Job* _tmp11_ = NULL; + Job* j; + Job* _tmp12_; + gchar* _tmp13_; + gchar* _tmp14_; +#line 713 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = user; +#line 713 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp7_) { +#line 713 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = G_BUS_TYPE_SESSION; +#line 5561 "systemadm.c" + } else { +#line 713 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = G_BUS_TYPE_SYSTEM; +#line 5565 "systemadm.c" + } +#line 712 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = _tmp6_; +#line 712 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = jl; +#line 712 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = _tmp9_.path; +#line 712 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = g_initable_new (TYPE_JOB_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.freedesktop.systemd1", "g-bus-type", _tmp8_, "g-object-path", (const gchar*) _tmp10_, "g-interface-name", "org.freedesktop.systemd1.Job", NULL); +#line 712 "/home/lennart/projects/systemd/src/systemadm.vala" + j = (Job*) _tmp11_; +#line 712 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 712 "/home/lennart/projects/systemd/src/systemadm.vala" + unit_job_link_destroy (&jl); +#line 712 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (t); +#line 5583 "systemadm.c" + goto __catch5_g_error; + } +#line 717 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = j; +#line 717 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = job_get_job_type (_tmp12_); +#line 717 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = _tmp13_; +#line 717 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (t); +#line 717 "/home/lennart/projects/systemd/src/systemadm.vala" + t = _tmp14_; +#line 711 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (j); +#line 5598 "systemadm.c" + } +#line 726 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = t; +#line 726 "/home/lennart/projects/systemd/src/systemadm.vala" + if (g_strcmp0 (_tmp16_, "") != 0) { +#line 5604 "systemadm.c" + const gchar* _tmp17_; + gchar* _tmp18_ = NULL; +#line 726 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = t; +#line 726 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp18_ = g_strdup_printf ("→ %s", _tmp17_); +#line 726 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp15_); +#line 726 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = _tmp18_; +#line 5615 "systemadm.c" + } else { + gchar* _tmp19_; +#line 726 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp19_ = g_strdup (""); +#line 726 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp15_); +#line 726 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = _tmp19_; +#line 5624 "systemadm.c" + } +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp20_ = self->priv->unit_model; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp21_ = *iter; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp22_ = id; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp23_ = u; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp24_ = unit_get_description (_tmp23_); +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp25_ = _tmp24_; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp26_ = _tmp25_; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp27_ = u; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp28_ = unit_get_load_state (_tmp27_); +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp29_ = _tmp28_; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp30_ = _tmp29_; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp31_ = u; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp32_ = unit_get_active_state (_tmp31_); +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp33_ = _tmp32_; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp34_ = _tmp33_; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp35_ = u; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp36_ = unit_get_sub_state (_tmp35_); +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp37_ = _tmp36_; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp38_ = _tmp37_; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp39_ = _tmp15_; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp40_ = u; +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_list_store_set (_tmp20_, &_tmp21_, 0, _tmp22_, 1, _tmp26_, 2, _tmp30_, 3, _tmp34_, 4, _tmp38_, 5, _tmp39_, 6, _tmp40_, -1); +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp38_); +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp34_); +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp30_); +#line 720 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp26_); +#line 707 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp15_); +#line 707 "/home/lennart/projects/systemd/src/systemadm.vala" + unit_job_link_destroy (&jl); +#line 707 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (t); +#line 5684 "systemadm.c" + } + goto __finally5; + __catch5_g_error: + { + GError* e = NULL; + GError* _tmp41_; + const gchar* _tmp42_; +#line 707 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 707 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 729 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp41_ = e; +#line 729 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp42_ = _tmp41_->message; +#line 729 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_error (self, _tmp42_); +#line 707 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 5704 "systemadm.c" + } + __finally5: +#line 707 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 707 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 707 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 707 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 5715 "systemadm.c" + } +} + + +void main_window_on_unit_new (MainWindow* self, const gchar* id, const char* path) { + GError * _inner_error_ = NULL; +#line 733 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 733 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (id != NULL); +#line 733 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (path != NULL); +#line 5728 "systemadm.c" + { + GBusType _tmp0_ = 0; + gboolean _tmp1_; + GBusType _tmp2_; + const char* _tmp3_; + Properties* _tmp4_ = NULL; + Properties* p; + Properties* _tmp5_; + GtkTreeIter iter = {0}; + GtkListStore* _tmp6_; + GtkTreeIter _tmp7_ = {0}; + GBusType _tmp8_ = 0; + gboolean _tmp9_; + GBusType _tmp10_; + const char* _tmp11_; + Unit* _tmp12_ = NULL; + Unit* u; + GeeHashMap* _tmp13_; + const gchar* _tmp14_; + Unit* _tmp15_; + GtkTreeIter _tmp16_; + const gchar* _tmp17_; + Unit* _tmp18_; +#line 737 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = user; +#line 737 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp1_) { +#line 737 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = G_BUS_TYPE_SESSION; +#line 5758 "systemadm.c" + } else { +#line 737 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = G_BUS_TYPE_SYSTEM; +#line 5762 "systemadm.c" + } +#line 736 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = _tmp0_; +#line 736 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = path; +#line 736 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = g_initable_new (TYPE_PROPERTIES_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.freedesktop.systemd1", "g-bus-type", _tmp2_, "g-object-path", (const gchar*) _tmp3_, "g-interface-name", "org.freedesktop.Properties", NULL); +#line 736 "/home/lennart/projects/systemd/src/systemadm.vala" + p = (Properties*) _tmp4_; +#line 736 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 5774 "systemadm.c" + goto __catch6_g_error; + } +#line 741 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = p; +#line 741 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp5_, "properties-changed", (GCallback) _main_window_on_unit_changed_properties_properties_changed, self, 0); +#line 744 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = self->priv->unit_model; +#line 744 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_list_store_append (_tmp6_, &_tmp7_); +#line 744 "/home/lennart/projects/systemd/src/systemadm.vala" + iter = _tmp7_; +#line 747 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = user; +#line 747 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp9_) { +#line 747 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = G_BUS_TYPE_SESSION; +#line 5793 "systemadm.c" + } else { +#line 747 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = G_BUS_TYPE_SYSTEM; +#line 5797 "systemadm.c" + } +#line 746 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = _tmp8_; +#line 746 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = path; +#line 746 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = g_initable_new (TYPE_UNIT_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.freedesktop.systemd1", "g-bus-type", _tmp10_, "g-object-path", (const gchar*) _tmp11_, "g-interface-name", "org.freedesktop.systemd1.Unit", NULL); +#line 746 "/home/lennart/projects/systemd/src/systemadm.vala" + u = (Unit*) _tmp12_; +#line 746 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 746 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (p); +#line 5811 "systemadm.c" + goto __catch6_g_error; + } +#line 751 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = self->priv->unit_map; +#line 751 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = id; +#line 751 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = u; +#line 751 "/home/lennart/projects/systemd/src/systemadm.vala" + gee_abstract_map_set ((GeeAbstractMap*) _tmp13_, _tmp14_, _tmp15_); +#line 753 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = iter; +#line 753 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = id; +#line 753 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp18_ = u; +#line 753 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_update_unit_iter (self, &_tmp16_, _tmp17_, _tmp18_); +#line 734 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 734 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (p); +#line 5834 "systemadm.c" + } + goto __finally6; + __catch6_g_error: + { + GError* e = NULL; + GError* _tmp19_; + const gchar* _tmp20_; +#line 734 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 734 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 755 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp19_ = e; +#line 755 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp20_ = _tmp19_->message; +#line 755 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_error (self, _tmp20_); +#line 734 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 5854 "systemadm.c" + } + __finally6: +#line 734 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 734 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 734 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 734 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 5865 "systemadm.c" + } +} + + +void main_window_update_job_iter (MainWindow* self, GtkTreeIter* iter, guint32 id, Job* j) { + GtkListStore* _tmp0_; + GtkTreeIter _tmp1_; + guint32 _tmp2_; + gchar* _tmp3_ = NULL; + gchar* _tmp4_; + Job* _tmp5_; + JobUnitLink _tmp6_; + JobUnitLink _tmp7_; + JobUnitLink _tmp8_; + const gchar* _tmp9_; + Job* _tmp10_; + gchar* _tmp11_; + gchar* _tmp12_; + gchar* _tmp13_; + gchar* _tmp14_ = NULL; + gchar* _tmp15_; + Job* _tmp16_; + gchar* _tmp17_; + gchar* _tmp18_; + gchar* _tmp19_; + Job* _tmp20_; + guint32 _tmp21_; +#line 759 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 759 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (iter != NULL); +#line 759 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (j != NULL); +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->job_model; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = *iter; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = id; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = g_strdup_printf ("%u", (guint) _tmp2_); +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = _tmp3_; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = j; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + job_get_unit (_tmp5_, &_tmp6_); +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = _tmp6_; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = _tmp7_; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = _tmp8_.id; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = j; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = job_get_job_type (_tmp10_); +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = _tmp11_; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = _tmp12_; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = g_strdup_printf ("→ %s", _tmp13_); +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = _tmp14_; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = j; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = job_get_state (_tmp16_); +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp18_ = _tmp17_; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp19_ = _tmp18_; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp20_ = j; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp21_ = id; +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_list_store_set (_tmp0_, &_tmp1_, 0, _tmp4_, 1, _tmp9_, 2, _tmp15_, 3, _tmp19_, 4, _tmp20_, 5, _tmp21_, -1); +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp19_); +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp15_); +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp13_); +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + job_unit_link_destroy (&_tmp8_); +#line 760 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp4_); +#line 5955 "systemadm.c" +} + + +void main_window_on_job_new (MainWindow* self, guint32 id, const char* path) { + GError * _inner_error_ = NULL; +#line 769 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 769 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (path != NULL); +#line 5965 "systemadm.c" + { + GBusType _tmp0_ = 0; + gboolean _tmp1_; + GBusType _tmp2_; + const char* _tmp3_; + Properties* _tmp4_ = NULL; + Properties* p; + Properties* _tmp5_; + GtkTreeIter iter = {0}; + GtkListStore* _tmp6_; + GtkTreeIter _tmp7_ = {0}; + GBusType _tmp8_ = 0; + gboolean _tmp9_; + GBusType _tmp10_; + const char* _tmp11_; + Job* _tmp12_ = NULL; + Job* j; + GtkTreeIter _tmp13_; + guint32 _tmp14_; + Job* _tmp15_; +#line 774 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = user; +#line 774 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp1_) { +#line 774 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = G_BUS_TYPE_SESSION; +#line 5992 "systemadm.c" + } else { +#line 774 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = G_BUS_TYPE_SYSTEM; +#line 5996 "systemadm.c" + } +#line 773 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = _tmp0_; +#line 773 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = path; +#line 773 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = g_initable_new (TYPE_PROPERTIES_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.freedesktop.systemd1", "g-bus-type", _tmp2_, "g-object-path", (const gchar*) _tmp3_, "g-interface-name", "org.freedesktop.Properties", NULL); +#line 773 "/home/lennart/projects/systemd/src/systemadm.vala" + p = (Properties*) _tmp4_; +#line 773 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 6008 "systemadm.c" + goto __catch7_g_error; + } +#line 778 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = p; +#line 778 "/home/lennart/projects/systemd/src/systemadm.vala" + g_signal_connect_object (_tmp5_, "properties-changed", (GCallback) _main_window_on_job_changed_properties_properties_changed, self, 0); +#line 781 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = self->priv->job_model; +#line 781 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_list_store_append (_tmp6_, &_tmp7_); +#line 781 "/home/lennart/projects/systemd/src/systemadm.vala" + iter = _tmp7_; +#line 784 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = user; +#line 784 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp9_) { +#line 784 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = G_BUS_TYPE_SESSION; +#line 6027 "systemadm.c" + } else { +#line 784 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = G_BUS_TYPE_SYSTEM; +#line 6031 "systemadm.c" + } +#line 783 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = _tmp8_; +#line 783 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = path; +#line 783 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = g_initable_new (TYPE_JOB_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.freedesktop.systemd1", "g-bus-type", _tmp10_, "g-object-path", (const gchar*) _tmp11_, "g-interface-name", "org.freedesktop.systemd1.Job", NULL); +#line 783 "/home/lennart/projects/systemd/src/systemadm.vala" + j = (Job*) _tmp12_; +#line 783 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 783 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (p); +#line 6045 "systemadm.c" + goto __catch7_g_error; + } +#line 788 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = iter; +#line 788 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = id; +#line 788 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = j; +#line 788 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_update_job_iter (self, &_tmp13_, _tmp14_, _tmp15_); +#line 771 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (j); +#line 771 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (p); +#line 6060 "systemadm.c" + } + goto __finally7; + __catch7_g_error: + { + GError* e = NULL; + GError* _tmp16_; + const gchar* _tmp17_; +#line 771 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 771 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 791 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = e; +#line 791 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = _tmp16_->message; +#line 791 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_error (self, _tmp17_); +#line 771 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 6080 "systemadm.c" + } + __finally7: +#line 771 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 771 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 771 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 771 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 6091 "systemadm.c" + } +} + + +void main_window_on_unit_removed (MainWindow* self, const gchar* id, const char* path) { + GtkTreeIter iter = {0}; + GtkListStore* _tmp0_; + GtkTreeIter _tmp1_ = {0}; + gboolean _tmp2_ = FALSE; + GeeHashMap* _tmp15_; + const gchar* _tmp16_; +#line 795 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 795 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (id != NULL); +#line 795 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (path != NULL); +#line 797 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->unit_model; +#line 797 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = gtk_tree_model_get_iter_first ((GtkTreeModel*) _tmp0_, &_tmp1_); +#line 797 "/home/lennart/projects/systemd/src/systemadm.vala" + iter = _tmp1_; +#line 797 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp2_) { +#line 798 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 6119 "systemadm.c" + } + { + gboolean _tmp3_; +#line 800 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = TRUE; +#line 800 "/home/lennart/projects/systemd/src/systemadm.vala" + while (TRUE) { +#line 6127 "systemadm.c" + gboolean _tmp4_; + gchar* name = NULL; + GtkListStore* _tmp7_; + GtkTreeIter _tmp8_; + const gchar* _tmp9_; + const gchar* _tmp10_; +#line 800 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = _tmp3_; +#line 800 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp4_) { +#line 6138 "systemadm.c" + GtkListStore* _tmp5_; + gboolean _tmp6_ = FALSE; +#line 813 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = self->priv->unit_model; +#line 813 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = gtk_tree_model_iter_next ((GtkTreeModel*) _tmp5_, &iter); +#line 813 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp6_) { +#line 813 "/home/lennart/projects/systemd/src/systemadm.vala" + break; +#line 6149 "systemadm.c" + } + } +#line 800 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = FALSE; +#line 803 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = self->priv->unit_model; +#line 803 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = iter; +#line 803 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_model_get ((GtkTreeModel*) _tmp7_, &_tmp8_, 0, &name, -1); +#line 805 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = id; +#line 805 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = name; +#line 805 "/home/lennart/projects/systemd/src/systemadm.vala" + if (g_strcmp0 (_tmp9_, _tmp10_) == 0) { +#line 6166 "systemadm.c" + const gchar* _tmp11_; + const gchar* _tmp12_; + GtkListStore* _tmp13_; + GtkTreeIter _tmp14_; +#line 806 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = self->priv->current_unit_id; +#line 806 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = name; +#line 806 "/home/lennart/projects/systemd/src/systemadm.vala" + if (g_strcmp0 (_tmp11_, _tmp12_) == 0) { +#line 807 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_clear_unit (self); +#line 6179 "systemadm.c" + } +#line 809 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = self->priv->unit_model; +#line 809 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = iter; +#line 809 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_list_store_remove (_tmp13_, &_tmp14_); +#line 810 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (name); +#line 810 "/home/lennart/projects/systemd/src/systemadm.vala" + break; +#line 6191 "systemadm.c" + } +#line 800 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (name); +#line 6195 "systemadm.c" + } + } +#line 815 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = self->priv->unit_map; +#line 815 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = id; +#line 815 "/home/lennart/projects/systemd/src/systemadm.vala" + gee_abstract_map_unset ((GeeAbstractMap*) _tmp15_, _tmp16_, NULL); +#line 6204 "systemadm.c" +} + + +void main_window_on_job_removed (MainWindow* self, guint32 id, const char* path, const gchar* res) { + GtkTreeIter iter = {0}; + GtkListStore* _tmp0_; + GtkTreeIter _tmp1_ = {0}; + gboolean _tmp2_ = FALSE; +#line 818 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 818 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (path != NULL); +#line 818 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (res != NULL); +#line 820 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->job_model; +#line 820 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = gtk_tree_model_get_iter_first ((GtkTreeModel*) _tmp0_, &_tmp1_); +#line 820 "/home/lennart/projects/systemd/src/systemadm.vala" + iter = _tmp1_; +#line 820 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp2_) { +#line 821 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 6229 "systemadm.c" + } + { + gboolean _tmp3_; +#line 823 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = TRUE; +#line 823 "/home/lennart/projects/systemd/src/systemadm.vala" + while (TRUE) { +#line 6237 "systemadm.c" + gboolean _tmp4_; + guint32 j = 0U; + GtkListStore* _tmp7_; + GtkTreeIter _tmp8_; + guint32 _tmp9_; + guint32 _tmp10_; +#line 823 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = _tmp3_; +#line 823 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp4_) { +#line 6248 "systemadm.c" + GtkListStore* _tmp5_; + gboolean _tmp6_ = FALSE; +#line 837 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = self->priv->job_model; +#line 837 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = gtk_tree_model_iter_next ((GtkTreeModel*) _tmp5_, &iter); +#line 837 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp6_) { +#line 837 "/home/lennart/projects/systemd/src/systemadm.vala" + break; +#line 6259 "systemadm.c" + } + } +#line 823 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = FALSE; +#line 826 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = self->priv->job_model; +#line 826 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = iter; +#line 826 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_model_get ((GtkTreeModel*) _tmp7_, &_tmp8_, 5, &j, -1); +#line 828 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = id; +#line 828 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = j; +#line 828 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp9_ == _tmp10_) { +#line 6276 "systemadm.c" + guint32 _tmp11_; + guint32 _tmp12_; + GtkListStore* _tmp13_; + GtkTreeIter _tmp14_; +#line 829 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = self->priv->current_job_id; +#line 829 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = j; +#line 829 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp11_ == _tmp12_) { +#line 830 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_clear_job (self); +#line 6289 "systemadm.c" + } +#line 832 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = self->priv->job_model; +#line 832 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = iter; +#line 832 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_list_store_remove (_tmp13_, &_tmp14_); +#line 834 "/home/lennart/projects/systemd/src/systemadm.vala" + break; +#line 6299 "systemadm.c" + } + } + } +} + + +void main_window_on_unit_changed (MainWindow* self, Properties* p, const gchar* iface, GHashTable* changed_properties, gchar** invalidated_properties, int invalidated_properties_length1) { + GError * _inner_error_ = NULL; +#line 840 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 840 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (p != NULL); +#line 840 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (iface != NULL); +#line 840 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (changed_properties != NULL); +#line 6316 "systemadm.c" + { + GtkTreeIter iter = {0}; + gchar* id = NULL; + GBusType _tmp0_ = 0; + gboolean _tmp1_; + GBusType _tmp2_; + Properties* _tmp3_; + const gchar* _tmp4_ = NULL; + Properties* _tmp5_; + const gchar* _tmp6_ = NULL; + Unit* _tmp7_ = NULL; + Unit* u; + GtkListStore* _tmp8_; + GtkTreeIter _tmp9_ = {0}; + gboolean _tmp10_ = FALSE; + Unit* _tmp11_; + gchar* _tmp12_; + gchar* _tmp13_; +#line 847 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = user; +#line 847 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp1_) { +#line 847 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = G_BUS_TYPE_SESSION; +#line 6341 "systemadm.c" + } else { +#line 847 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = G_BUS_TYPE_SYSTEM; +#line 6345 "systemadm.c" + } +#line 846 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = _tmp0_; +#line 846 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = p; +#line 846 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = g_dbus_proxy_get_name ((GDBusProxy*) _tmp3_); +#line 846 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = p; +#line 846 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = g_dbus_proxy_get_object_path ((GDBusProxy*) _tmp5_); +#line 846 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = g_initable_new (TYPE_UNIT_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", _tmp4_, "g-bus-type", _tmp2_, "g-object-path", _tmp6_, "g-interface-name", "org.freedesktop.systemd1.Unit", NULL); +#line 846 "/home/lennart/projects/systemd/src/systemadm.vala" + u = (Unit*) _tmp7_; +#line 846 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 846 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 6365 "systemadm.c" + goto __catch8_g_error; + } +#line 851 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = self->priv->unit_model; +#line 851 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = gtk_tree_model_get_iter_first ((GtkTreeModel*) _tmp8_, &_tmp9_); +#line 851 "/home/lennart/projects/systemd/src/systemadm.vala" + iter = _tmp9_; +#line 851 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp10_) { +#line 852 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 852 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 852 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 6382 "systemadm.c" + } +#line 854 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = u; +#line 854 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = unit_get_id (_tmp11_); +#line 854 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = _tmp12_; +#line 854 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 854 "/home/lennart/projects/systemd/src/systemadm.vala" + id = _tmp13_; +#line 6394 "systemadm.c" + { + gboolean _tmp14_; +#line 856 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = TRUE; +#line 856 "/home/lennart/projects/systemd/src/systemadm.vala" + while (TRUE) { +#line 6401 "systemadm.c" + gboolean _tmp15_; + gchar* name = NULL; + GtkListStore* _tmp18_; + GtkTreeIter _tmp19_; + const gchar* _tmp20_; + const gchar* _tmp21_; +#line 856 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = _tmp14_; +#line 856 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp15_) { +#line 6412 "systemadm.c" + GtkListStore* _tmp16_; + gboolean _tmp17_ = FALSE; +#line 870 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = self->priv->unit_model; +#line 870 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = gtk_tree_model_iter_next ((GtkTreeModel*) _tmp16_, &iter); +#line 870 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp17_) { +#line 870 "/home/lennart/projects/systemd/src/systemadm.vala" + break; +#line 6423 "systemadm.c" + } + } +#line 856 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = FALSE; +#line 859 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp18_ = self->priv->unit_model; +#line 859 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp19_ = iter; +#line 859 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_model_get ((GtkTreeModel*) _tmp18_, &_tmp19_, 0, &name, -1); +#line 861 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp20_ = id; +#line 861 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp21_ = name; +#line 861 "/home/lennart/projects/systemd/src/systemadm.vala" + if (g_strcmp0 (_tmp20_, _tmp21_) == 0) { +#line 6440 "systemadm.c" + GtkTreeIter _tmp22_; + const gchar* _tmp23_; + Unit* _tmp24_; + const gchar* _tmp25_; + const gchar* _tmp26_; +#line 862 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp22_ = iter; +#line 862 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp23_ = id; +#line 862 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp24_ = u; +#line 862 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_update_unit_iter (self, &_tmp22_, _tmp23_, _tmp24_); +#line 864 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp25_ = self->priv->current_unit_id; +#line 864 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp26_ = id; +#line 864 "/home/lennart/projects/systemd/src/systemadm.vala" + if (g_strcmp0 (_tmp25_, _tmp26_) == 0) { +#line 6460 "systemadm.c" + Unit* _tmp27_; +#line 865 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp27_ = u; +#line 865 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_unit (self, _tmp27_); +#line 6466 "systemadm.c" + } +#line 867 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (name); +#line 867 "/home/lennart/projects/systemd/src/systemadm.vala" + break; +#line 6472 "systemadm.c" + } +#line 856 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (name); +#line 6476 "systemadm.c" + } + } +#line 842 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 842 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 6483 "systemadm.c" + } + goto __finally8; + __catch8_g_error: + { + GError* e = NULL; + GError* _tmp28_; + const gchar* _tmp29_; +#line 842 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 842 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 873 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp28_ = e; +#line 873 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp29_ = _tmp28_->message; +#line 873 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_error (self, _tmp29_); +#line 842 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 6503 "systemadm.c" + } + __finally8: +#line 842 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 842 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 842 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 842 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 6514 "systemadm.c" + } +} + + +void main_window_on_job_changed (MainWindow* self, Properties* p, const gchar* iface, GHashTable* changed_properties, gchar** invalidated_properties, int invalidated_properties_length1) { + GError * _inner_error_ = NULL; +#line 877 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 877 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (p != NULL); +#line 877 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (iface != NULL); +#line 877 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (changed_properties != NULL); +#line 6529 "systemadm.c" + { + GtkTreeIter iter = {0}; + guint32 id = 0U; + GBusType _tmp0_ = 0; + gboolean _tmp1_; + GBusType _tmp2_; + Properties* _tmp3_; + const gchar* _tmp4_ = NULL; + Properties* _tmp5_; + const gchar* _tmp6_ = NULL; + Job* _tmp7_ = NULL; + Job* j; + GtkListStore* _tmp8_; + GtkTreeIter _tmp9_ = {0}; + gboolean _tmp10_ = FALSE; + Job* _tmp11_; + guint32 _tmp12_; + guint32 _tmp13_; +#line 883 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = user; +#line 883 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp1_) { +#line 883 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = G_BUS_TYPE_SESSION; +#line 6554 "systemadm.c" + } else { +#line 883 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = G_BUS_TYPE_SYSTEM; +#line 6558 "systemadm.c" + } +#line 882 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = _tmp0_; +#line 882 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = p; +#line 882 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = g_dbus_proxy_get_name ((GDBusProxy*) _tmp3_); +#line 882 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = p; +#line 882 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = g_dbus_proxy_get_object_path ((GDBusProxy*) _tmp5_); +#line 882 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = g_initable_new (TYPE_JOB_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", _tmp4_, "g-bus-type", _tmp2_, "g-object-path", _tmp6_, "g-interface-name", "org.freedesktop.systemd1.Job", NULL); +#line 882 "/home/lennart/projects/systemd/src/systemadm.vala" + j = (Job*) _tmp7_; +#line 882 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 6576 "systemadm.c" + goto __catch9_g_error; + } +#line 887 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = self->priv->job_model; +#line 887 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = gtk_tree_model_get_iter_first ((GtkTreeModel*) _tmp8_, &_tmp9_); +#line 887 "/home/lennart/projects/systemd/src/systemadm.vala" + iter = _tmp9_; +#line 887 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp10_) { +#line 888 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (j); +#line 888 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 6591 "systemadm.c" + } +#line 890 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = j; +#line 890 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = job_get_id (_tmp11_); +#line 890 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = _tmp12_; +#line 890 "/home/lennart/projects/systemd/src/systemadm.vala" + id = _tmp13_; +#line 6601 "systemadm.c" + { + gboolean _tmp14_; +#line 892 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = TRUE; +#line 892 "/home/lennart/projects/systemd/src/systemadm.vala" + while (TRUE) { +#line 6608 "systemadm.c" + gboolean _tmp15_; + guint32 k = 0U; + GtkListStore* _tmp18_; + GtkTreeIter _tmp19_; + guint32 _tmp20_; + guint32 _tmp21_; +#line 892 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = _tmp14_; +#line 892 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp15_) { +#line 6619 "systemadm.c" + GtkListStore* _tmp16_; + gboolean _tmp17_ = FALSE; +#line 906 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = self->priv->job_model; +#line 906 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = gtk_tree_model_iter_next ((GtkTreeModel*) _tmp16_, &iter); +#line 906 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp17_) { +#line 906 "/home/lennart/projects/systemd/src/systemadm.vala" + break; +#line 6630 "systemadm.c" + } + } +#line 892 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = FALSE; +#line 895 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp18_ = self->priv->job_model; +#line 895 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp19_ = iter; +#line 895 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_model_get ((GtkTreeModel*) _tmp18_, &_tmp19_, 5, &k, -1); +#line 897 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp20_ = id; +#line 897 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp21_ = k; +#line 897 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp20_ == _tmp21_) { +#line 6647 "systemadm.c" + GtkTreeIter _tmp22_; + guint32 _tmp23_; + Job* _tmp24_; + guint32 _tmp25_; + guint32 _tmp26_; +#line 898 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp22_ = iter; +#line 898 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp23_ = id; +#line 898 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp24_ = j; +#line 898 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_update_job_iter (self, &_tmp22_, _tmp23_, _tmp24_); +#line 900 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp25_ = self->priv->current_job_id; +#line 900 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp26_ = id; +#line 900 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp25_ == _tmp26_) { +#line 6667 "systemadm.c" + Job* _tmp27_; +#line 901 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp27_ = j; +#line 901 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_job (self, _tmp27_); +#line 6673 "systemadm.c" + } +#line 903 "/home/lennart/projects/systemd/src/systemadm.vala" + break; +#line 6677 "systemadm.c" + } + } + } +#line 878 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (j); +#line 6683 "systemadm.c" + } + goto __finally9; + __catch9_g_error: + { + GError* e = NULL; + GError* _tmp28_; + const gchar* _tmp29_; +#line 878 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 878 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 909 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp28_ = e; +#line 909 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp29_ = _tmp28_->message; +#line 909 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_error (self, _tmp29_); +#line 878 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 6703 "systemadm.c" + } + __finally9: +#line 878 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 878 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 878 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 878 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 6714 "systemadm.c" + } +} + + +gboolean main_window_unit_filter (MainWindow* self, GtkTreeModel* model, GtkTreeIter* iter) { + gboolean result = FALSE; + gchar* id = NULL; + gchar* active_state = NULL; + gchar* job = NULL; + GtkTreeModel* _tmp0_; + GtkTreeIter _tmp1_; + const gchar* _tmp2_; + gboolean _tmp3_ = FALSE; + gboolean _tmp4_ = FALSE; + GtkCheckButton* _tmp5_; + gboolean _tmp6_ = FALSE; + gboolean _tmp8_; + gboolean _tmp10_; + GtkComboBox* _tmp11_; + gint _tmp12_ = 0; +#line 913 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_val_if_fail (self != NULL, FALSE); +#line 913 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_val_if_fail (model != NULL, FALSE); +#line 913 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_val_if_fail (iter != NULL, FALSE); +#line 916 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = model; +#line 916 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = *iter; +#line 916 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_model_get (_tmp0_, &_tmp1_, 0, &id, 3, &active_state, 5, &job, -1); +#line 918 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = id; +#line 918 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp2_ == NULL) { +#line 919 "/home/lennart/projects/systemd/src/systemadm.vala" + result = FALSE; +#line 919 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 919 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 919 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 919 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 6761 "systemadm.c" + } +#line 921 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = self->priv->inactive_checkbox; +#line 921 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = gtk_toggle_button_get_active ((GtkToggleButton*) _tmp5_); +#line 921 "/home/lennart/projects/systemd/src/systemadm.vala" + if (!_tmp6_) { +#line 6769 "systemadm.c" + const gchar* _tmp7_; +#line 922 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = active_state; +#line 922 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = g_strcmp0 (_tmp7_, "inactive") == 0; +#line 6775 "systemadm.c" + } else { +#line 921 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = FALSE; +#line 6779 "systemadm.c" + } +#line 921 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = _tmp4_; +#line 921 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp8_) { +#line 6785 "systemadm.c" + const gchar* _tmp9_; +#line 922 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = job; +#line 922 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = g_strcmp0 (_tmp9_, "") == 0; +#line 6791 "systemadm.c" + } else { +#line 921 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = FALSE; +#line 6795 "systemadm.c" + } +#line 921 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = _tmp3_; +#line 921 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp10_) { +#line 923 "/home/lennart/projects/systemd/src/systemadm.vala" + result = FALSE; +#line 923 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 923 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 923 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 923 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 6811 "systemadm.c" + } +#line 925 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = self->priv->unit_type_combo_box; +#line 925 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = gtk_combo_box_get_active (_tmp11_); +#line 925 "/home/lennart/projects/systemd/src/systemadm.vala" + switch (_tmp12_) { +#line 925 "/home/lennart/projects/systemd/src/systemadm.vala" + case 0: +#line 6821 "systemadm.c" + { +#line 927 "/home/lennart/projects/systemd/src/systemadm.vala" + result = TRUE; +#line 927 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 927 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 927 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 927 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 6833 "systemadm.c" + } +#line 925 "/home/lennart/projects/systemd/src/systemadm.vala" + case 1: +#line 6837 "systemadm.c" + { + const gchar* _tmp13_; + gboolean _tmp14_ = FALSE; +#line 929 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = id; +#line 929 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = g_str_has_suffix (_tmp13_, ".target"); +#line 929 "/home/lennart/projects/systemd/src/systemadm.vala" + result = _tmp14_; +#line 929 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 929 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 929 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 929 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 6855 "systemadm.c" + } +#line 925 "/home/lennart/projects/systemd/src/systemadm.vala" + case 2: +#line 6859 "systemadm.c" + { + const gchar* _tmp15_; + gboolean _tmp16_ = FALSE; +#line 931 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = id; +#line 931 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = g_str_has_suffix (_tmp15_, ".service"); +#line 931 "/home/lennart/projects/systemd/src/systemadm.vala" + result = _tmp16_; +#line 931 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 931 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 931 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 931 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 6877 "systemadm.c" + } +#line 925 "/home/lennart/projects/systemd/src/systemadm.vala" + case 3: +#line 6881 "systemadm.c" + { + const gchar* _tmp17_; + gboolean _tmp18_ = FALSE; +#line 933 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = id; +#line 933 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp18_ = g_str_has_suffix (_tmp17_, ".device"); +#line 933 "/home/lennart/projects/systemd/src/systemadm.vala" + result = _tmp18_; +#line 933 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 933 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 933 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 933 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 6899 "systemadm.c" + } +#line 925 "/home/lennart/projects/systemd/src/systemadm.vala" + case 4: +#line 6903 "systemadm.c" + { + const gchar* _tmp19_; + gboolean _tmp20_ = FALSE; +#line 935 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp19_ = id; +#line 935 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp20_ = g_str_has_suffix (_tmp19_, ".mount"); +#line 935 "/home/lennart/projects/systemd/src/systemadm.vala" + result = _tmp20_; +#line 935 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 935 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 935 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 935 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 6921 "systemadm.c" + } +#line 925 "/home/lennart/projects/systemd/src/systemadm.vala" + case 5: +#line 6925 "systemadm.c" + { + const gchar* _tmp21_; + gboolean _tmp22_ = FALSE; +#line 937 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp21_ = id; +#line 937 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp22_ = g_str_has_suffix (_tmp21_, ".automount"); +#line 937 "/home/lennart/projects/systemd/src/systemadm.vala" + result = _tmp22_; +#line 937 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 937 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 937 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 937 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 6943 "systemadm.c" + } +#line 925 "/home/lennart/projects/systemd/src/systemadm.vala" + case 6: +#line 6947 "systemadm.c" + { + const gchar* _tmp23_; + gboolean _tmp24_ = FALSE; +#line 939 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp23_ = id; +#line 939 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp24_ = g_str_has_suffix (_tmp23_, ".swap"); +#line 939 "/home/lennart/projects/systemd/src/systemadm.vala" + result = _tmp24_; +#line 939 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 939 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 939 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 939 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 6965 "systemadm.c" + } +#line 925 "/home/lennart/projects/systemd/src/systemadm.vala" + case 7: +#line 6969 "systemadm.c" + { + const gchar* _tmp25_; + gboolean _tmp26_ = FALSE; +#line 941 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp25_ = id; +#line 941 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp26_ = g_str_has_suffix (_tmp25_, ".socket"); +#line 941 "/home/lennart/projects/systemd/src/systemadm.vala" + result = _tmp26_; +#line 941 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 941 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 941 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 941 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 6987 "systemadm.c" + } +#line 925 "/home/lennart/projects/systemd/src/systemadm.vala" + case 8: +#line 6991 "systemadm.c" + { + const gchar* _tmp27_; + gboolean _tmp28_ = FALSE; +#line 943 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp27_ = id; +#line 943 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp28_ = g_str_has_suffix (_tmp27_, ".path"); +#line 943 "/home/lennart/projects/systemd/src/systemadm.vala" + result = _tmp28_; +#line 943 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 943 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 943 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 943 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 7009 "systemadm.c" + } +#line 925 "/home/lennart/projects/systemd/src/systemadm.vala" + case 9: +#line 7013 "systemadm.c" + { + const gchar* _tmp29_; + gboolean _tmp30_ = FALSE; +#line 945 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp29_ = id; +#line 945 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp30_ = g_str_has_suffix (_tmp29_, ".timer"); +#line 945 "/home/lennart/projects/systemd/src/systemadm.vala" + result = _tmp30_; +#line 945 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 945 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 945 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 945 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 7031 "systemadm.c" + } +#line 925 "/home/lennart/projects/systemd/src/systemadm.vala" + case 10: +#line 7035 "systemadm.c" + { + const gchar* _tmp31_; + gboolean _tmp32_ = FALSE; +#line 947 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp31_ = id; +#line 947 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp32_ = g_str_has_suffix (_tmp31_, ".snapshot"); +#line 947 "/home/lennart/projects/systemd/src/systemadm.vala" + result = _tmp32_; +#line 947 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 947 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 947 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 947 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 7053 "systemadm.c" + } + default: + { +#line 949 "/home/lennart/projects/systemd/src/systemadm.vala" + g_assert (FALSE); +#line 950 "/home/lennart/projects/systemd/src/systemadm.vala" + result = FALSE; +#line 950 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 950 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 950 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 950 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 7069 "systemadm.c" + } + } +#line 913 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (job); +#line 913 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (active_state); +#line 913 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (id); +#line 7078 "systemadm.c" +} + + +void main_window_unit_type_changed (MainWindow* self) { + GtkTreeView* _tmp0_; + GtkTreeModel* _tmp1_ = NULL; + GtkTreeModel* _tmp2_ = NULL; + GtkTreeModelFilter* _tmp3_; + GtkTreeModelFilter* model; +#line 954 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 955 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->unit_view; +#line 955 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = gtk_tree_view_get_model (_tmp0_); +#line 955 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (_tmp1_)); +#line 955 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = _g_object_ref0 (GTK_TREE_MODEL_FILTER (_tmp2_)); +#line 955 "/home/lennart/projects/systemd/src/systemadm.vala" + model = _tmp3_; +#line 957 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_tree_model_filter_refilter (model); +#line 954 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (model); +#line 7104 "systemadm.c" +} + + +void main_window_on_server_reload (MainWindow* self) { + GError * _inner_error_ = NULL; +#line 960 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 7112 "systemadm.c" + { + Manager* _tmp0_; +#line 962 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->manager; +#line 962 "/home/lennart/projects/systemd/src/systemadm.vala" + manager_reload (_tmp0_, &_inner_error_); +#line 962 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 7121 "systemadm.c" + goto __catch10_g_error; + } + } + goto __finally10; + __catch10_g_error: + { + GError* e = NULL; + GError* _tmp1_; + const gchar* _tmp2_; +#line 961 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 961 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 964 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = e; +#line 964 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = _tmp1_->message; +#line 964 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_error (self, _tmp2_); +#line 961 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 7143 "systemadm.c" + } + __finally10: +#line 961 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 961 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 961 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 961 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 7154 "systemadm.c" + } +} + + +void main_window_on_server_snapshot (MainWindow* self) { + GError * _inner_error_ = NULL; +#line 968 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 7163 "systemadm.c" + { + Manager* _tmp0_; + char* _tmp1_ = NULL; + char* _tmp2_; + GtkComboBox* _tmp3_; + gint _tmp4_ = 0; +#line 970 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->manager; +#line 970 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = manager_create_snapshot (_tmp0_, "", FALSE, &_inner_error_); +#line 970 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = _tmp1_; +#line 970 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp2_); +#line 970 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 7180 "systemadm.c" + goto __catch11_g_error; + } +#line 972 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = self->priv->unit_type_combo_box; +#line 972 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = gtk_combo_box_get_active (_tmp3_); +#line 972 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp4_ != 0) { +#line 7189 "systemadm.c" + GtkComboBox* _tmp5_; +#line 973 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = self->priv->unit_type_combo_box; +#line 973 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_combo_box_set_active (_tmp5_, 8); +#line 7195 "systemadm.c" + } + } + goto __finally11; + __catch11_g_error: + { + GError* e = NULL; + GError* _tmp6_; + const gchar* _tmp7_; +#line 969 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 969 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 976 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = e; +#line 976 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = _tmp6_->message; +#line 976 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_error (self, _tmp7_); +#line 969 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 7216 "systemadm.c" + } + __finally11: +#line 969 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 969 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 969 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 969 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 7227 "systemadm.c" + } +} + + +void main_window_on_unit_load (MainWindow* self) { + GtkEntry* _tmp0_; + const gchar* _tmp1_ = NULL; + gchar* _tmp2_; + gchar* t; + const gchar* _tmp3_; + GError * _inner_error_ = NULL; +#line 980 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 981 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->unit_load_entry; +#line 981 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = gtk_entry_get_text (_tmp0_); +#line 981 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = g_strdup (_tmp1_); +#line 981 "/home/lennart/projects/systemd/src/systemadm.vala" + t = _tmp2_; +#line 983 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = t; +#line 983 "/home/lennart/projects/systemd/src/systemadm.vala" + if (g_strcmp0 (_tmp3_, "") == 0) { +#line 984 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (t); +#line 984 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 7257 "systemadm.c" + } + { + Manager* _tmp4_; + const gchar* _tmp5_; + char* _tmp6_ = NULL; + char* path; + GBusType _tmp7_ = 0; + gboolean _tmp8_; + GBusType _tmp9_; + const char* _tmp10_; + Unit* _tmp11_ = NULL; + Unit* u; + Unit* _tmp12_; + gchar* _tmp13_; + gchar* _tmp14_; + gchar* _tmp15_; + GtkMessageDialog* _tmp16_; + GtkMessageDialog* _tmp17_; + GtkMessageDialog* _tmp18_; + GtkMessageDialog* m; + GtkMessageDialog* _tmp19_; + GtkMessageDialog* _tmp20_; + GtkMessageDialog* _tmp21_; + Unit* _tmp22_; +#line 987 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = self->priv->manager; +#line 987 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = t; +#line 987 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = manager_load_unit (_tmp4_, _tmp5_, &_inner_error_); +#line 987 "/home/lennart/projects/systemd/src/systemadm.vala" + path = _tmp6_; +#line 987 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 7292 "systemadm.c" + goto __catch12_g_error; + } +#line 990 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = user; +#line 990 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp8_) { +#line 990 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = G_BUS_TYPE_SESSION; +#line 7301 "systemadm.c" + } else { +#line 990 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = G_BUS_TYPE_SYSTEM; +#line 7305 "systemadm.c" + } +#line 989 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = _tmp7_; +#line 989 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = path; +#line 989 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp11_ = g_initable_new (TYPE_UNIT_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.freedesktop.systemd1", "g-bus-type", _tmp9_, "g-object-path", (const gchar*) _tmp10_, "g-interface-name", "org.freedesktop.systemd1.Unit", NULL); +#line 989 "/home/lennart/projects/systemd/src/systemadm.vala" + u = (Unit*) _tmp11_; +#line 989 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 989 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (path); +#line 7319 "systemadm.c" + goto __catch12_g_error; + } +#line 994 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp12_ = u; +#line 994 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp13_ = unit_get_id (_tmp12_); +#line 994 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp14_ = _tmp13_; +#line 994 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp15_ = _tmp14_; +#line 994 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp16_ = (GtkMessageDialog*) gtk_message_dialog_new ((GtkWindow*) self, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "Unit available as id %s", _tmp15_); +#line 994 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp17_ = g_object_ref_sink (_tmp16_); +#line 994 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp18_ = _tmp17_; +#line 994 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (_tmp15_); +#line 994 "/home/lennart/projects/systemd/src/systemadm.vala" + m = _tmp18_; +#line 999 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp19_ = m; +#line 999 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_window_set_title ((GtkWindow*) _tmp19_, "Unit"); +#line 1000 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp20_ = m; +#line 1000 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_dialog_run ((GtkDialog*) _tmp20_); +#line 1001 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp21_ = m; +#line 1001 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_object_destroy ((GtkObject*) _tmp21_); +#line 1003 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp22_ = u; +#line 1003 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_unit (self, _tmp22_); +#line 986 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (m); +#line 986 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 986 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (path); +#line 7362 "systemadm.c" + } + goto __finally12; + __catch12_g_error: + { + GError* e = NULL; + GError* _tmp23_; + const gchar* _tmp24_; +#line 986 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 986 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 1005 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp23_ = e; +#line 1005 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp24_ = _tmp23_->message; +#line 1005 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_error (self, _tmp24_); +#line 986 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 7382 "systemadm.c" + } + __finally12: +#line 986 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 986 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (t); +#line 986 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 986 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 986 "/home/lennart/projects/systemd/src/systemadm.vala" + return; +#line 7395 "systemadm.c" + } +#line 980 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (t); +#line 7399 "systemadm.c" +} + + +void main_window_on_unit_load_entry_changed (MainWindow* self) { + GtkButton* _tmp0_; + GtkEntry* _tmp1_; + const gchar* _tmp2_ = NULL; +#line 1009 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 1010 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->unit_load_button; +#line 1010 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = self->priv->unit_load_entry; +#line 1010 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = gtk_entry_get_text (_tmp1_); +#line 1010 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_widget_set_sensitive ((GtkWidget*) _tmp0_, g_strcmp0 (_tmp2_, "") != 0); +#line 7417 "systemadm.c" +} + + +gboolean main_window_on_activate_link (MainWindow* self, const gchar* uri) { + gboolean result = FALSE; + GError * _inner_error_ = NULL; +#line 1013 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_val_if_fail (self != NULL, FALSE); +#line 1013 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_val_if_fail (uri != NULL, FALSE); +#line 7428 "systemadm.c" + { + Manager* _tmp0_; + const gchar* _tmp1_; + char* _tmp2_ = NULL; + gchar* path; + GBusType _tmp3_ = 0; + gboolean _tmp4_; + GBusType _tmp5_; + const gchar* _tmp6_; + Unit* _tmp7_ = NULL; + Unit* u; + Unit* _tmp8_; +#line 1016 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = self->priv->manager; +#line 1016 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = uri; +#line 1016 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = manager_get_unit (_tmp0_, _tmp1_, &_inner_error_); +#line 1016 "/home/lennart/projects/systemd/src/systemadm.vala" + path = (gchar*) _tmp2_; +#line 1016 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 7451 "systemadm.c" + goto __catch13_g_error; + } +#line 1019 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = user; +#line 1019 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_tmp4_) { +#line 1019 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = G_BUS_TYPE_SESSION; +#line 7460 "systemadm.c" + } else { +#line 1019 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = G_BUS_TYPE_SYSTEM; +#line 7464 "systemadm.c" + } +#line 1018 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = _tmp3_; +#line 1018 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = path; +#line 1018 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = g_initable_new (TYPE_UNIT_PROXY, NULL, &_inner_error_, "g-flags", 0, "g-name", "org.freedesktop.systemd1", "g-bus-type", _tmp5_, "g-object-path", _tmp6_, "g-interface-name", "org.freedesktop.systemd1.Unit", NULL); +#line 1018 "/home/lennart/projects/systemd/src/systemadm.vala" + u = (Unit*) _tmp7_; +#line 1018 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 1018 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (path); +#line 7478 "systemadm.c" + goto __catch13_g_error; + } +#line 1023 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp8_ = u; +#line 1023 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_unit (self, _tmp8_); +#line 1015 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (u); +#line 1015 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (path); +#line 7489 "systemadm.c" + } + goto __finally13; + __catch13_g_error: + { + GError* e = NULL; + GError* _tmp9_; + const gchar* _tmp10_; +#line 1015 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 1015 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 1025 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp9_ = e; +#line 1025 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp10_ = _tmp9_->message; +#line 1025 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_show_error (self, _tmp10_); +#line 1015 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 7509 "systemadm.c" + } + __finally13: +#line 1015 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 1015 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 1015 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 1015 "/home/lennart/projects/systemd/src/systemadm.vala" + return FALSE; +#line 7520 "systemadm.c" + } +#line 1028 "/home/lennart/projects/systemd/src/systemadm.vala" + result = TRUE; +#line 1028 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 7526 "systemadm.c" +} + + +void main_window_show_error (MainWindow* self, const gchar* e) { + const gchar* _tmp0_; + GtkMessageDialog* _tmp1_; + GtkMessageDialog* _tmp2_; + GtkMessageDialog* m; +#line 1031 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (self != NULL); +#line 1031 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (e != NULL); +#line 1032 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = e; +#line 1032 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = (GtkMessageDialog*) gtk_message_dialog_new ((GtkWindow*) self, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", _tmp0_); +#line 1032 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = g_object_ref_sink (_tmp1_); +#line 1032 "/home/lennart/projects/systemd/src/systemadm.vala" + m = _tmp2_; +#line 1036 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_window_set_title ((GtkWindow*) m, "Error"); +#line 1037 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_dialog_run ((GtkDialog*) m); +#line 1038 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_object_destroy ((GtkObject*) m); +#line 1031 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (m); +#line 7555 "systemadm.c" +} + + +static void main_window_class_init (MainWindowClass * klass) { +#line 71 "/home/lennart/projects/systemd/src/systemadm.vala" + main_window_parent_class = g_type_class_peek_parent (klass); +#line 71 "/home/lennart/projects/systemd/src/systemadm.vala" + g_type_class_add_private (klass, sizeof (MainWindowPrivate)); +#line 71 "/home/lennart/projects/systemd/src/systemadm.vala" + G_OBJECT_CLASS (klass)->finalize = main_window_finalize; +#line 7566 "systemadm.c" +} + + +static void main_window_instance_init (MainWindow * self) { +#line 71 "/home/lennart/projects/systemd/src/systemadm.vala" + self->priv = MAIN_WINDOW_GET_PRIVATE (self); +#line 7573 "systemadm.c" +} + + +static void main_window_finalize (GObject* obj) { + MainWindow * self; +#line 71 "/home/lennart/projects/systemd/src/systemadm.vala" + self = MAIN_WINDOW (obj); +#line 73 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_free0 (self->priv->current_unit_id); +#line 76 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_view); +#line 77 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->job_view); +#line 79 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_model); +#line 80 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->job_model); +#line 82 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_map); +#line 84 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->start_button); +#line 85 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->stop_button); +#line 86 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->restart_button); +#line 87 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->reload_button); +#line 88 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->cancel_button); +#line 90 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_load_entry); +#line 91 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_load_button); +#line 93 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->server_snapshot_button); +#line 94 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->server_reload_button); +#line 96 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->manager); +#line 98 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_id_label); +#line 99 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_dependency_label); +#line 100 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_description_label); +#line 101 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_load_state_label); +#line 102 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_active_state_label); +#line 103 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_sub_state_label); +#line 104 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_fragment_path_label); +#line 105 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_active_enter_timestamp_label); +#line 106 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_active_exit_timestamp_label); +#line 107 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_can_start_label); +#line 108 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_can_reload_label); +#line 109 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_cgroup_label); +#line 111 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->job_id_label); +#line 112 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->job_state_label); +#line 113 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->job_type_label); +#line 115 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->unit_type_combo_box); +#line 116 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (self->priv->inactive_checkbox); +#line 71 "/home/lennart/projects/systemd/src/systemadm.vala" + G_OBJECT_CLASS (main_window_parent_class)->finalize (obj); +#line 7649 "systemadm.c" +} + + +GType main_window_get_type (void) { + static volatile gsize main_window_type_id__volatile = 0; + if (g_once_init_enter (&main_window_type_id__volatile)) { + static const GTypeInfo g_define_type_info = { sizeof (MainWindowClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) main_window_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (MainWindow), 0, (GInstanceInitFunc) main_window_instance_init, NULL }; + GType main_window_type_id; + main_window_type_id = g_type_register_static (GTK_TYPE_WINDOW, "MainWindow", &g_define_type_info, 0); + g_once_init_leave (&main_window_type_id__volatile, main_window_type_id); + } + return main_window_type_id__volatile; +} + + +void show_error (const gchar* e) { + const gchar* _tmp0_; + GtkMessageDialog* _tmp1_; + GtkMessageDialog* _tmp2_; + GtkMessageDialog* m; +#line 1049 "/home/lennart/projects/systemd/src/systemadm.vala" + g_return_if_fail (e != NULL); +#line 1050 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = e; +#line 1050 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = (GtkMessageDialog*) gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", _tmp0_); +#line 1050 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = g_object_ref_sink (_tmp1_); +#line 1050 "/home/lennart/projects/systemd/src/systemadm.vala" + m = _tmp2_; +#line 1051 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_dialog_run ((GtkDialog*) m); +#line 1052 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_object_destroy ((GtkObject*) m); +#line 1049 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (m); +#line 7686 "systemadm.c" +} + + +gint _vala_main (gchar** args, int args_length1) { + gint result = 0; + GError * _inner_error_ = NULL; + { + MainWindow* _tmp0_; + MainWindow* _tmp1_; + MainWindow* window; + MainWindow* _tmp2_; +#line 1058 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_init_with_args (&args_length1, &args, "[OPTION...]", entries, "systemadm", &_inner_error_); +#line 1058 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 1058 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_->domain == G_IO_ERROR) { +#line 7704 "systemadm.c" + goto __catch14_g_io_error; + } + goto __catch14_g_error; + } +#line 1060 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp0_ = main_window_new (&_inner_error_); +#line 1060 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp1_ = g_object_ref_sink (_tmp0_); +#line 1060 "/home/lennart/projects/systemd/src/systemadm.vala" + window = _tmp1_; +#line 1060 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 1060 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_->domain == G_IO_ERROR) { +#line 7719 "systemadm.c" + goto __catch14_g_io_error; + } + goto __catch14_g_error; + } +#line 1061 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp2_ = window; +#line 1061 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_widget_show_all ((GtkWidget*) _tmp2_); +#line 1063 "/home/lennart/projects/systemd/src/systemadm.vala" + gtk_main (); +#line 1057 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_object_unref0 (window); +#line 7732 "systemadm.c" + } + goto __finally14; + __catch14_g_io_error: + { + GError* e = NULL; + GError* _tmp3_; + const gchar* _tmp4_; +#line 1057 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 1057 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 1065 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp3_ = e; +#line 1065 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp4_ = _tmp3_->message; +#line 1065 "/home/lennart/projects/systemd/src/systemadm.vala" + show_error (_tmp4_); +#line 1057 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 7752 "systemadm.c" + } + goto __finally14; + __catch14_g_error: + { + GError* e = NULL; + FILE* _tmp5_; + GError* _tmp6_; + const gchar* _tmp7_; +#line 1057 "/home/lennart/projects/systemd/src/systemadm.vala" + e = _inner_error_; +#line 1057 "/home/lennart/projects/systemd/src/systemadm.vala" + _inner_error_ = NULL; +#line 1067 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp5_ = stderr; +#line 1067 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp6_ = e; +#line 1067 "/home/lennart/projects/systemd/src/systemadm.vala" + _tmp7_ = _tmp6_->message; +#line 1067 "/home/lennart/projects/systemd/src/systemadm.vala" + fprintf (_tmp5_, "%s\n", _tmp7_); +#line 1057 "/home/lennart/projects/systemd/src/systemadm.vala" + _g_error_free0 (e); +#line 7775 "systemadm.c" + } + __finally14: +#line 1057 "/home/lennart/projects/systemd/src/systemadm.vala" + if (_inner_error_ != NULL) { +#line 1057 "/home/lennart/projects/systemd/src/systemadm.vala" + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); +#line 1057 "/home/lennart/projects/systemd/src/systemadm.vala" + g_clear_error (&_inner_error_); +#line 1057 "/home/lennart/projects/systemd/src/systemadm.vala" + return 0; +#line 7786 "systemadm.c" + } +#line 1070 "/home/lennart/projects/systemd/src/systemadm.vala" + result = 0; +#line 1070 "/home/lennart/projects/systemd/src/systemadm.vala" + return result; +#line 7792 "systemadm.c" +} + + +int main (int argc, char ** argv) { +#line 1055 "/home/lennart/projects/systemd/src/systemadm.vala" + g_type_init (); +#line 1055 "/home/lennart/projects/systemd/src/systemadm.vala" + return _vala_main (argv, argc); +#line 7801 "systemadm.c" +} + + +static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) { + if ((array != NULL) && (destroy_func != NULL)) { + int i; + for (i = 0; i < array_length; i = i + 1) { + if (((gpointer*) array)[i] != NULL) { + destroy_func (((gpointer*) array)[i]); + } + } + } +} + + +static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) { + _vala_array_destroy (array, array_length, destroy_func); + g_free (array); +} + + + diff --git a/src/systemadm.vala b/src/systemadm.vala new file mode 100644 index 0000000..5971ac0 --- /dev/null +++ b/src/systemadm.vala @@ -0,0 +1,1071 @@ +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +using Gtk; +using GLib; +using Pango; + +static bool user = false; + +public string format_time(uint64 time_ns) { + if (time_ns <= 0) + return ""; + Time timestamp = Time.local((time_t) (time_ns / 1000000)); + return timestamp.format("%a, %d %b %Y %H:%M:%S"); +} + +public void new_column(TreeView view, int column_id, string title) { + TreeViewColumn col; + col = new TreeViewColumn.with_attributes(title, new CellRendererText(), "text", column_id); + col.set_sort_column_id(column_id); + view.insert_column(col, -1); +} + +public class LeftLabel : Label { + public LeftLabel(string? text = null) { + if (text != null) + set_markup("%s".printf(text)); + set_alignment(0, 0); + set_padding(6, 0); + } +} + +public class RightLabel : WrapLabel { + + public RightLabel(string? text = null) { + set_selectable(true); + set_text_or_na(text); + } + + public void set_text_or_na(string? text = null) { + if (text == null || text == "") + set_markup("n/a"); + else + set_text(text); + } + + public void set_markup_or_na(string? text = null) { + if (text == null || text == "") + set_markup("n/a"); + else + set_markup(text); + } +} + +public class MainWindow : Window { + + private string? current_unit_id; + private uint32 current_job_id; + + private TreeView unit_view; + private TreeView job_view; + + private ListStore unit_model; + private ListStore job_model; + + private Gee.HashMap unit_map; + + private Button start_button; + private Button stop_button; + private Button restart_button; + private Button reload_button; + private Button cancel_button; + + private Entry unit_load_entry; + private Button unit_load_button; + + private Button server_snapshot_button; + private Button server_reload_button; + + private Manager manager; + + private RightLabel unit_id_label; + private RightLabel unit_dependency_label; + private RightLabel unit_description_label; + private RightLabel unit_load_state_label; + private RightLabel unit_active_state_label; + private RightLabel unit_sub_state_label; + private RightLabel unit_fragment_path_label; + private RightLabel unit_active_enter_timestamp_label; + private RightLabel unit_active_exit_timestamp_label; + private RightLabel unit_can_start_label; + private RightLabel unit_can_reload_label; + private RightLabel unit_cgroup_label; + + private RightLabel job_id_label; + private RightLabel job_state_label; + private RightLabel job_type_label; + + private ComboBox unit_type_combo_box; + private CheckButton inactive_checkbox; + + public MainWindow() throws IOError { + title = user ? "systemd User Service Manager" : "systemd System Manager"; + set_position(WindowPosition.CENTER); + set_default_size(1000, 700); + set_border_width(12); + destroy.connect(Gtk.main_quit); + + Notebook notebook = new Notebook(); + add(notebook); + + Box unit_vbox = new VBox(false, 12); + notebook.append_page(unit_vbox, new Label("Units")); + unit_vbox.set_border_width(12); + + Box job_vbox = new VBox(false, 12); + notebook.append_page(job_vbox, new Label("Jobs")); + job_vbox.set_border_width(12); + + unit_type_combo_box = new ComboBox.text(); + Box type_hbox = new HBox(false, 6); + type_hbox.pack_start(unit_type_combo_box, false, false, 0); + unit_vbox.pack_start(type_hbox, false, false, 0); + + unit_type_combo_box.append_text("All unit types"); + unit_type_combo_box.append_text("Targets"); + unit_type_combo_box.append_text("Services"); + unit_type_combo_box.append_text("Devices"); + unit_type_combo_box.append_text("Mounts"); + unit_type_combo_box.append_text("Automounts"); + unit_type_combo_box.append_text("Swaps"); + unit_type_combo_box.append_text("Sockets"); + unit_type_combo_box.append_text("Paths"); + unit_type_combo_box.append_text("Timers"); + unit_type_combo_box.append_text("Snapshots"); + unit_type_combo_box.set_active(0); // Show All + unit_type_combo_box.changed.connect(unit_type_changed); + + inactive_checkbox = new CheckButton.with_label("inactive too"); + inactive_checkbox.toggled.connect(unit_type_changed); + type_hbox.pack_start(inactive_checkbox, false, false, 0); + + unit_load_entry = new Entry(); + unit_load_button = new Button.with_mnemonic("_Load"); + unit_load_button.set_sensitive(false); + + unit_load_entry.changed.connect(on_unit_load_entry_changed); + unit_load_entry.activate.connect(on_unit_load); + unit_load_button.clicked.connect(on_unit_load); + + Box unit_load_hbox = new HBox(false, 6); + unit_load_hbox.pack_start(unit_load_entry, false, true, 0); + unit_load_hbox.pack_start(unit_load_button, false, true, 0); + + server_snapshot_button = new Button.with_mnemonic("Take S_napshot"); + server_reload_button = new Button.with_mnemonic("Reload _Configuration"); + + server_snapshot_button.clicked.connect(on_server_snapshot); + server_reload_button.clicked.connect(on_server_reload); + + type_hbox.pack_end(server_snapshot_button, false, true, 0); + type_hbox.pack_end(server_reload_button, false, true, 0); + type_hbox.pack_end(unit_load_hbox, false, true, 24); + + unit_model = new ListStore(7, typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(Unit)); + job_model = new ListStore(6, typeof(string), typeof(string), typeof(string), typeof(string), typeof(Job), typeof(uint32)); + + unit_map = new Gee.HashMap(); + + TreeModelFilter unit_model_filter; + unit_model_filter = new TreeModelFilter(unit_model, null); + unit_model_filter.set_visible_func(unit_filter); + + TreeModelSort unit_model_sort = new TreeModelSort.with_model(unit_model_filter); + + unit_view = new TreeView.with_model(unit_model_sort); + job_view = new TreeView.with_model(job_model); + + unit_view.cursor_changed.connect(unit_changed); + job_view.cursor_changed.connect(job_changed); + + new_column(unit_view, 2, "Load State"); + new_column(unit_view, 3, "Active State"); + new_column(unit_view, 4, "Unit State"); + new_column(unit_view, 0, "Unit"); + new_column(unit_view, 5, "Job"); + + new_column(job_view, 0, "Job"); + new_column(job_view, 1, "Unit"); + new_column(job_view, 2, "Type"); + new_column(job_view, 3, "State"); + + ScrolledWindow scroll = new ScrolledWindow(null, null); + scroll.set_policy(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC); + scroll.set_shadow_type(ShadowType.IN); + scroll.add(unit_view); + unit_vbox.pack_start(scroll, true, true, 0); + + scroll = new ScrolledWindow(null, null); + scroll.set_policy(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC); + scroll.set_shadow_type(ShadowType.IN); + scroll.add(job_view); + job_vbox.pack_start(scroll, true, true, 0); + + unit_id_label = new RightLabel(); + unit_dependency_label = new RightLabel(); + unit_description_label = new RightLabel(); + unit_load_state_label = new RightLabel(); + unit_active_state_label = new RightLabel(); + unit_sub_state_label = new RightLabel(); + unit_fragment_path_label = new RightLabel(); + unit_active_enter_timestamp_label = new RightLabel(); + unit_active_exit_timestamp_label = new RightLabel(); + unit_can_start_label = new RightLabel(); + unit_can_reload_label = new RightLabel(); + unit_cgroup_label = new RightLabel(); + + job_id_label = new RightLabel(); + job_state_label = new RightLabel(); + job_type_label = new RightLabel(); + + unit_dependency_label.set_track_visited_links(false); + unit_dependency_label.set_selectable(true); + unit_dependency_label.activate_link.connect(on_activate_link); + + unit_fragment_path_label.set_track_visited_links(false); + + Table unit_table = new Table(8, 6, false); + unit_table.set_row_spacings(6); + unit_table.set_border_width(0); + unit_vbox.pack_start(unit_table, false, true, 0); + + Table job_table = new Table(2, 2, false); + job_table.set_row_spacings(6); + job_table.set_border_width(0); + job_vbox.pack_start(job_table, false, true, 0); + + unit_table.attach(new LeftLabel("Id:"), 0, 1, 0, 1, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_id_label, 1, 6, 0, 1, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Description:"), 0, 1, 1, 2, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_description_label, 1, 6, 1, 2, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Dependencies:"), 0, 1, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_dependency_label, 1, 6, 2, 3, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Fragment Path:"), 0, 1, 3, 4, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_fragment_path_label, 1, 6, 3, 4, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Control Group:"), 0, 1, 4, 5, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_cgroup_label, 1, 6, 4, 5, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + + unit_table.attach(new LeftLabel("Load State:"), 0, 1, 5, 6, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_load_state_label, 1, 2, 5, 6, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Active State:"), 0, 1, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_active_state_label, 1, 2, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Unit State:"), 0, 1, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_sub_state_label, 1, 2, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + + unit_table.attach(new LeftLabel("Activated:"), 2, 3, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_active_enter_timestamp_label, 3, 4, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Deactivated:"), 2, 3, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_active_exit_timestamp_label, 3, 4, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + + unit_table.attach(new LeftLabel("Can Start/Stop:"), 4, 5, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_can_start_label, 5, 6, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(new LeftLabel("Can Reload:"), 4, 5, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + unit_table.attach(unit_can_reload_label, 5, 6, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + + job_table.attach(new LeftLabel("Id:"), 0, 1, 0, 1, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + job_table.attach(job_id_label, 1, 2, 0, 1, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + job_table.attach(new LeftLabel("State:"), 0, 1, 1, 2, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + job_table.attach(job_state_label, 1, 2, 1, 2, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + job_table.attach(new LeftLabel("Type:"), 0, 1, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0); + job_table.attach(job_type_label, 1, 2, 2, 3, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0); + + ButtonBox bbox = new HButtonBox(); + bbox.set_layout(ButtonBoxStyle.START); + bbox.set_spacing(6); + unit_vbox.pack_start(bbox, false, true, 0); + + start_button = new Button.with_mnemonic("_Start"); + stop_button = new Button.with_mnemonic("Sto_p"); + reload_button = new Button.with_mnemonic("_Reload"); + restart_button = new Button.with_mnemonic("Res_tart"); + + start_button.clicked.connect(on_start); + stop_button.clicked.connect(on_stop); + reload_button.clicked.connect(on_reload); + restart_button.clicked.connect(on_restart); + + bbox.pack_start(start_button, false, true, 0); + bbox.pack_start(stop_button, false, true, 0); + bbox.pack_start(restart_button, false, true, 0); + bbox.pack_start(reload_button, false, true, 0); + + bbox = new HButtonBox(); + bbox.set_layout(ButtonBoxStyle.START); + bbox.set_spacing(6); + job_vbox.pack_start(bbox, false, true, 0); + + cancel_button = new Button.with_mnemonic("_Cancel"); + + cancel_button.clicked.connect(on_cancel); + + bbox.pack_start(cancel_button, false, true, 0); + + manager = Bus.get_proxy_sync( + user ? BusType.SESSION : BusType.SYSTEM, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1"); + + manager.unit_new.connect(on_unit_new); + manager.job_new.connect(on_job_new); + manager.unit_removed.connect(on_unit_removed); + manager.job_removed.connect(on_job_removed); + + manager.subscribe(); + + clear_unit(); + clear_job(); + populate_unit_model(); + populate_job_model(); + } + + public void populate_unit_model() throws IOError { + unit_model.clear(); + + var list = manager.list_units(); + + foreach (var i in list) { + TreeIter iter; + + Properties p = Bus.get_proxy_sync( + user ? BusType.SESSION : BusType.SYSTEM, + "org.freedesktop.systemd1", + i.unit_path); + + p.properties_changed.connect(on_unit_changed); + + Unit u = Bus.get_proxy_sync( + user ? BusType.SESSION : BusType.SYSTEM, + "org.freedesktop.systemd1", + i.unit_path); + + unit_map[i.id] = u; + + unit_model.append(out iter); + unit_model.set(iter, + 0, i.id, + 1, i.description, + 2, i.load_state, + 3, i.active_state, + 4, i.sub_state, + 5, i.job_type != "" ? "→ %s".printf(i.job_type) : "", + 6, u); + } + } + + public void populate_job_model() throws IOError { + job_model.clear(); + + var list = manager.list_jobs(); + + foreach (var i in list) { + TreeIter iter; + + Properties p = Bus.get_proxy_sync( + user ? BusType.SESSION : BusType.SYSTEM, + "org.freedesktop.systemd1", + i.job_path); + + p.properties_changed.connect(on_job_changed); + + Job j = Bus.get_proxy_sync( + user ? BusType.SESSION : BusType.SYSTEM, + "org.freedesktop.systemd1", + i.job_path); + + job_model.append(out iter); + job_model.set(iter, + 0, "%u".printf(i.id), + 1, i.name, + 2, "→ %s".printf(i.type), + 3, i.state, + 4, j, + 5, i.id); + } + } + + public Unit? get_current_unit() { + TreePath p; + unit_view.get_cursor(out p, null); + + if (p == null) + return null; + + TreeModel model = unit_view.get_model(); + TreeIter iter; + Unit u; + + model.get_iter(out iter, p); + model.get(iter, 6, out u); + + return u; + } + + public Unit? get_unit(string id) { + return this.unit_map[id]; + } + + public void unit_changed() { + Unit u = get_current_unit(); + + if (u == null) + clear_unit(); + else + show_unit(u); + } + + public void clear_unit() { + current_unit_id = null; + + start_button.set_sensitive(false); + stop_button.set_sensitive(false); + reload_button.set_sensitive(false); + restart_button.set_sensitive(false); + + unit_id_label.set_text_or_na(); + unit_description_label.set_text_or_na(); + unit_description_label.set_text_or_na(); + unit_load_state_label.set_text_or_na(); + unit_active_state_label.set_text_or_na(); + unit_sub_state_label.set_text_or_na(); + unit_fragment_path_label.set_text_or_na(); + unit_active_enter_timestamp_label.set_text_or_na(); + unit_active_exit_timestamp_label.set_text_or_na(); + unit_can_reload_label.set_text_or_na(); + unit_can_start_label.set_text_or_na(); + unit_cgroup_label.set_text_or_na(); + } + + public string format_unit_link(string i, bool link) { + Unit? u = get_unit(i); + if(u == null) + return "" + i + "" + + i + "(" + + u.sub_state + ")" + ""; + if(link) + return " " + span + ""; + else + return span; + } + + + public string make_dependency_string(string? prefix, string word, string[] dependencies) { + Gee.Collection sorted = new Gee.TreeSet(); + foreach (string i in dependencies) + sorted.add(i); + + bool first = true; + string r; + + if (prefix == null) + r = ""; + else + r = prefix; + + foreach (string i in sorted) { + if (r != "") + r += first ? "\n" : ","; + + if (first) { + r += "" + word + ":"; + first = false; + } + + r += format_unit_link(i, true); + } + + return r; + } + + public void show_unit(Unit unit) { + current_unit_id = unit.id; + + string id_display = format_unit_link(current_unit_id, false); + bool has_alias = false; + foreach (string i in unit.names) { + if (i == current_unit_id) + continue; + + if (!has_alias) { + id_display += " (aliases:"; + has_alias = true; + } + + id_display += " " + i; + } + if(has_alias) + id_display += ")"; + + unit_id_label.set_markup_or_na(id_display); + + string[] + requires = unit.requires, + requires_overridable = unit.requires_overridable, + requisite = unit.requisite, + requisite_overridable = unit.requisite_overridable, + wants = unit.wants, + required_by = unit.required_by, + required_by_overridable = unit.required_by_overridable, + wanted_by = unit.wanted_by, + conflicts = unit.conflicts, + before = unit.before, + after = unit.after; + + unit_dependency_label.set_markup_or_na( + make_dependency_string( + make_dependency_string( + make_dependency_string( + make_dependency_string( + make_dependency_string( + make_dependency_string( + make_dependency_string( + make_dependency_string( + make_dependency_string( + make_dependency_string( + make_dependency_string(null, + "requires", requires), + "overridable requires", requires_overridable), + "requisite", requisite), + "overridable requisite", requisite_overridable), + "wants", wants), + "conflicts", conflicts), + "required by", required_by), + "overridable required by", required_by_overridable), + "wanted by", wanted_by), + "after", after), + "before", before)); + + unit_description_label.set_text_or_na(unit.description); + unit_load_state_label.set_text_or_na(unit.load_state); + unit_active_state_label.set_text_or_na(unit.active_state); + unit_sub_state_label.set_text_or_na(unit.sub_state); + + string fp = unit.fragment_path; + if (fp != "") + unit_fragment_path_label.set_markup_or_na( + "" + + "" + fp + ""); + else + unit_fragment_path_label.set_text_or_na(); + + + unit_active_enter_timestamp_label.set_text_or_na(format_time(unit.active_enter_timestamp)); + + unit_active_exit_timestamp_label.set_text_or_na(format_time(unit.active_exit_timestamp)); + + bool b = unit.can_start; + start_button.set_sensitive(b); + stop_button.set_sensitive(b); + restart_button.set_sensitive(b); + unit_can_start_label.set_text_or_na(b ? "Yes" : "No"); + + b = unit.can_reload; + reload_button.set_sensitive(b); + unit_can_reload_label.set_text_or_na(b ? "Yes" : "No"); + + unit_cgroup_label.set_text_or_na(unit.default_control_group); + } + + public Job? get_current_job() { + TreePath p; + job_view.get_cursor(out p, null); + + if (p == null) + return null; + + TreeIter iter; + TreeModel model = job_view.get_model(); + Job *j; + + model.get_iter(out iter, p); + model.get(iter, 4, out j); + + return j; + } + + public void job_changed() { + Job j = get_current_job(); + + if (j == null) + clear_job(); + else + show_job(j); + } + + public void clear_job() { + current_job_id = 0; + + job_id_label.set_text_or_na(); + job_state_label.set_text_or_na(); + job_type_label.set_text_or_na(); + + cancel_button.set_sensitive(false); + } + + public void show_job(Job job) { + current_job_id = job.id; + + job_id_label.set_text_or_na("%u".printf(current_job_id)); + job_state_label.set_text_or_na(job.state); + job_type_label.set_text_or_na(job.job_type); + + cancel_button.set_sensitive(true); + } + + public void on_start() { + Unit u = get_current_unit(); + + if (u == null) + return; + + try { + u.start("replace"); + } catch (Error e) { + show_error(e.message); + } + } + + public void on_stop() { + Unit u = get_current_unit(); + + if (u == null) + return; + + try { + u.stop("replace"); + } catch (Error e) { + show_error(e.message); + } + } + + public void on_reload() { + Unit u = get_current_unit(); + + if (u == null) + return; + + try { + u.reload("replace"); + } catch (Error e) { + show_error(e.message); + } + } + + public void on_restart() { + Unit u = get_current_unit(); + + if (u == null) + return; + + try { + u.restart("replace"); + } catch (Error e) { + show_error(e.message); + } + } + + public void on_cancel() { + Job j = get_current_job(); + + if (j == null) + return; + + try { + j.cancel(); + } catch (Error e) { + show_error(e.message); + } + } + + public void update_unit_iter(TreeIter iter, string id, Unit u) { + + try { + string t = ""; + Unit.JobLink jl = u.job; + + if (jl.id != 0) { + Job j = Bus.get_proxy_sync( + user ? BusType.SESSION : BusType.SYSTEM, + "org.freedesktop.systemd1", + jl.path); + + t = j.job_type; + } + + unit_model.set(iter, + 0, id, + 1, u.description, + 2, u.load_state, + 3, u.active_state, + 4, u.sub_state, + 5, t != "" ? "→ %s".printf(t) : "", + 6, u); + } catch (Error e) { + show_error(e.message); + } + } + + public void on_unit_new(string id, ObjectPath path) { + try { + + Properties p = Bus.get_proxy_sync( + user ? BusType.SESSION : BusType.SYSTEM, + "org.freedesktop.systemd1", + path); + + p.properties_changed.connect(on_unit_changed); + + TreeIter iter; + unit_model.append(out iter); + + Unit u = Bus.get_proxy_sync( + user ? BusType.SESSION : BusType.SYSTEM, + "org.freedesktop.systemd1", + path); + + unit_map[id] = u; + + update_unit_iter(iter, id, u); + } catch (Error e) { + show_error(e.message); + } + } + + public void update_job_iter(TreeIter iter, uint32 id, Job j) { + job_model.set(iter, + 0, "%u".printf(id), + 1, j.unit.id, + 2, "→ %s".printf(j.job_type), + 3, j.state, + 4, j, + 5, id); + } + + public void on_job_new(uint32 id, ObjectPath path) { + + try { + + Properties p = Bus.get_proxy_sync( + user ? BusType.SESSION : BusType.SYSTEM, + "org.freedesktop.systemd1", + path); + + p.properties_changed.connect(on_job_changed); + + TreeIter iter; + job_model.append(out iter); + + Job j = Bus.get_proxy_sync( + user ? BusType.SESSION : BusType.SYSTEM, + "org.freedesktop.systemd1", + path); + + update_job_iter(iter, id, j); + + } catch (Error e) { + show_error(e.message); + } + } + + public void on_unit_removed(string id, ObjectPath path) { + TreeIter iter; + if (!(unit_model.get_iter_first(out iter))) + return; + + do { + string name; + + unit_model.get(iter, 0, out name); + + if (id == name) { + if (current_unit_id == name) + clear_unit(); + + unit_model.remove(iter); + break; + } + + } while (unit_model.iter_next(ref iter)); + + unit_map.unset(id); + } + + public void on_job_removed(uint32 id, ObjectPath path, string res) { + TreeIter iter; + if (!(job_model.get_iter_first(out iter))) + return; + + do { + uint32 j; + + job_model.get(iter, 5, out j); + + if (id == j) { + if (current_job_id == j) + clear_job(); + + job_model.remove(iter); + + break; + } + + } while (job_model.iter_next(ref iter)); + } + + public void on_unit_changed(Properties p, string iface, HashTable changed_properties, string[] invalidated_properties) { + + try { + TreeIter iter; + string id; + + Unit u = Bus.get_proxy_sync( + user ? BusType.SESSION : BusType.SYSTEM, + p.get_name(), + p.get_object_path()); + + if (!(unit_model.get_iter_first(out iter))) + return; + + id = u.id; + + do { + string name; + + unit_model.get(iter, 0, out name); + + if (id == name) { + update_unit_iter(iter, id, u); + + if (current_unit_id == id) + show_unit(u); + + break; + } + + } while (unit_model.iter_next(ref iter)); + + } catch (Error e) { + show_error(e.message); + } + } + + public void on_job_changed(Properties p, string iface, HashTable changed_properties, string[] invalidated_properties) { + try { + TreeIter iter; + uint32 id; + + Job j = Bus.get_proxy_sync( + user ? BusType.SESSION : BusType.SYSTEM, + p.get_name(), + p.get_object_path()); + + if (!(job_model.get_iter_first(out iter))) + return; + + id = j.id; + + do { + uint32 k; + + job_model.get(iter, 5, out k); + + if (id == k) { + update_job_iter(iter, id, j); + + if (current_job_id == id) + show_job(j); + + break; + } + + } while (job_model.iter_next(ref iter)); + + } catch (Error e) { + show_error(e.message); + } + } + + public bool unit_filter(TreeModel model, TreeIter iter) { + string id, active_state, job; + + model.get(iter, 0, out id, 3, out active_state, 5, out job); + + if (id == null) + return false; + + if (!inactive_checkbox.get_active() + && active_state == "inactive" && job == "") + return false; + + switch (unit_type_combo_box.get_active()) { + case 0: + return true; + case 1: + return id.has_suffix(".target"); + case 2: + return id.has_suffix(".service"); + case 3: + return id.has_suffix(".device"); + case 4: + return id.has_suffix(".mount"); + case 5: + return id.has_suffix(".automount"); + case 6: + return id.has_suffix(".swap"); + case 7: + return id.has_suffix(".socket"); + case 8: + return id.has_suffix(".path"); + case 9: + return id.has_suffix(".timer"); + case 10: + return id.has_suffix(".snapshot"); + default: + assert(false); + return false; + } + } + + public void unit_type_changed() { + TreeModelFilter model = (TreeModelFilter) ((TreeModelSort) unit_view.get_model()).get_model(); + + model.refilter(); + } + + public void on_server_reload() { + try { + manager.reload(); + } catch (Error e) { + show_error(e.message); + } + } + + public void on_server_snapshot() { + try { + manager.create_snapshot(); + + if (unit_type_combo_box.get_active() != 0) + unit_type_combo_box.set_active(8); + + } catch (Error e) { + show_error(e.message); + } + } + + public void on_unit_load() { + string t = unit_load_entry.get_text(); + + if (t == "") + return; + + try { + var path = manager.load_unit(t); + + Unit u = Bus.get_proxy_sync( + user ? BusType.SESSION : BusType.SYSTEM, + "org.freedesktop.systemd1", + path); + + var m = new MessageDialog(this, + DialogFlags.DESTROY_WITH_PARENT, + MessageType.INFO, + ButtonsType.CLOSE, + "Unit available as id %s", u.id); + m.title = "Unit"; + m.run(); + m.destroy(); + + show_unit(u); + } catch (Error e) { + show_error(e.message); + } + } + + public void on_unit_load_entry_changed() { + unit_load_button.set_sensitive(unit_load_entry.get_text() != ""); + } + + public bool on_activate_link(string uri) { + + try { + string path = manager.get_unit(uri); + + Unit u = Bus.get_proxy_sync( + user ? BusType.SESSION : BusType.SYSTEM, + "org.freedesktop.systemd1", + path); + + show_unit(u); + } catch (Error e) { + show_error(e.message); + } + + return true; + } + + public void show_error(string e) { + var m = new MessageDialog(this, + DialogFlags.DESTROY_WITH_PARENT, + MessageType.ERROR, + ButtonsType.CLOSE, "%s", e); + m.title = "Error"; + m.run(); + m.destroy(); + } + +} + +static const OptionEntry entries[] = { + { "user", 0, 0, OptionArg.NONE, out user, "Connect to user service manager", null }, + { "system", 0, OptionFlags.REVERSE, OptionArg.NONE, out user, "Connect to system manager", null }, + { null } +}; + +void show_error(string e) { + var m = new MessageDialog(null, 0, MessageType.ERROR, ButtonsType.CLOSE, "%s", e); + m.run(); + m.destroy(); +} + +int main(string[] args) { + + try { + Gtk.init_with_args(ref args, "[OPTION...]", entries, "systemadm"); + + MainWindow window = new MainWindow(); + window.show_all(); + + Gtk.main(); + } catch (IOError e) { + show_error(e.message); + } catch (GLib.Error e) { + stderr.printf("%s\n", e.message); + } + + return 0; +} diff --git a/src/systemctl.c b/src/systemctl.c new file mode 100644 index 0000000..ab6d126 --- /dev/null +++ b/src/systemctl.c @@ -0,0 +1,5367 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "log.h" +#include "util.h" +#include "macro.h" +#include "set.h" +#include "utmp-wtmp.h" +#include "special.h" +#include "initreq.h" +#include "strv.h" +#include "dbus-common.h" +#include "cgroup-show.h" +#include "cgroup-util.h" +#include "list.h" +#include "path-lookup.h" +#include "conf-parser.h" +#include "shutdownd.h" +#include "exit-status.h" +#include "bus-errors.h" +#include "build.h" +#include "unit-name.h" +#include "pager.h" +#include "spawn-agent.h" +#include "install.h" +#include "logs-show.h" + +static const char *arg_type = NULL; +static char **arg_property = NULL; +static bool arg_all = false; +static const char *arg_job_mode = "replace"; +static UnitFileScope arg_scope = UNIT_FILE_SYSTEM; +static bool arg_immediate = false; +static bool arg_no_block = false; +static bool arg_no_legend = false; +static bool arg_no_pager = false; +static bool arg_no_wtmp = false; +static bool arg_no_sync = false; +static bool arg_no_wall = false; +static bool arg_no_reload = false; +static bool arg_dry = false; +static bool arg_quiet = false; +static bool arg_full = false; +static bool arg_force = false; +static bool arg_ask_password = false; +static bool arg_failed = false; +static bool arg_runtime = false; +static char **arg_wall = NULL; +static const char *arg_kill_who = NULL; +static const char *arg_kill_mode = NULL; +static int arg_signal = SIGTERM; +static const char *arg_root = NULL; +static usec_t arg_when = 0; +static enum action { + ACTION_INVALID, + ACTION_SYSTEMCTL, + ACTION_HALT, + ACTION_POWEROFF, + ACTION_REBOOT, + ACTION_KEXEC, + ACTION_EXIT, + ACTION_RUNLEVEL2, + ACTION_RUNLEVEL3, + ACTION_RUNLEVEL4, + ACTION_RUNLEVEL5, + ACTION_RESCUE, + ACTION_EMERGENCY, + ACTION_DEFAULT, + ACTION_RELOAD, + ACTION_REEXEC, + ACTION_RUNLEVEL, + ACTION_CANCEL_SHUTDOWN, + _ACTION_MAX +} arg_action = ACTION_SYSTEMCTL; +static enum dot { + DOT_ALL, + DOT_ORDER, + DOT_REQUIRE +} arg_dot = DOT_ALL; +static enum transport { + TRANSPORT_NORMAL, + TRANSPORT_SSH, + TRANSPORT_POLKIT +} arg_transport = TRANSPORT_NORMAL; +static const char *arg_host = NULL; +static bool arg_follow = false; +static unsigned arg_lines = 10; +static OutputMode arg_output = OUTPUT_SHORT; + +static bool private_bus = false; + +static int daemon_reload(DBusConnection *bus, char **args); + +static bool on_tty(void) { + static int t = -1; + + /* Note that this is invoked relatively early, before we start + * the pager. That means the value we return reflects whether + * we originally were started on a tty, not if we currently + * are. But this is intended, since we want colour and so on + * when run in our own pager. */ + + if (_unlikely_(t < 0)) + t = isatty(STDOUT_FILENO) > 0; + + return t; +} + +static void pager_open_if_enabled(void) { + + /* Cache result before we open the pager */ + on_tty(); + + if (arg_no_pager) + return; + + pager_open(); +} + +static void agent_open_if_enabled(void) { + + /* Open the password agent as a child process if necessary */ + + if (!arg_ask_password) + return; + + if (arg_scope != UNIT_FILE_SYSTEM) + return; + + agent_open(); +} + +static const char *ansi_highlight_red(bool b) { + + if (!on_tty()) + return ""; + + return b ? ANSI_HIGHLIGHT_RED_ON : ANSI_HIGHLIGHT_OFF; +} + +static const char *ansi_highlight_green(bool b) { + + if (!on_tty()) + return ""; + + return b ? ANSI_HIGHLIGHT_GREEN_ON : ANSI_HIGHLIGHT_OFF; +} + +static bool error_is_no_service(const DBusError *error) { + assert(error); + + if (!dbus_error_is_set(error)) + return false; + + if (dbus_error_has_name(error, DBUS_ERROR_NAME_HAS_NO_OWNER)) + return true; + + if (dbus_error_has_name(error, DBUS_ERROR_SERVICE_UNKNOWN)) + return true; + + return startswith(error->name, "org.freedesktop.DBus.Error.Spawn."); +} + +static int translate_bus_error_to_exit_status(int r, const DBusError *error) { + assert(error); + + if (!dbus_error_is_set(error)) + return r; + + if (dbus_error_has_name(error, DBUS_ERROR_ACCESS_DENIED) || + dbus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) || + dbus_error_has_name(error, BUS_ERROR_NO_ISOLATION) || + dbus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE)) + return EXIT_NOPERMISSION; + + if (dbus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT)) + return EXIT_NOTINSTALLED; + + if (dbus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) || + dbus_error_has_name(error, BUS_ERROR_NOT_SUPPORTED)) + return EXIT_NOTIMPLEMENTED; + + if (dbus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) + return EXIT_NOTCONFIGURED; + + if (r != 0) + return r; + + return EXIT_FAILURE; +} + +static void warn_wall(enum action action) { + static const char *table[_ACTION_MAX] = { + [ACTION_HALT] = "The system is going down for system halt NOW!", + [ACTION_REBOOT] = "The system is going down for reboot NOW!", + [ACTION_POWEROFF] = "The system is going down for power-off NOW!", + [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!", + [ACTION_RESCUE] = "The system is going down to rescue mode NOW!", + [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!" + }; + + if (arg_no_wall) + return; + + if (arg_wall) { + char *p; + + if (!(p = strv_join(arg_wall, " "))) { + log_error("Failed to join strings."); + return; + } + + if (*p) { + utmp_wall(p, NULL); + free(p); + return; + } + + free(p); + } + + if (!table[action]) + return; + + utmp_wall(table[action], NULL); +} + +static bool avoid_bus(void) { + + if (running_in_chroot() > 0) + return true; + + if (sd_booted() <= 0) + return true; + + if (!isempty(arg_root)) + return true; + + if (arg_scope == UNIT_FILE_GLOBAL) + return true; + + return false; +} + +struct unit_info { + const char *id; + const char *description; + const char *load_state; + const char *active_state; + const char *sub_state; + const char *following; + const char *unit_path; + uint32_t job_id; + const char *job_type; + const char *job_path; +}; + +static int compare_unit_info(const void *a, const void *b) { + const char *d1, *d2; + const struct unit_info *u = a, *v = b; + + d1 = strrchr(u->id, '.'); + d2 = strrchr(v->id, '.'); + + if (d1 && d2) { + int r; + + if ((r = strcasecmp(d1, d2)) != 0) + return r; + } + + return strcasecmp(u->id, v->id); +} + +static bool output_show_unit(const struct unit_info *u) { + const char *dot; + + if (arg_failed) + return streq(u->active_state, "failed"); + + return (!arg_type || ((dot = strrchr(u->id, '.')) && + streq(dot+1, arg_type))) && + (arg_all || !(streq(u->active_state, "inactive") || u->following[0]) || u->job_id > 0); +} + +static void output_units_list(const struct unit_info *unit_infos, unsigned c) { + unsigned id_len, max_id_len, active_len, sub_len, job_len, desc_len, n_shown = 0; + const struct unit_info *u; + + max_id_len = sizeof("UNIT")-1; + active_len = sizeof("ACTIVE")-1; + sub_len = sizeof("SUB")-1; + job_len = sizeof("JOB")-1; + desc_len = 0; + + for (u = unit_infos; u < unit_infos + c; u++) { + if (!output_show_unit(u)) + continue; + + max_id_len = MAX(max_id_len, strlen(u->id)); + active_len = MAX(active_len, strlen(u->active_state)); + sub_len = MAX(sub_len, strlen(u->sub_state)); + if (u->job_id != 0) + job_len = MAX(job_len, strlen(u->job_type)); + } + + if (!arg_full) { + unsigned basic_len; + id_len = MIN(max_id_len, 25); + basic_len = 5 + id_len + 6 + active_len + sub_len + job_len; + if (basic_len < (unsigned) columns()) { + unsigned extra_len, incr; + extra_len = columns() - basic_len; + /* Either UNIT already got 25, or is fully satisfied. + * Grant up to 25 to DESC now. */ + incr = MIN(extra_len, 25); + desc_len += incr; + extra_len -= incr; + /* split the remaining space between UNIT and DESC, + * but do not give UNIT more than it needs. */ + if (extra_len > 0) { + incr = MIN(extra_len / 2, max_id_len - id_len); + id_len += incr; + desc_len += extra_len - incr; + } + } + } else + id_len = max_id_len; + + if (!arg_no_legend) { + printf("%-*s %-6s %-*s %-*s %-*s ", id_len, "UNIT", "LOAD", + active_len, "ACTIVE", sub_len, "SUB", job_len, "JOB"); + if (!arg_full && arg_no_pager) + printf("%.*s\n", desc_len, "DESCRIPTION"); + else + printf("%s\n", "DESCRIPTION"); + } + + for (u = unit_infos; u < unit_infos + c; u++) { + char *e; + const char *on_loaded, *off_loaded; + const char *on_active, *off_active; + + if (!output_show_unit(u)) + continue; + + n_shown++; + + if (streq(u->load_state, "error")) { + on_loaded = ansi_highlight_red(true); + off_loaded = ansi_highlight_red(false); + } else + on_loaded = off_loaded = ""; + + if (streq(u->active_state, "failed")) { + on_active = ansi_highlight_red(true); + off_active = ansi_highlight_red(false); + } else + on_active = off_active = ""; + + e = arg_full ? NULL : ellipsize(u->id, id_len, 33); + + printf("%-*s %s%-6s%s %s%-*s %-*s%s %-*s ", + id_len, e ? e : u->id, + on_loaded, u->load_state, off_loaded, + on_active, active_len, u->active_state, + sub_len, u->sub_state, off_active, + job_len, u->job_id ? u->job_type : ""); + if (!arg_full && arg_no_pager) + printf("%.*s\n", desc_len, u->description); + else + printf("%s\n", u->description); + + free(e); + } + + if (!arg_no_legend) { + printf("\nLOAD = Reflects whether the unit definition was properly loaded.\n" + "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n" + "SUB = The low-level unit activation state, values depend on unit type.\n" + "JOB = Pending job for the unit.\n"); + + if (arg_all) + printf("\n%u units listed.\n", n_shown); + else + printf("\n%u units listed. Pass --all to see inactive units, too.\n", n_shown); + } +} + +static int list_units(DBusConnection *bus, char **args) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; + DBusMessageIter iter, sub, sub2; + unsigned c = 0, n_units = 0; + struct unit_info *unit_infos = NULL; + + dbus_error_init(&error); + + assert(bus); + + pager_open_if_enabled(); + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "ListUnits"))) { + log_error("Could not allocate message."); + return -ENOMEM; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + struct unit_info *u; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if (c >= n_units) { + struct unit_info *w; + + n_units = MAX(2*c, 16); + w = realloc(unit_infos, sizeof(struct unit_info) * n_units); + + if (!w) { + log_error("Failed to allocate unit array."); + r = -ENOMEM; + goto finish; + } + + unit_infos = w; + } + + u = unit_infos+c; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->id, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->description, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->load_state, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->active_state, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->sub_state, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->following, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &u->unit_path, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &u->job_id, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->job_type, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &u->job_path, false) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_next(&sub); + c++; + } + + if (c > 0) { + qsort(unit_infos, c, sizeof(struct unit_info), compare_unit_info); + output_units_list(unit_infos, c); + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + free(unit_infos); + + dbus_error_free(&error); + + return r; +} + +static int compare_unit_file_list(const void *a, const void *b) { + const char *d1, *d2; + const UnitFileList *u = a, *v = b; + + d1 = strrchr(u->path, '.'); + d2 = strrchr(v->path, '.'); + + if (d1 && d2) { + int r; + + r = strcasecmp(d1, d2); + if (r != 0) + return r; + } + + return strcasecmp(file_name_from_path(u->path), file_name_from_path(v->path)); +} + +static bool output_show_unit_file(const UnitFileList *u) { + const char *dot; + + return !arg_type || ((dot = strrchr(u->path, '.')) && streq(dot+1, arg_type)); +} + +static void output_unit_file_list(const UnitFileList *units, unsigned c) { + unsigned max_id_len, id_cols, state_cols, n_shown = 0; + const UnitFileList *u; + + max_id_len = sizeof("UNIT FILE")-1; + state_cols = sizeof("STATE")-1; + for (u = units; u < units + c; u++) { + if (!output_show_unit_file(u)) + continue; + + max_id_len = MAX(max_id_len, strlen(file_name_from_path(u->path))); + state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state))); + } + + if (!arg_full) { + unsigned basic_cols; + id_cols = MIN(max_id_len, 25); + basic_cols = 1 + id_cols + state_cols; + if (basic_cols < (unsigned) columns()) + id_cols += MIN(columns() - basic_cols, max_id_len - id_cols); + } else + id_cols = max_id_len; + + if (!arg_no_legend) + printf("%-*s %-*s\n", id_cols, "UNIT FILE", state_cols, "STATE"); + + for (u = units; u < units + c; u++) { + char *e; + const char *on, *off; + const char *id; + + if (!output_show_unit_file(u)) + continue; + + n_shown++; + + if (u->state == UNIT_FILE_MASKED || + u->state == UNIT_FILE_MASKED_RUNTIME || + u->state == UNIT_FILE_DISABLED) { + on = ansi_highlight_red(true); + off = ansi_highlight_red(false); + } else if (u->state == UNIT_FILE_ENABLED) { + on = ansi_highlight_green(true); + off = ansi_highlight_green(false); + } else + on = off = ""; + + id = file_name_from_path(u->path); + + e = arg_full ? NULL : ellipsize(id, id_cols, 33); + + printf("%-*s %s%-*s%s\n", + id_cols, e ? e : id, + on, state_cols, unit_file_state_to_string(u->state), off); + + free(e); + } + + if (!arg_no_legend) + printf("\n%u unit files listed.\n", n_shown); +} + +static int list_unit_files(DBusConnection *bus, char **args) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; + DBusMessageIter iter, sub, sub2; + unsigned c = 0, n_units = 0; + UnitFileList *units = NULL; + + dbus_error_init(&error); + + pager_open_if_enabled(); + + if (avoid_bus()) { + Hashmap *h; + UnitFileList *u; + Iterator i; + + h = hashmap_new(string_hash_func, string_compare_func); + if (!h) { + log_error("Out of memory"); + return -ENOMEM; + } + + r = unit_file_get_list(arg_scope, arg_root, h); + if (r < 0) { + unit_file_list_free(h); + log_error("Failed to get unit file list: %s", strerror(-r)); + return r; + } + + n_units = hashmap_size(h); + units = new(UnitFileList, n_units); + if (!units) { + unit_file_list_free(h); + log_error("Out of memory"); + return -ENOMEM; + } + + HASHMAP_FOREACH(u, h, i) { + memcpy(units + c++, u, sizeof(UnitFileList)); + free(u); + } + + hashmap_free(h); + } else { + assert(bus); + + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "ListUnitFiles"); + if (!m) { + log_error("Could not allocate message."); + return -ENOMEM; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + UnitFileList *u; + const char *state; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if (c >= n_units) { + UnitFileList *w; + + n_units = MAX(2*c, 16); + w = realloc(units, sizeof(struct UnitFileList) * n_units); + + if (!w) { + log_error("Failed to allocate unit array."); + r = -ENOMEM; + goto finish; + } + + units = w; + } + + u = units+c; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &u->path, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &state, false) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + u->state = unit_file_state_from_string(state); + + dbus_message_iter_next(&sub); + c++; + } + } + + if (c > 0) { + qsort(units, c, sizeof(UnitFileList), compare_unit_file_list); + output_unit_file_list(units, c); + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + free(units); + + dbus_error_free(&error); + + return r; +} + +static int dot_one_property(const char *name, const char *prop, DBusMessageIter *iter) { + static const char * const colors[] = { + "Requires", "[color=\"black\"]", + "RequiresOverridable", "[color=\"black\"]", + "Requisite", "[color=\"darkblue\"]", + "RequisiteOverridable", "[color=\"darkblue\"]", + "Wants", "[color=\"darkgrey\"]", + "Conflicts", "[color=\"red\"]", + "ConflictedBy", "[color=\"red\"]", + "After", "[color=\"green\"]" + }; + + const char *c = NULL; + unsigned i; + + assert(name); + assert(prop); + assert(iter); + + for (i = 0; i < ELEMENTSOF(colors); i += 2) + if (streq(colors[i], prop)) { + c = colors[i+1]; + break; + } + + if (!c) + return 0; + + if (arg_dot != DOT_ALL) + if ((arg_dot == DOT_ORDER) != streq(prop, "After")) + return 0; + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_ARRAY: + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING) { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *s; + + assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING); + dbus_message_iter_get_basic(&sub, &s); + printf("\t\"%s\"->\"%s\" %s;\n", name, s, c); + + dbus_message_iter_next(&sub); + } + + return 0; + } + } + + return 0; +} + +static int dot_one(DBusConnection *bus, const char *name, const char *path) { + DBusMessage *m = NULL, *reply = NULL; + const char *interface = "org.freedesktop.systemd1.Unit"; + int r; + DBusError error; + DBusMessageIter iter, sub, sub2, sub3; + + assert(bus); + assert(path); + + dbus_error_init(&error); + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "GetAll"))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *prop; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &prop, true) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub2, &sub3); + + if (dot_one_property(name, prop, &sub3)) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_next(&sub); + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int dot(DBusConnection *bus, char **args) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; + DBusMessageIter iter, sub, sub2; + + dbus_error_init(&error); + + assert(bus); + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "ListUnits"))) { + log_error("Could not allocate message."); + return -ENOMEM; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + printf("digraph systemd {\n"); + + dbus_message_iter_recurse(&iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *id, *description, *load_state, *active_state, *sub_state, *following, *unit_path; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &id, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &description, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &load_state, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &active_state, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &sub_state, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &following, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &unit_path, true) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if ((r = dot_one(bus, id, unit_path)) < 0) + goto finish; + + /* printf("\t\"%s\";\n", id); */ + dbus_message_iter_next(&sub); + } + + printf("}\n"); + + log_info(" Color legend: black = Requires\n" + " dark blue = Requisite\n" + " dark grey = Wants\n" + " red = Conflicts\n" + " green = After\n"); + + if (on_tty()) + log_notice("-- You probably want to process this output with graphviz' dot tool.\n" + "-- Try a shell pipeline like 'systemctl dot | dot -Tsvg > systemd.svg'!\n"); + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int list_jobs(DBusConnection *bus, char **args) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; + DBusMessageIter iter, sub, sub2; + unsigned k = 0; + + dbus_error_init(&error); + + assert(bus); + + pager_open_if_enabled(); + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "ListJobs"))) { + log_error("Could not allocate message."); + return -ENOMEM; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (on_tty()) + printf("%4s %-25s %-15s %-7s\n", "JOB", "UNIT", "TYPE", "STATE"); + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *name, *type, *state, *job_path, *unit_path; + uint32_t id; + char *e; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &id, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &state, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &job_path, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_OBJECT_PATH, &unit_path, false) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + e = arg_full ? NULL : ellipsize(name, 25, 33); + printf("%4u %-25s %-15s %-7s\n", id, e ? e : name, type, state); + free(e); + + k++; + + dbus_message_iter_next(&sub); + } + + if (on_tty()) + printf("\n%u jobs listed.\n", k); + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int load_unit(DBusConnection *bus, char **args) { + DBusMessage *m = NULL; + DBusError error; + int r; + char **name; + + dbus_error_init(&error); + + assert(bus); + assert(args); + + STRV_FOREACH(name, args+1) { + DBusMessage *reply; + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "LoadUnit"))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, name, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(m); + dbus_message_unref(reply); + + m = reply = NULL; + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + dbus_error_free(&error); + + return r; +} + +static int cancel_job(DBusConnection *bus, char **args) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; + char **name; + + dbus_error_init(&error); + + assert(bus); + assert(args); + + if (strv_length(args) <= 1) + return daemon_reload(bus, args); + + STRV_FOREACH(name, args+1) { + unsigned id; + const char *path; + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetJob"))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if ((r = safe_atou(*name, &id)) < 0) { + log_error("Failed to parse job id: %s", strerror(-r)); + goto finish; + } + + assert_cc(sizeof(uint32_t) == sizeof(id)); + if (!dbus_message_append_args(m, + DBUS_TYPE_UINT32, &id, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(m); + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + path, + "org.freedesktop.systemd1.Job", + "Cancel"))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + dbus_message_unref(reply); + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static bool need_daemon_reload(DBusConnection *bus, const char *unit) { + DBusMessage *m = NULL, *reply = NULL; + dbus_bool_t b = FALSE; + DBusMessageIter iter, sub; + const char + *interface = "org.freedesktop.systemd1.Unit", + *property = "NeedDaemonReload", + *path; + + /* We ignore all errors here, since this is used to show a warning only */ + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnit"))) + goto finish; + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &unit, + DBUS_TYPE_INVALID)) + goto finish; + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, NULL))) + goto finish; + + if (!dbus_message_get_args(reply, NULL, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) + goto finish; + + dbus_message_unref(m); + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get"))) + goto finish; + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID)) { + goto finish; + } + + dbus_message_unref(reply); + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, NULL))) + goto finish; + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) + goto finish; + + dbus_message_iter_recurse(&iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN) + goto finish; + + dbus_message_iter_get_basic(&sub, &b); + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + return b; +} + +typedef struct WaitData { + Set *set; + char *result; +} WaitData; + +static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *message, void *data) { + DBusError error; + WaitData *d = data; + + assert(connection); + assert(message); + assert(d); + + dbus_error_init(&error); + + log_debug("Got D-Bus request: %s.%s() on %s", + dbus_message_get_interface(message), + dbus_message_get_member(message), + dbus_message_get_path(message)); + + if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { + log_error("Warning! D-Bus connection terminated."); + dbus_connection_close(connection); + + } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "JobRemoved")) { + uint32_t id; + const char *path, *result; + dbus_bool_t success = true; + + if (dbus_message_get_args(message, &error, + DBUS_TYPE_UINT32, &id, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_STRING, &result, + DBUS_TYPE_INVALID)) { + char *p; + + if ((p = set_remove(d->set, (char*) path))) + free(p); + + if (*result) + d->result = strdup(result); + + goto finish; + } +#ifndef LEGACY + dbus_error_free(&error); + + if (dbus_message_get_args(message, &error, + DBUS_TYPE_UINT32, &id, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_BOOLEAN, &success, + DBUS_TYPE_INVALID)) { + char *p; + + /* Compatibility with older systemd versions < + * 19 during upgrades. This should be dropped + * one day */ + + if ((p = set_remove(d->set, (char*) path))) + free(p); + + if (!success) + d->result = strdup("failed"); + + goto finish; + } +#endif + + log_error("Failed to parse message: %s", bus_error_message(&error)); + } + +finish: + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static int enable_wait_for_jobs(DBusConnection *bus) { + DBusError error; + + assert(bus); + + if (private_bus) + return 0; + + dbus_error_init(&error); + dbus_bus_add_match(bus, + "type='signal'," + "sender='org.freedesktop.systemd1'," + "interface='org.freedesktop.systemd1.Manager'," + "member='JobRemoved'," + "path='/org/freedesktop/systemd1'", + &error); + + if (dbus_error_is_set(&error)) { + log_error("Failed to add match: %s", bus_error_message(&error)); + dbus_error_free(&error); + return -EIO; + } + + /* This is slightly dirty, since we don't undo the match registrations. */ + return 0; +} + +static int wait_for_jobs(DBusConnection *bus, Set *s) { + int r; + WaitData d; + + assert(bus); + assert(s); + + zero(d); + d.set = s; + + if (!dbus_connection_add_filter(bus, wait_filter, &d, NULL)) { + log_error("Failed to add filter."); + r = -ENOMEM; + goto finish; + } + + while (!set_isempty(s) && + dbus_connection_read_write_dispatch(bus, -1)) + ; + + if (!arg_quiet && d.result) { + if (streq(d.result, "timeout")) + log_error("Job timed out."); + else if (streq(d.result, "canceled")) + log_error("Job canceled."); + else if (streq(d.result, "dependency")) + log_error("A dependency job failed. See system journal for details."); + else if (!streq(d.result, "done") && !streq(d.result, "skipped")) + log_error("Job failed. See system journal and 'systemctl status' for details."); + } + + if (streq_ptr(d.result, "timeout")) + r = -ETIME; + else if (streq_ptr(d.result, "canceled")) + r = -ECANCELED; + else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped")) + r = -EIO; + else + r = 0; + + free(d.result); + +finish: + /* This is slightly dirty, since we don't undo the filter registration. */ + + return r; +} + +static int start_unit_one( + DBusConnection *bus, + const char *method, + const char *name, + const char *mode, + DBusError *error, + Set *s) { + + DBusMessage *m = NULL, *reply = NULL; + const char *path; + int r; + + assert(bus); + assert(method); + assert(name); + assert(mode); + assert(error); + assert(arg_no_block || s); + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + method))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error))) { + + if (arg_action != ACTION_SYSTEMCTL && error_is_no_service(error)) { + /* There's always a fallback possible for + * legacy actions. */ + r = -EADDRNOTAVAIL; + goto finish; + } + + log_error("Failed to issue method call: %s", bus_error_message(error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_get_args(reply, error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(error)); + r = -EIO; + goto finish; + } + + if (need_daemon_reload(bus, name)) + log_warning("Warning: Unit file of created job changed on disk, 'systemctl %s daemon-reload' recommended.", + arg_scope == UNIT_FILE_SYSTEM ? "--system" : "--user"); + + if (!arg_no_block) { + char *p; + + if (!(p = strdup(path))) { + log_error("Failed to duplicate path."); + r = -ENOMEM; + goto finish; + } + + if ((r = set_put(s, p)) < 0) { + free(p); + log_error("Failed to add path to set."); + goto finish; + } + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + return r; +} + +static enum action verb_to_action(const char *verb) { + if (streq(verb, "halt")) + return ACTION_HALT; + else if (streq(verb, "poweroff")) + return ACTION_POWEROFF; + else if (streq(verb, "reboot")) + return ACTION_REBOOT; + else if (streq(verb, "kexec")) + return ACTION_KEXEC; + else if (streq(verb, "rescue")) + return ACTION_RESCUE; + else if (streq(verb, "emergency")) + return ACTION_EMERGENCY; + else if (streq(verb, "default")) + return ACTION_DEFAULT; + else if (streq(verb, "exit")) + return ACTION_EXIT; + else + return ACTION_INVALID; +} + +static int start_unit(DBusConnection *bus, char **args) { + + static const char * const table[_ACTION_MAX] = { + [ACTION_HALT] = SPECIAL_HALT_TARGET, + [ACTION_POWEROFF] = SPECIAL_POWEROFF_TARGET, + [ACTION_REBOOT] = SPECIAL_REBOOT_TARGET, + [ACTION_KEXEC] = SPECIAL_KEXEC_TARGET, + [ACTION_RUNLEVEL2] = SPECIAL_RUNLEVEL2_TARGET, + [ACTION_RUNLEVEL3] = SPECIAL_RUNLEVEL3_TARGET, + [ACTION_RUNLEVEL4] = SPECIAL_RUNLEVEL4_TARGET, + [ACTION_RUNLEVEL5] = SPECIAL_RUNLEVEL5_TARGET, + [ACTION_RESCUE] = SPECIAL_RESCUE_TARGET, + [ACTION_EMERGENCY] = SPECIAL_EMERGENCY_TARGET, + [ACTION_DEFAULT] = SPECIAL_DEFAULT_TARGET, + [ACTION_EXIT] = SPECIAL_EXIT_TARGET + }; + + int r, ret = 0; + const char *method, *mode, *one_name; + Set *s = NULL; + DBusError error; + char **name; + + dbus_error_init(&error); + + assert(bus); + + agent_open_if_enabled(); + + if (arg_action == ACTION_SYSTEMCTL) { + method = + streq(args[0], "stop") || + streq(args[0], "condstop") ? "StopUnit" : + streq(args[0], "reload") ? "ReloadUnit" : + streq(args[0], "restart") ? "RestartUnit" : + + streq(args[0], "try-restart") || + streq(args[0], "condrestart") ? "TryRestartUnit" : + + streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" : + + streq(args[0], "reload-or-try-restart") || + streq(args[0], "condreload") || + + streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" : + "StartUnit"; + + mode = + (streq(args[0], "isolate") || + streq(args[0], "rescue") || + streq(args[0], "emergency")) ? "isolate" : arg_job_mode; + + one_name = table[verb_to_action(args[0])]; + + } else { + assert(arg_action < ELEMENTSOF(table)); + assert(table[arg_action]); + + method = "StartUnit"; + + mode = (arg_action == ACTION_EMERGENCY || + arg_action == ACTION_RESCUE || + arg_action == ACTION_RUNLEVEL2 || + arg_action == ACTION_RUNLEVEL3 || + arg_action == ACTION_RUNLEVEL4 || + arg_action == ACTION_RUNLEVEL5) ? "isolate" : "replace"; + + one_name = table[arg_action]; + } + + if (!arg_no_block) { + if ((ret = enable_wait_for_jobs(bus)) < 0) { + log_error("Could not watch jobs: %s", strerror(-ret)); + goto finish; + } + + if (!(s = set_new(string_hash_func, string_compare_func))) { + log_error("Failed to allocate set."); + ret = -ENOMEM; + goto finish; + } + } + + if (one_name) { + if ((ret = start_unit_one(bus, method, one_name, mode, &error, s)) <= 0) + goto finish; + } else { + STRV_FOREACH(name, args+1) + if ((r = start_unit_one(bus, method, *name, mode, &error, s)) != 0) { + ret = translate_bus_error_to_exit_status(r, &error); + dbus_error_free(&error); + } + } + + if (!arg_no_block) + if ((r = wait_for_jobs(bus, s)) < 0) { + ret = r; + goto finish; + } + +finish: + if (s) + set_free_free(s); + + dbus_error_free(&error); + + return ret; +} + +static int start_special(DBusConnection *bus, char **args) { + int r; + + assert(bus); + assert(args); + + if (arg_force && + (streq(args[0], "halt") || + streq(args[0], "poweroff") || + streq(args[0], "reboot") || + streq(args[0], "kexec") || + streq(args[0], "exit"))) + return daemon_reload(bus, args); + + r = start_unit(bus, args); + + if (r >= 0) + warn_wall(verb_to_action(args[0])); + + return r; +} + +static int check_unit(DBusConnection *bus, char **args) { + DBusMessage *m = NULL, *reply = NULL; + const char + *interface = "org.freedesktop.systemd1.Unit", + *property = "ActiveState"; + int r = 3; /* According to LSB: "program is not running" */ + DBusError error; + char **name; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + STRV_FOREACH(name, args+1) { + const char *path = NULL; + const char *state; + DBusMessageIter iter, sub; + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnit"))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, name, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + + /* Hmm, cannot figure out anything about this unit... */ + if (!arg_quiet) + puts("unknown"); + + dbus_error_free(&error); + dbus_message_unref(m); + m = NULL; + continue; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(m); + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get"))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + dbus_message_unref(reply); + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_get_basic(&sub, &state); + + if (!arg_quiet) + puts(state); + + if (streq(state, "active") || streq(state, "reloading")) + r = 0; + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + } + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int kill_unit(DBusConnection *bus, char **args) { + DBusMessage *m = NULL; + int r = 0; + DBusError error; + char **name; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + if (!arg_kill_who) + arg_kill_who = "all"; + + if (!arg_kill_mode) + arg_kill_mode = streq(arg_kill_who, "all") ? "control-group" : "process"; + + STRV_FOREACH(name, args+1) { + DBusMessage *reply; + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "KillUnit"))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, name, + DBUS_TYPE_STRING, &arg_kill_who, + DBUS_TYPE_STRING, &arg_kill_mode, + DBUS_TYPE_INT32, &arg_signal, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + dbus_error_free(&error); + r = -EIO; + } + + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + m = reply = NULL; + } + +finish: + if (m) + dbus_message_unref(m); + + dbus_error_free(&error); + + return r; +} + +typedef struct ExecStatusInfo { + char *name; + + char *path; + char **argv; + + bool ignore; + + usec_t start_timestamp; + usec_t exit_timestamp; + pid_t pid; + int code; + int status; + + LIST_FIELDS(struct ExecStatusInfo, exec); +} ExecStatusInfo; + +static void exec_status_info_free(ExecStatusInfo *i) { + assert(i); + + free(i->name); + free(i->path); + strv_free(i->argv); + free(i); +} + +static int exec_status_info_deserialize(DBusMessageIter *sub, ExecStatusInfo *i) { + uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic; + DBusMessageIter sub2, sub3; + const char*path; + unsigned n; + uint32_t pid; + int32_t code, status; + dbus_bool_t ignore; + + assert(i); + assert(i); + + if (dbus_message_iter_get_arg_type(sub) != DBUS_TYPE_STRUCT) + return -EIO; + + dbus_message_iter_recurse(sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0) + return -EIO; + + if (!(i->path = strdup(path))) + return -ENOMEM; + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&sub2) != DBUS_TYPE_STRING) + return -EIO; + + n = 0; + dbus_message_iter_recurse(&sub2, &sub3); + while (dbus_message_iter_get_arg_type(&sub3) != DBUS_TYPE_INVALID) { + assert(dbus_message_iter_get_arg_type(&sub3) == DBUS_TYPE_STRING); + dbus_message_iter_next(&sub3); + n++; + } + + + if (!(i->argv = new0(char*, n+1))) + return -ENOMEM; + + n = 0; + dbus_message_iter_recurse(&sub2, &sub3); + while (dbus_message_iter_get_arg_type(&sub3) != DBUS_TYPE_INVALID) { + const char *s; + + assert(dbus_message_iter_get_arg_type(&sub3) == DBUS_TYPE_STRING); + dbus_message_iter_get_basic(&sub3, &s); + dbus_message_iter_next(&sub3); + + if (!(i->argv[n++] = strdup(s))) + return -ENOMEM; + } + + if (!dbus_message_iter_next(&sub2) || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_BOOLEAN, &ignore, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &start_timestamp, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &start_timestamp_monotonic, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &exit_timestamp, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &exit_timestamp_monotonic, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &pid, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &code, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &status, false) < 0) + return -EIO; + + i->ignore = ignore; + i->start_timestamp = (usec_t) start_timestamp; + i->exit_timestamp = (usec_t) exit_timestamp; + i->pid = (pid_t) pid; + i->code = code; + i->status = status; + + return 0; +} + +typedef struct UnitStatusInfo { + const char *id; + const char *load_state; + const char *active_state; + const char *sub_state; + const char *unit_file_state; + + const char *description; + const char *following; + + const char *path; + const char *default_control_group; + + const char *load_error; + const char *result; + + usec_t inactive_exit_timestamp; + usec_t inactive_exit_timestamp_monotonic; + usec_t active_enter_timestamp; + usec_t active_exit_timestamp; + usec_t inactive_enter_timestamp; + + bool need_daemon_reload; + + /* Service */ + pid_t main_pid; + pid_t control_pid; + const char *status_text; + bool running:1; +#ifdef HAVE_SYSV_COMPAT + bool is_sysv:1; +#endif + + usec_t start_timestamp; + usec_t exit_timestamp; + + int exit_code, exit_status; + + usec_t condition_timestamp; + bool condition_result; + + /* Socket */ + unsigned n_accepted; + unsigned n_connections; + bool accept; + + /* Device */ + const char *sysfs_path; + + /* Mount, Automount */ + const char *where; + + /* Swap */ + const char *what; + + LIST_HEAD(ExecStatusInfo, exec); +} UnitStatusInfo; + +static void print_status_info(UnitStatusInfo *i) { + ExecStatusInfo *p; + const char *on, *off, *ss; + usec_t timestamp; + char since1[FORMAT_TIMESTAMP_PRETTY_MAX], *s1; + char since2[FORMAT_TIMESTAMP_MAX], *s2; + + assert(i); + + /* This shows pretty information about a unit. See + * print_property() for a low-level property printer */ + + printf("%s", strna(i->id)); + + if (i->description && !streq_ptr(i->id, i->description)) + printf(" - %s", i->description); + + printf("\n"); + + if (i->following) + printf("\t Follow: unit currently follows state of %s\n", i->following); + + if (streq_ptr(i->load_state, "error")) { + on = ansi_highlight_red(true); + off = ansi_highlight_red(false); + } else + on = off = ""; + + if (i->load_error) + printf("\t Loaded: %s%s%s (Reason: %s)\n", on, strna(i->load_state), off, i->load_error); + else if (i->path && i->unit_file_state) + printf("\t Loaded: %s%s%s (%s; %s)\n", on, strna(i->load_state), off, i->path, i->unit_file_state); + else if (i->path) + printf("\t Loaded: %s%s%s (%s)\n", on, strna(i->load_state), off, i->path); + else + printf("\t Loaded: %s%s%s\n", on, strna(i->load_state), off); + + ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state; + + if (streq_ptr(i->active_state, "failed")) { + on = ansi_highlight_red(true); + off = ansi_highlight_red(false); + } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) { + on = ansi_highlight_green(true); + off = ansi_highlight_green(false); + } else + on = off = ""; + + if (ss) + printf("\t Active: %s%s (%s)%s", + on, + strna(i->active_state), + ss, + off); + else + printf("\t Active: %s%s%s", + on, + strna(i->active_state), + off); + + if (!isempty(i->result) && !streq(i->result, "success")) + printf(" (Result: %s)", i->result); + + timestamp = (streq_ptr(i->active_state, "active") || + streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp : + (streq_ptr(i->active_state, "inactive") || + streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp : + streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp : + i->active_exit_timestamp; + + s1 = format_timestamp_pretty(since1, sizeof(since1), timestamp); + s2 = format_timestamp(since2, sizeof(since2), timestamp); + + if (s1) + printf(" since %s; %s\n", s2, s1); + else if (s2) + printf(" since %s\n", s2); + else + printf("\n"); + + if (!i->condition_result && i->condition_timestamp > 0) { + s1 = format_timestamp_pretty(since1, sizeof(since1), i->condition_timestamp); + s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp); + + if (s1) + printf("\t start condition failed at %s; %s\n", s2, s1); + else if (s2) + printf("\t start condition failed at %s\n", s2); + } + + if (i->sysfs_path) + printf("\t Device: %s\n", i->sysfs_path); + if (i->where) + printf("\t Where: %s\n", i->where); + if (i->what) + printf("\t What: %s\n", i->what); + + if (i->accept) + printf("\tAccepted: %u; Connected: %u\n", i->n_accepted, i->n_connections); + + LIST_FOREACH(exec, p, i->exec) { + char *t; + bool good; + + /* Only show exited processes here */ + if (p->code == 0) + continue; + + t = strv_join(p->argv, " "); + printf("\t Process: %u %s=%s ", p->pid, p->name, strna(t)); + free(t); + +#ifdef HAVE_SYSV_COMPAT + if (i->is_sysv) + good = is_clean_exit_lsb(p->code, p->status); + else +#endif + good = is_clean_exit(p->code, p->status); + + if (!good) { + on = ansi_highlight_red(true); + off = ansi_highlight_red(false); + } else + on = off = ""; + + printf("%s(code=%s, ", on, sigchld_code_to_string(p->code)); + + if (p->code == CLD_EXITED) { + const char *c; + + printf("status=%i", p->status); + +#ifdef HAVE_SYSV_COMPAT + if ((c = exit_status_to_string(p->status, i->is_sysv ? EXIT_STATUS_LSB : EXIT_STATUS_SYSTEMD))) +#else + if ((c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD))) +#endif + printf("/%s", c); + + } else + printf("signal=%s", signal_to_string(p->status)); + + printf(")%s\n", off); + + if (i->main_pid == p->pid && + i->start_timestamp == p->start_timestamp && + i->exit_timestamp == p->start_timestamp) + /* Let's not show this twice */ + i->main_pid = 0; + + if (p->pid == i->control_pid) + i->control_pid = 0; + } + + if (i->main_pid > 0 || i->control_pid > 0) { + printf("\t"); + + if (i->main_pid > 0) { + printf("Main PID: %u", (unsigned) i->main_pid); + + if (i->running) { + char *t = NULL; + get_process_comm(i->main_pid, &t); + if (t) { + printf(" (%s)", t); + free(t); + } + } else if (i->exit_code > 0) { + printf(" (code=%s, ", sigchld_code_to_string(i->exit_code)); + + if (i->exit_code == CLD_EXITED) { + const char *c; + + printf("status=%i", i->exit_status); + +#ifdef HAVE_SYSV_COMPAT + if ((c = exit_status_to_string(i->exit_status, i->is_sysv ? EXIT_STATUS_LSB : EXIT_STATUS_SYSTEMD))) +#else + if ((c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD))) +#endif + printf("/%s", c); + + } else + printf("signal=%s", signal_to_string(i->exit_status)); + printf(")"); + } + } + + if (i->main_pid > 0 && i->control_pid > 0) + printf(";"); + + if (i->control_pid > 0) { + char *t = NULL; + + printf(" Control: %u", (unsigned) i->control_pid); + + get_process_comm(i->control_pid, &t); + if (t) { + printf(" (%s)", t); + free(t); + } + } + + printf("\n"); + } + + if (i->status_text) + printf("\t Status: \"%s\"\n", i->status_text); + + if (i->default_control_group) { + unsigned c; + + printf("\t CGroup: %s\n", i->default_control_group); + + if (arg_transport != TRANSPORT_SSH) { + if ((c = columns()) > 18) + c -= 18; + else + c = 0; + + show_cgroup_by_path(i->default_control_group, "\t\t ", c, false); + } + } + + if (i->id && arg_transport != TRANSPORT_SSH) { + printf("\n"); + show_journal_by_unit(i->id, arg_output, NULL, 0, i->inactive_exit_timestamp_monotonic, arg_lines, arg_all, arg_follow); + } + + if (i->need_daemon_reload) + printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %s daemon-reload' recommended.\n", + ansi_highlight_red(true), + ansi_highlight_red(false), + arg_scope == UNIT_FILE_SYSTEM ? "--system" : "--user"); +} + +static int status_property(const char *name, DBusMessageIter *iter, UnitStatusInfo *i) { + + assert(name); + assert(iter); + assert(i); + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRING: { + const char *s; + + dbus_message_iter_get_basic(iter, &s); + + if (!isempty(s)) { + if (streq(name, "Id")) + i->id = s; + else if (streq(name, "LoadState")) + i->load_state = s; + else if (streq(name, "ActiveState")) + i->active_state = s; + else if (streq(name, "SubState")) + i->sub_state = s; + else if (streq(name, "Description")) + i->description = s; + else if (streq(name, "FragmentPath")) + i->path = s; +#ifdef HAVE_SYSV_COMPAT + else if (streq(name, "SysVPath")) { + i->is_sysv = true; + i->path = s; + } +#endif + else if (streq(name, "DefaultControlGroup")) + i->default_control_group = s; + else if (streq(name, "StatusText")) + i->status_text = s; + else if (streq(name, "SysFSPath")) + i->sysfs_path = s; + else if (streq(name, "Where")) + i->where = s; + else if (streq(name, "What")) + i->what = s; + else if (streq(name, "Following")) + i->following = s; + else if (streq(name, "UnitFileState")) + i->unit_file_state = s; + else if (streq(name, "Result")) + i->result = s; + } + + break; + } + + case DBUS_TYPE_BOOLEAN: { + dbus_bool_t b; + + dbus_message_iter_get_basic(iter, &b); + + if (streq(name, "Accept")) + i->accept = b; + else if (streq(name, "NeedDaemonReload")) + i->need_daemon_reload = b; + else if (streq(name, "ConditionResult")) + i->condition_result = b; + + break; + } + + case DBUS_TYPE_UINT32: { + uint32_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "MainPID")) { + if (u > 0) { + i->main_pid = (pid_t) u; + i->running = true; + } + } else if (streq(name, "ControlPID")) + i->control_pid = (pid_t) u; + else if (streq(name, "ExecMainPID")) { + if (u > 0) + i->main_pid = (pid_t) u; + } else if (streq(name, "NAccepted")) + i->n_accepted = u; + else if (streq(name, "NConnections")) + i->n_connections = u; + + break; + } + + case DBUS_TYPE_INT32: { + int32_t j; + + dbus_message_iter_get_basic(iter, &j); + + if (streq(name, "ExecMainCode")) + i->exit_code = (int) j; + else if (streq(name, "ExecMainStatus")) + i->exit_status = (int) j; + + break; + } + + case DBUS_TYPE_UINT64: { + uint64_t u; + + dbus_message_iter_get_basic(iter, &u); + + if (streq(name, "ExecMainStartTimestamp")) + i->start_timestamp = (usec_t) u; + else if (streq(name, "ExecMainExitTimestamp")) + i->exit_timestamp = (usec_t) u; + else if (streq(name, "ActiveEnterTimestamp")) + i->active_enter_timestamp = (usec_t) u; + else if (streq(name, "InactiveEnterTimestamp")) + i->inactive_enter_timestamp = (usec_t) u; + else if (streq(name, "InactiveExitTimestamp")) + i->inactive_exit_timestamp = (usec_t) u; + else if (streq(name, "InactiveExitTimestampMonotonic")) + i->inactive_exit_timestamp_monotonic = (usec_t) u; + else if (streq(name, "ActiveExitTimestamp")) + i->active_exit_timestamp = (usec_t) u; + else if (streq(name, "ConditionTimestamp")) + i->condition_timestamp = (usec_t) u; + + break; + } + + case DBUS_TYPE_ARRAY: { + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && + startswith(name, "Exec")) { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + ExecStatusInfo *info; + int r; + + if (!(info = new0(ExecStatusInfo, 1))) + return -ENOMEM; + + if (!(info->name = strdup(name))) { + free(info); + return -ENOMEM; + } + + if ((r = exec_status_info_deserialize(&sub, info)) < 0) { + free(info); + return r; + } + + LIST_PREPEND(ExecStatusInfo, exec, i->exec, info); + + dbus_message_iter_next(&sub); + } + } + + break; + } + + case DBUS_TYPE_STRUCT: { + + if (streq(name, "LoadError")) { + DBusMessageIter sub; + const char *n, *message; + int r; + + dbus_message_iter_recurse(iter, &sub); + + r = bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &n, true); + if (r < 0) + return r; + + r = bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &message, false); + if (r < 0) + return r; + + if (!isempty(message)) + i->load_error = message; + } + + break; + } + } + + return 0; +} + +static int print_property(const char *name, DBusMessageIter *iter) { + assert(name); + assert(iter); + + /* This is a low-level property printer, see + * print_status_info() for the nicer output */ + + if (arg_property && !strv_find(arg_property, name)) + return 0; + + switch (dbus_message_iter_get_arg_type(iter)) { + + case DBUS_TYPE_STRUCT: { + DBusMessageIter sub; + dbus_message_iter_recurse(iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32 && streq(name, "Job")) { + uint32_t u; + + dbus_message_iter_get_basic(&sub, &u); + + if (u) + printf("%s=%u\n", name, (unsigned) u); + else if (arg_all) + printf("%s=\n", name); + + return 0; + } else if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "Unit")) { + const char *s; + + dbus_message_iter_get_basic(&sub, &s); + + if (arg_all || s[0]) + printf("%s=%s\n", name, s); + + return 0; + } else if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING && streq(name, "LoadError")) { + const char *a = NULL, *b = NULL; + + if (bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &a, true) >= 0) + bus_iter_get_basic_and_next(&sub, DBUS_TYPE_STRING, &b, false); + + if (arg_all || !isempty(a) || !isempty(b)) + printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b)); + + return 0; + } + + break; + } + + case DBUS_TYPE_ARRAY: + + if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "EnvironmentFiles")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *path; + dbus_bool_t ignore; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_BOOLEAN, &ignore, false) >= 0) + printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore)); + + dbus_message_iter_next(&sub); + } + + return 0; + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Paths")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *type, *path; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, false) >= 0) + printf("%s=%s\n", type, path); + + dbus_message_iter_next(&sub); + } + + return 0; + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Timers")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *base; + uint64_t value, next_elapse; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &base, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &value, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &next_elapse, false) >= 0) { + char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX]; + + printf("%s={ value=%s ; next_elapse=%s }\n", + base, + format_timespan(timespan1, sizeof(timespan1), value), + format_timespan(timespan2, sizeof(timespan2), next_elapse)); + } + + dbus_message_iter_next(&sub); + } + + return 0; + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "ControlGroupAttributes")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *controller, *attr, *value; + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &controller, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &attr, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &value, false) >= 0) { + + printf("ControlGroupAttribute={ controller=%s ; attribute=%s ; value=\"%s\" }\n", + controller, + attr, + value); + } + + dbus_message_iter_next(&sub); + } + + return 0; + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && startswith(name, "Exec")) { + DBusMessageIter sub; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + ExecStatusInfo info; + + zero(info); + if (exec_status_info_deserialize(&sub, &info) >= 0) { + char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX]; + char *t; + + t = strv_join(info.argv, " "); + + printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n", + name, + strna(info.path), + strna(t), + yes_no(info.ignore), + strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)), + strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)), + (unsigned) info. pid, + sigchld_code_to_string(info.code), + info.status, + info.code == CLD_EXITED ? "" : "/", + strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status))); + + free(t); + } + + free(info.path); + strv_free(info.argv); + + dbus_message_iter_next(&sub); + } + + return 0; + } + + break; + } + + if (generic_print_property(name, iter, arg_all) > 0) + return 0; + + if (arg_all) + printf("%s=[unprintable]\n", name); + + return 0; +} + +static int show_one(const char *verb, DBusConnection *bus, const char *path, bool show_properties, bool *new_line) { + DBusMessage *m = NULL, *reply = NULL; + const char *interface = ""; + int r; + DBusError error; + DBusMessageIter iter, sub, sub2, sub3; + UnitStatusInfo info; + ExecStatusInfo *p; + + assert(bus); + assert(path); + assert(new_line); + + zero(info); + dbus_error_init(&error); + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "GetAll"))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (*new_line) + printf("\n"); + + *new_line = true; + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *name; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub2, &sub3); + + if (show_properties) + r = print_property(name, &sub3); + else + r = status_property(name, &sub3, &info); + + if (r < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_next(&sub); + } + + r = 0; + + if (!show_properties) + print_status_info(&info); + + if (!streq_ptr(info.active_state, "active") && + !streq_ptr(info.active_state, "reloading") && + streq(verb, "status")) + /* According to LSB: "program not running" */ + r = 3; + + while ((p = info.exec)) { + LIST_REMOVE(ExecStatusInfo, exec, info.exec, p); + exec_status_info_free(p); + } + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int show(DBusConnection *bus, char **args) { + DBusMessage *m = NULL, *reply = NULL; + int r, ret = 0; + DBusError error; + bool show_properties, new_line = false; + char **name; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + show_properties = !streq(args[0], "status"); + + if (show_properties) + pager_open_if_enabled(); + + if (show_properties && strv_length(args) <= 1) { + /* If not argument is specified inspect the manager + * itself */ + + ret = show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line); + goto finish; + } + + STRV_FOREACH(name, args+1) { + const char *path = NULL; + uint32_t id; + + if (safe_atou32(*name, &id) < 0) { + + /* Interpret as unit name */ + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "LoadUnit"))) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, name, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + + if (!dbus_error_has_name(&error, DBUS_ERROR_ACCESS_DENIED)) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + + dbus_error_free(&error); + + dbus_message_unref(m); + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnit"))) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, name, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + + if (dbus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT)) + ret = 4; /* According to LSB: "program or service status is unknown" */ + else + ret = -EIO; + goto finish; + } + } + + } else if (show_properties) { + + /* Interpret as job id */ + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetJob"))) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_UINT32, &id, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + } else { + + /* Interpret as PID */ + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnitByPID"))) { + log_error("Could not allocate message."); + ret = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_UINT32, &id, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + ret = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + ret = -EIO; + goto finish; + } + + if ((r = show_one(args[0], bus, path, show_properties, &new_line)) != 0) + ret = r; + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + } + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return ret; +} + +static int dump(DBusConnection *bus, char **args) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; + const char *text; + + dbus_error_init(&error); + + pager_open_if_enabled(); + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "Dump"))) { + log_error("Could not allocate message."); + return -ENOMEM; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + fputs(text, stdout); + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int snapshot(DBusConnection *bus, char **args) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; + const char *name = "", *path, *id; + dbus_bool_t cleanup = FALSE; + DBusMessageIter iter, sub; + const char + *interface = "org.freedesktop.systemd1.Unit", + *property = "Id"; + + dbus_error_init(&error); + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "CreateSnapshot"))) { + log_error("Could not allocate message."); + return -ENOMEM; + } + + if (strv_length(args) > 1) + name = args[1]; + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_BOOLEAN, &cleanup, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(m); + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get"))) { + log_error("Could not allocate message."); + return -ENOMEM; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + dbus_message_unref(reply); + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_get_basic(&sub, &id); + + if (!arg_quiet) + puts(id); + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int delete_snapshot(DBusConnection *bus, char **args) { + DBusMessage *m = NULL, *reply = NULL; + int r; + DBusError error; + char **name; + + assert(bus); + assert(args); + + dbus_error_init(&error); + + STRV_FOREACH(name, args+1) { + const char *path = NULL; + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnit"))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, name, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(m); + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + path, + "org.freedesktop.systemd1.Snapshot", + "Remove"))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + dbus_message_unref(reply); + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int daemon_reload(DBusConnection *bus, char **args) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; + const char *method; + + dbus_error_init(&error); + + if (arg_action == ACTION_RELOAD) + method = "Reload"; + else if (arg_action == ACTION_REEXEC) + method = "Reexecute"; + else { + assert(arg_action == ACTION_SYSTEMCTL); + + method = + streq(args[0], "clear-jobs") || + streq(args[0], "cancel") ? "ClearJobs" : + streq(args[0], "daemon-reexec") ? "Reexecute" : + streq(args[0], "reset-failed") ? "ResetFailed" : + streq(args[0], "halt") ? "Halt" : + streq(args[0], "poweroff") ? "PowerOff" : + streq(args[0], "reboot") ? "Reboot" : + streq(args[0], "kexec") ? "KExec" : + streq(args[0], "exit") ? "Exit" : + /* "daemon-reload" */ "Reload"; + } + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + method))) { + log_error("Could not allocate message."); + return -ENOMEM; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + + if (arg_action != ACTION_SYSTEMCTL && error_is_no_service(&error)) { + /* There's always a fallback possible for + * legacy actions. */ + r = -EADDRNOTAVAIL; + goto finish; + } + + if (streq(method, "Reexecute") && dbus_error_has_name(&error, DBUS_ERROR_NO_REPLY)) { + /* On reexecution, we expect a disconnect, not + * a reply */ + r = 0; + goto finish; + } + + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int reset_failed(DBusConnection *bus, char **args) { + DBusMessage *m = NULL; + int r; + DBusError error; + char **name; + + assert(bus); + dbus_error_init(&error); + + if (strv_length(args) <= 1) + return daemon_reload(bus, args); + + STRV_FOREACH(name, args+1) { + DBusMessage *reply; + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "ResetFailedUnit"))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, name, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + dbus_error_free(&error); + + return r; +} + +static int show_enviroment(DBusConnection *bus, char **args) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + DBusMessageIter iter, sub, sub2; + int r; + const char + *interface = "org.freedesktop.systemd1.Manager", + *property = "Environment"; + + dbus_error_init(&error); + + pager_open_if_enabled(); + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.DBus.Properties", + "Get"))) { + log_error("Could not allocate message."); + return -ENOMEM; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + while (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_INVALID) { + const char *text; + + if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_get_basic(&sub2, &text); + printf("%s\n", text); + + dbus_message_iter_next(&sub2); + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int set_environment(DBusConnection *bus, char **args) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int r; + const char *method; + DBusMessageIter iter, sub; + char **name; + + dbus_error_init(&error); + + method = streq(args[0], "set-environment") + ? "SetEnvironment" + : "UnsetEnvironment"; + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + method))) { + + log_error("Could not allocate message."); + return -ENOMEM; + } + + dbus_message_iter_init_append(m, &iter); + + if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + STRV_FOREACH(name, args+1) + if (!dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, name)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int enable_sysv_units(char **args) { + int r = 0; + +#if defined (HAVE_SYSV_COMPAT) && (defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_SUSE) || defined(TARGET_MEEGO) || defined(TARGET_ALTLINUX) || defined(TARGET_MAGEIA)) + const char *verb = args[0]; + unsigned f = 1, t = 1; + LookupPaths paths; + + if (arg_scope != UNIT_FILE_SYSTEM) + return 0; + + if (!streq(verb, "enable") && + !streq(verb, "disable") && + !streq(verb, "is-enabled")) + return 0; + + /* Processes all SysV units, and reshuffles the array so that + * afterwards only the native units remain */ + + zero(paths); + r = lookup_paths_init(&paths, MANAGER_SYSTEM, false); + if (r < 0) + return r; + + r = 0; + + for (f = 1; args[f]; f++) { + const char *name; + char *p; + bool found_native = false, found_sysv; + unsigned c = 1; + const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL }; + char **k, *l, *q = NULL; + int j; + pid_t pid; + siginfo_t status; + + name = args[f]; + + if (!endswith(name, ".service")) + continue; + + if (path_is_absolute(name)) + continue; + + STRV_FOREACH(k, paths.unit_path) { + p = NULL; + + if (!isempty(arg_root)) + asprintf(&p, "%s/%s/%s", arg_root, *k, name); + else + asprintf(&p, "%s/%s", *k, name); + + if (!p) { + log_error("No memory"); + r = -ENOMEM; + goto finish; + } + + found_native = access(p, F_OK) >= 0; + free(p); + + if (found_native) + break; + } + + if (found_native) + continue; + + p = NULL; + if (!isempty(arg_root)) + asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name); + else + asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name); + if (!p) { + log_error("No memory"); + r = -ENOMEM; + goto finish; + } + + p[strlen(p) - sizeof(".service") + 1] = 0; + found_sysv = access(p, F_OK) >= 0; + + if (!found_sysv) { + free(p); + continue; + } + + /* Mark this entry, so that we don't try enabling it as native unit */ + args[f] = (char*) ""; + + log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name); + + if (!isempty(arg_root)) + argv[c++] = q = strappend("--root=", arg_root); + + argv[c++] = file_name_from_path(p); + argv[c++] = + streq(verb, "enable") ? "on" : + streq(verb, "disable") ? "off" : "--level=5"; + argv[c] = NULL; + + l = strv_join((char**)argv, " "); + if (!l) { + log_error("No memory."); + free(q); + free(p); + r = -ENOMEM; + goto finish; + } + + log_info("Executing %s", l); + free(l); + + pid = fork(); + if (pid < 0) { + log_error("Failed to fork: %m"); + free(p); + free(q); + r = -errno; + goto finish; + } else if (pid == 0) { + /* Child */ + + execv(argv[0], (char**) argv); + _exit(EXIT_FAILURE); + } + + free(p); + free(q); + + j = wait_for_terminate(pid, &status); + if (j < 0) { + log_error("Failed to wait for child: %s", strerror(-r)); + r = j; + goto finish; + } + + if (status.si_code == CLD_EXITED) { + if (streq(verb, "is-enabled")) { + if (status.si_status == 0) { + if (!arg_quiet) + puts("enabled"); + r = 1; + } else { + if (!arg_quiet) + puts("disabled"); + } + + } else if (status.si_status != 0) { + r = -EINVAL; + goto finish; + } + } else { + r = -EPROTO; + goto finish; + } + } + +finish: + lookup_paths_free(&paths); + + /* Drop all SysV units */ + for (f = 1, t = 1; args[f]; f++) { + + if (isempty(args[f])) + continue; + + args[t++] = args[f]; + } + + args[t] = NULL; + +#endif + return r; +} + +static int enable_unit(DBusConnection *bus, char **args) { + const char *verb = args[0]; + UnitFileChange *changes = NULL; + unsigned n_changes = 0, i; + int carries_install_info = -1; + DBusMessage *m = NULL, *reply = NULL; + int r; + DBusError error; + + r = enable_sysv_units(args); + if (r < 0) + return r; + + if (!args[1]) + return 0; + + dbus_error_init(&error); + + if (!bus || avoid_bus()) { + if (streq(verb, "enable")) { + r = unit_file_enable(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + carries_install_info = r; + } else if (streq(verb, "disable")) + r = unit_file_disable(arg_scope, arg_runtime, arg_root, args+1, &changes, &n_changes); + else if (streq(verb, "reenable")) { + r = unit_file_reenable(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + carries_install_info = r; + } else if (streq(verb, "link")) + r = unit_file_link(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + else if (streq(verb, "preset")) { + r = unit_file_preset(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + carries_install_info = r; + } else if (streq(verb, "mask")) + r = unit_file_mask(arg_scope, arg_runtime, arg_root, args+1, arg_force, &changes, &n_changes); + else if (streq(verb, "unmask")) + r = unit_file_unmask(arg_scope, arg_runtime, arg_root, args+1, &changes, &n_changes); + else + assert_not_reached("Unknown verb"); + + if (r < 0) { + log_error("Operation failed: %s", strerror(-r)); + goto finish; + } + + if (!arg_quiet) { + for (i = 0; i < n_changes; i++) { + if (changes[i].type == UNIT_FILE_SYMLINK) + log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path); + else + log_info("rm '%s'", changes[i].path); + } + } + + } else { + const char *method; + bool send_force = true, expect_carries_install_info = false; + dbus_bool_t a, b; + DBusMessageIter iter, sub, sub2; + + if (streq(verb, "enable")) { + method = "EnableUnitFiles"; + expect_carries_install_info = true; + } else if (streq(verb, "disable")) { + method = "DisableUnitFiles"; + send_force = false; + } else if (streq(verb, "reenable")) { + method = "ReenableUnitFiles"; + expect_carries_install_info = true; + } else if (streq(verb, "link")) + method = "LinkUnitFiles"; + else if (streq(verb, "preset")) { + method = "PresetUnitFiles"; + expect_carries_install_info = true; + } else if (streq(verb, "mask")) + method = "MaskUnitFiles"; + else if (streq(verb, "unmask")) { + method = "UnmaskUnitFiles"; + send_force = false; + } else + assert_not_reached("Unknown verb"); + + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + method); + if (!m) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + dbus_message_iter_init_append(m, &iter); + + r = bus_append_strv_iter(&iter, args+1); + if (r < 0) { + log_error("Failed to append unit files."); + goto finish; + } + + a = arg_runtime; + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &a)) { + log_error("Failed to append runtime boolean."); + r = -ENOMEM; + goto finish; + } + + if (send_force) { + b = arg_force; + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &b)) { + log_error("Failed to append force boolean."); + r = -ENOMEM; + goto finish; + } + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter)) { + log_error("Failed to initialize iterator."); + goto finish; + } + + if (expect_carries_install_info) { + r = bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &b, true); + if (r < 0) { + log_error("Failed to parse reply."); + goto finish; + } + + carries_install_info = b; + } + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + const char *type, *path, *source; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&sub, &sub2); + + if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, true) < 0 || + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &source, false) < 0) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + if (!arg_quiet) { + if (streq(type, "symlink")) + log_info("ln -s '%s' '%s'", source, path); + else + log_info("rm '%s'", path); + } + + dbus_message_iter_next(&sub); + } + + /* Try to reload if enabeld */ + if (!arg_no_reload) + r = daemon_reload(bus, args); + } + + if (carries_install_info == 0) + log_warning("Warning: unit files do not carry install information. No operation executed."); + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + unit_file_changes_free(changes, n_changes); + + dbus_error_free(&error); + return r; +} + +static int unit_is_enabled(DBusConnection *bus, char **args) { + DBusError error; + int r; + DBusMessage *m = NULL, *reply = NULL; + bool enabled; + char **name; + + dbus_error_init(&error); + + r = enable_sysv_units(args); + if (r < 0) + return r; + + enabled = r > 0; + + if (!bus || avoid_bus()) { + + STRV_FOREACH(name, args+1) { + UnitFileState state; + + state = unit_file_get_state(arg_scope, arg_root, *name); + if (state < 0) { + r = state; + goto finish; + } + + if (state == UNIT_FILE_ENABLED || + state == UNIT_FILE_ENABLED_RUNTIME || + state == UNIT_FILE_STATIC) + enabled = true; + + if (!arg_quiet) + puts(unit_file_state_to_string(state)); + } + + } else { + STRV_FOREACH(name, args+1) { + const char *s; + + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnitFileState"); + if (!m) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, name, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_STRING, &s, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + + if (streq(s, "enabled") || + streq(s, "enabled-runtime") || + streq(s, "static")) + enabled = true; + + if (!arg_quiet) + puts(s); + } + } + + r = enabled ? 0 : 1; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + return r; +} + +static int systemctl_help(void) { + + pager_open_if_enabled(); + + printf("%s [OPTIONS...] {COMMAND} ...\n\n" + "Query or send control commands to the systemd manager.\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " -t --type=TYPE List only units of a particular type\n" + " -p --property=NAME Show only properties by this name\n" + " -a --all Show all units/properties, including dead/empty ones\n" + " --failed Show only failed units\n" + " --full Don't ellipsize unit names on output\n" + " --fail When queueing a new job, fail if conflicting jobs are\n" + " pending\n" + " --ignore-dependencies\n" + " When queueing a new job, ignore all its dependencies\n" + " --kill-who=WHO Who to send signal to\n" + " -s --signal=SIGNAL Which signal to send\n" + " -H --host=[USER@]HOST\n" + " Show information for remote host\n" + " -P --privileged Acquire privileges before execution\n" + " -q --quiet Suppress output\n" + " --no-block Do not wait until operation finished\n" + " --no-wall Don't send wall message before halt/power-off/reboot\n" + " --no-reload When enabling/disabling unit files, don't reload daemon\n" + " configuration\n" + " --no-legend Do not print a legend (column headers and hints)\n" + " --no-pager Do not pipe output into a pager\n" + " --no-ask-password\n" + " Do not ask for system passwords\n" + " --order When generating graph for dot, show only order\n" + " --require When generating graph for dot, show only requirement\n" + " --system Connect to system manager\n" + " --user Connect to user service manager\n" + " --global Enable/disable unit files globally\n" + " -f --force When enabling unit files, override existing symlinks\n" + " When shutting down, execute action immediately\n" + " --root=PATH Enable unit files in the specified root directory\n" + " --runtime Enable unit files only temporarily until next reboot\n" + " -n --lines=INTEGER Journal entries to show\n" + " --follow Follow journal\n" + " -o --output=STRING Change journal output mode (short, short-monotonic,\n" + " verbose, export, json, cat)\n\n" + "Unit Commands:\n" + " list-units List loaded units\n" + " start [NAME...] Start (activate) one or more units\n" + " stop [NAME...] Stop (deactivate) one or more units\n" + " reload [NAME...] Reload one or more units\n" + " restart [NAME...] Start or restart one or more units\n" + " try-restart [NAME...] Restart one or more units if active\n" + " reload-or-restart [NAME...] Reload one or more units is possible,\n" + " otherwise start or restart\n" + " reload-or-try-restart [NAME...] Reload one or more units is possible,\n" + " otherwise restart if active\n" + " isolate [NAME] Start one unit and stop all others\n" + " kill [NAME...] Send signal to processes of a unit\n" + " is-active [NAME...] Check whether units are active\n" + " status [NAME...|PID...] Show runtime status of one or more units\n" + " show [NAME...|JOB...] Show properties of one or more\n" + " units/jobs or the manager\n" + " reset-failed [NAME...] Reset failed state for all, one, or more\n" + " units\n" + " load [NAME...] Load one or more units\n\n" + "Unit File Commands:\n" + " list-unit-files List installed unit files\n" + " enable [NAME...] Enable one or more unit files\n" + " disable [NAME...] Disable one or more unit files\n" + " reenable [NAME...] Reenable one or more unit files\n" + " preset [NAME...] Enable/disable one or more unit files\n" + " based on preset configuration\n" + " mask [NAME...] Mask one or more units\n" + " unmask [NAME...] Unmask one or more units\n" + " link [PATH...] Link one or more units files into\n" + " the search path\n" + " is-enabled [NAME...] Check whether unit files are enabled\n\n" + "Job Commands:\n" + " list-jobs List jobs\n" + " cancel [JOB...] Cancel all, one, or more jobs\n\n" + "Status Commands:\n" + " dump Dump server status\n" + " dot Dump dependency graph for dot(1)\n\n" + "Snapshot Commands:\n" + " snapshot [NAME] Create a snapshot\n" + " delete [NAME...] Remove one or more snapshots\n\n" + "Environment Commands:\n" + " show-environment Dump environment\n" + " set-environment [NAME=VALUE...] Set one or more environment variables\n" + " unset-environment [NAME...] Unset one or more environment variables\n\n" + "Manager Lifecycle Commands:\n" + " daemon-reload Reload systemd manager configuration\n" + " daemon-reexec Reexecute systemd manager\n\n" + "System Commands:\n" + " default Enter system default mode\n" + " rescue Enter system rescue mode\n" + " emergency Enter system emergency mode\n" + " halt Shut down and halt the system\n" + " poweroff Shut down and power-off the system\n" + " reboot Shut down and reboot the system\n" + " kexec Shut down and reboot the system with kexec\n" + " exit Ask for user instance termination\n", + program_invocation_short_name); + + return 0; +} + +static int halt_help(void) { + + printf("%s [OPTIONS...]\n\n" + "%s the system.\n\n" + " --help Show this help\n" + " --halt Halt the machine\n" + " -p --poweroff Switch off the machine\n" + " --reboot Reboot the machine\n" + " -f --force Force immediate halt/power-off/reboot\n" + " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n" + " -d --no-wtmp Don't write wtmp record\n" + " -n --no-sync Don't sync before halt/power-off/reboot\n" + " --no-wall Don't send wall message before halt/power-off/reboot\n", + program_invocation_short_name, + arg_action == ACTION_REBOOT ? "Reboot" : + arg_action == ACTION_POWEROFF ? "Power off" : + "Halt"); + + return 0; +} + +static int shutdown_help(void) { + + printf("%s [OPTIONS...] [TIME] [WALL...]\n\n" + "Shut down the system.\n\n" + " --help Show this help\n" + " -H --halt Halt the machine\n" + " -P --poweroff Power-off the machine\n" + " -r --reboot Reboot the machine\n" + " -h Equivalent to --poweroff, overriden by --halt\n" + " -k Don't halt/power-off/reboot, just send warnings\n" + " --no-wall Don't send wall message before halt/power-off/reboot\n" + " -c Cancel a pending shutdown\n", + program_invocation_short_name); + + return 0; +} + +static int telinit_help(void) { + + printf("%s [OPTIONS...] {COMMAND}\n\n" + "Send control commands to the init daemon.\n\n" + " --help Show this help\n" + " --no-wall Don't send wall message before halt/power-off/reboot\n\n" + "Commands:\n" + " 0 Power-off the machine\n" + " 6 Reboot the machine\n" + " 2, 3, 4, 5 Start runlevelX.target unit\n" + " 1, s, S Enter rescue mode\n" + " q, Q Reload init daemon configuration\n" + " u, U Reexecute init daemon\n", + program_invocation_short_name); + + return 0; +} + +static int runlevel_help(void) { + + printf("%s [OPTIONS...]\n\n" + "Prints the previous and current runlevel of the init system.\n\n" + " --help Show this help\n", + program_invocation_short_name); + + return 0; +} + +static int systemctl_parse_argv(int argc, char *argv[]) { + + enum { + ARG_FAIL = 0x100, + ARG_IGNORE_DEPENDENCIES, + ARG_VERSION, + ARG_USER, + ARG_SYSTEM, + ARG_GLOBAL, + ARG_NO_BLOCK, + ARG_NO_LEGEND, + ARG_NO_PAGER, + ARG_NO_WALL, + ARG_ORDER, + ARG_REQUIRE, + ARG_ROOT, + ARG_FULL, + ARG_NO_RELOAD, + ARG_KILL_MODE, + ARG_KILL_WHO, + ARG_NO_ASK_PASSWORD, + ARG_FAILED, + ARG_RUNTIME, + ARG_FOLLOW + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "type", required_argument, NULL, 't' }, + { "property", required_argument, NULL, 'p' }, + { "all", no_argument, NULL, 'a' }, + { "failed", no_argument, NULL, ARG_FAILED }, + { "full", no_argument, NULL, ARG_FULL }, + { "fail", no_argument, NULL, ARG_FAIL }, + { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, + { "user", no_argument, NULL, ARG_USER }, + { "system", no_argument, NULL, ARG_SYSTEM }, + { "global", no_argument, NULL, ARG_GLOBAL }, + { "no-block", no_argument, NULL, ARG_NO_BLOCK }, + { "no-legend", no_argument, NULL, ARG_NO_LEGEND }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "no-wall", no_argument, NULL, ARG_NO_WALL }, + { "quiet", no_argument, NULL, 'q' }, + { "order", no_argument, NULL, ARG_ORDER }, + { "require", no_argument, NULL, ARG_REQUIRE }, + { "root", required_argument, NULL, ARG_ROOT }, + { "force", no_argument, NULL, 'f' }, + { "no-reload", no_argument, NULL, ARG_NO_RELOAD }, + { "kill-mode", required_argument, NULL, ARG_KILL_MODE }, /* undocumented on purpose */ + { "kill-who", required_argument, NULL, ARG_KILL_WHO }, + { "signal", required_argument, NULL, 's' }, + { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, + { "host", required_argument, NULL, 'H' }, + { "privileged",no_argument, NULL, 'P' }, + { "runtime", no_argument, NULL, ARG_RUNTIME }, + { "lines", required_argument, NULL, 'n' }, + { "follow", no_argument, NULL, ARG_FOLLOW }, + { "output", required_argument, NULL, 'o' }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + /* Only when running as systemctl we ask for passwords */ + arg_ask_password = true; + + while ((c = getopt_long(argc, argv, "ht:p:aqfs:H:Pn:o:", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + systemctl_help(); + return 0; + + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(DISTRIBUTION); + puts(SYSTEMD_FEATURES); + return 0; + + case 't': + arg_type = optarg; + break; + + case 'p': { + char **l; + + if (!(l = strv_append(arg_property, optarg))) + return -ENOMEM; + + strv_free(arg_property); + arg_property = l; + + /* If the user asked for a particular + * property, show it to him, even if it is + * empty. */ + arg_all = true; + break; + } + + case 'a': + arg_all = true; + break; + + case ARG_FAIL: + arg_job_mode = "fail"; + break; + + case ARG_IGNORE_DEPENDENCIES: + arg_job_mode = "ignore-dependencies"; + break; + + case ARG_USER: + arg_scope = UNIT_FILE_USER; + break; + + case ARG_SYSTEM: + arg_scope = UNIT_FILE_SYSTEM; + break; + + case ARG_GLOBAL: + arg_scope = UNIT_FILE_GLOBAL; + break; + + case ARG_NO_BLOCK: + arg_no_block = true; + break; + + case ARG_NO_LEGEND: + arg_no_legend = true; + break; + + case ARG_NO_PAGER: + arg_no_pager = true; + break; + + case ARG_NO_WALL: + arg_no_wall = true; + break; + + case ARG_ORDER: + arg_dot = DOT_ORDER; + break; + + case ARG_REQUIRE: + arg_dot = DOT_REQUIRE; + break; + + case ARG_ROOT: + arg_root = optarg; + break; + + case ARG_FULL: + arg_full = true; + break; + + case ARG_FAILED: + arg_failed = true; + break; + + case 'q': + arg_quiet = true; + break; + + case 'f': + arg_force = true; + break; + + case ARG_NO_RELOAD: + arg_no_reload = true; + break; + + case ARG_KILL_WHO: + arg_kill_who = optarg; + break; + + case ARG_KILL_MODE: + arg_kill_mode = optarg; + break; + + case 's': + if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) { + log_error("Failed to parse signal string %s.", optarg); + return -EINVAL; + } + break; + + case ARG_NO_ASK_PASSWORD: + arg_ask_password = false; + break; + + case 'P': + arg_transport = TRANSPORT_POLKIT; + break; + + case 'H': + arg_transport = TRANSPORT_SSH; + arg_host = optarg; + break; + + case ARG_RUNTIME: + arg_runtime = true; + break; + + case 'n': + if (safe_atou(optarg, &arg_lines) < 0) { + log_error("Failed to parse lines '%s'", optarg); + return -EINVAL; + } + break; + + case ARG_FOLLOW: + arg_follow = true; + break; + + case 'o': + arg_output = output_mode_from_string(optarg); + if (arg_output < 0) { + log_error("Unknown output '%s'.", optarg); + return -EINVAL; + } + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (arg_transport != TRANSPORT_NORMAL && arg_scope != UNIT_FILE_SYSTEM) { + log_error("Cannot access user instance remotely."); + return -EINVAL; + } + + return 1; +} + +static int halt_parse_argv(int argc, char *argv[]) { + + enum { + ARG_HELP = 0x100, + ARG_HALT, + ARG_REBOOT, + ARG_NO_WALL + }; + + static const struct option options[] = { + { "help", no_argument, NULL, ARG_HELP }, + { "halt", no_argument, NULL, ARG_HALT }, + { "poweroff", no_argument, NULL, 'p' }, + { "reboot", no_argument, NULL, ARG_REBOOT }, + { "force", no_argument, NULL, 'f' }, + { "wtmp-only", no_argument, NULL, 'w' }, + { "no-wtmp", no_argument, NULL, 'd' }, + { "no-sync", no_argument, NULL, 'n' }, + { "no-wall", no_argument, NULL, ARG_NO_WALL }, + { NULL, 0, NULL, 0 } + }; + + int c, runlevel; + + assert(argc >= 0); + assert(argv); + + if (utmp_get_runlevel(&runlevel, NULL) >= 0) + if (runlevel == '0' || runlevel == '6') + arg_immediate = true; + + while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) { + switch (c) { + + case ARG_HELP: + halt_help(); + return 0; + + case ARG_HALT: + arg_action = ACTION_HALT; + break; + + case 'p': + if (arg_action != ACTION_REBOOT) + arg_action = ACTION_POWEROFF; + break; + + case ARG_REBOOT: + arg_action = ACTION_REBOOT; + break; + + case 'f': + arg_immediate = true; + break; + + case 'w': + arg_dry = true; + break; + + case 'd': + arg_no_wtmp = true; + break; + + case 'n': + arg_no_sync = true; + break; + + case ARG_NO_WALL: + arg_no_wall = true; + break; + + case 'i': + case 'h': + /* Compatibility nops */ + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind < argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + return 1; +} + +static int parse_time_spec(const char *t, usec_t *_u) { + assert(t); + assert(_u); + + if (streq(t, "now")) + *_u = 0; + else if (!strchr(t, ':')) { + uint64_t u; + + if (safe_atou64(t, &u) < 0) + return -EINVAL; + + *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u; + } else { + char *e = NULL; + long hour, minute; + struct tm tm; + time_t s; + usec_t n; + + errno = 0; + hour = strtol(t, &e, 10); + if (errno != 0 || *e != ':' || hour < 0 || hour > 23) + return -EINVAL; + + minute = strtol(e+1, &e, 10); + if (errno != 0 || *e != 0 || minute < 0 || minute > 59) + return -EINVAL; + + n = now(CLOCK_REALTIME); + s = (time_t) (n / USEC_PER_SEC); + + zero(tm); + assert_se(localtime_r(&s, &tm)); + + tm.tm_hour = (int) hour; + tm.tm_min = (int) minute; + tm.tm_sec = 0; + + assert_se(s = mktime(&tm)); + + *_u = (usec_t) s * USEC_PER_SEC; + + while (*_u <= n) + *_u += USEC_PER_DAY; + } + + return 0; +} + +static int shutdown_parse_argv(int argc, char *argv[]) { + + enum { + ARG_HELP = 0x100, + ARG_NO_WALL + }; + + static const struct option options[] = { + { "help", no_argument, NULL, ARG_HELP }, + { "halt", no_argument, NULL, 'H' }, + { "poweroff", no_argument, NULL, 'P' }, + { "reboot", no_argument, NULL, 'r' }, + { "no-wall", no_argument, NULL, ARG_NO_WALL }, + { NULL, 0, NULL, 0 } + }; + + int c, r; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) { + switch (c) { + + case ARG_HELP: + shutdown_help(); + return 0; + + case 'H': + arg_action = ACTION_HALT; + break; + + case 'P': + arg_action = ACTION_POWEROFF; + break; + + case 'r': + if (kexec_loaded()) + arg_action = ACTION_KEXEC; + else + arg_action = ACTION_REBOOT; + break; + + case 'h': + if (arg_action != ACTION_HALT) + arg_action = ACTION_POWEROFF; + break; + + case 'k': + arg_dry = true; + break; + + case ARG_NO_WALL: + arg_no_wall = true; + break; + + case 't': + case 'a': + /* Compatibility nops */ + break; + + case 'c': + arg_action = ACTION_CANCEL_SHUTDOWN; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (argc > optind) { + if ((r = parse_time_spec(argv[optind], &arg_when)) < 0) { + log_error("Failed to parse time specification: %s", argv[optind]); + return r; + } + } else + arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE; + + /* We skip the time argument */ + if (argc > optind + 1) + arg_wall = argv + optind + 1; + + optind = argc; + + return 1; +} + +static int telinit_parse_argv(int argc, char *argv[]) { + + enum { + ARG_HELP = 0x100, + ARG_NO_WALL + }; + + static const struct option options[] = { + { "help", no_argument, NULL, ARG_HELP }, + { "no-wall", no_argument, NULL, ARG_NO_WALL }, + { NULL, 0, NULL, 0 } + }; + + static const struct { + char from; + enum action to; + } table[] = { + { '0', ACTION_POWEROFF }, + { '6', ACTION_REBOOT }, + { '1', ACTION_RESCUE }, + { '2', ACTION_RUNLEVEL2 }, + { '3', ACTION_RUNLEVEL3 }, + { '4', ACTION_RUNLEVEL4 }, + { '5', ACTION_RUNLEVEL5 }, + { 's', ACTION_RESCUE }, + { 'S', ACTION_RESCUE }, + { 'q', ACTION_RELOAD }, + { 'Q', ACTION_RELOAD }, + { 'u', ACTION_REEXEC }, + { 'U', ACTION_REEXEC } + }; + + unsigned i; + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) { + switch (c) { + + case ARG_HELP: + telinit_help(); + return 0; + + case ARG_NO_WALL: + arg_no_wall = true; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind >= argc) { + telinit_help(); + return -EINVAL; + } + + if (optind + 1 < argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + if (strlen(argv[optind]) != 1) { + log_error("Expected single character argument."); + return -EINVAL; + } + + for (i = 0; i < ELEMENTSOF(table); i++) + if (table[i].from == argv[optind][0]) + break; + + if (i >= ELEMENTSOF(table)) { + log_error("Unknown command %s.", argv[optind]); + return -EINVAL; + } + + arg_action = table[i].to; + + optind ++; + + return 1; +} + +static int runlevel_parse_argv(int argc, char *argv[]) { + + enum { + ARG_HELP = 0x100, + }; + + static const struct option options[] = { + { "help", no_argument, NULL, ARG_HELP }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) { + switch (c) { + + case ARG_HELP: + runlevel_help(); + return 0; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind < argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + return 1; +} + +static int parse_argv(int argc, char *argv[]) { + assert(argc >= 0); + assert(argv); + + if (program_invocation_short_name) { + + if (strstr(program_invocation_short_name, "halt")) { + arg_action = ACTION_HALT; + return halt_parse_argv(argc, argv); + } else if (strstr(program_invocation_short_name, "poweroff")) { + arg_action = ACTION_POWEROFF; + return halt_parse_argv(argc, argv); + } else if (strstr(program_invocation_short_name, "reboot")) { + if (kexec_loaded()) + arg_action = ACTION_KEXEC; + else + arg_action = ACTION_REBOOT; + return halt_parse_argv(argc, argv); + } else if (strstr(program_invocation_short_name, "shutdown")) { + arg_action = ACTION_POWEROFF; + return shutdown_parse_argv(argc, argv); + } else if (strstr(program_invocation_short_name, "init")) { + + if (sd_booted() > 0) { + arg_action = ACTION_INVALID; + return telinit_parse_argv(argc, argv); + } else { + /* Hmm, so some other init system is + * running, we need to forward this + * request to it. For now we simply + * guess that it is Upstart. */ + + execv("/lib/upstart/telinit", argv); + + log_error("Couldn't find an alternative telinit implementation to spawn."); + return -EIO; + } + + } else if (strstr(program_invocation_short_name, "runlevel")) { + arg_action = ACTION_RUNLEVEL; + return runlevel_parse_argv(argc, argv); + } + } + + arg_action = ACTION_SYSTEMCTL; + return systemctl_parse_argv(argc, argv); +} + +static int action_to_runlevel(void) { + + static const char table[_ACTION_MAX] = { + [ACTION_HALT] = '0', + [ACTION_POWEROFF] = '0', + [ACTION_REBOOT] = '6', + [ACTION_RUNLEVEL2] = '2', + [ACTION_RUNLEVEL3] = '3', + [ACTION_RUNLEVEL4] = '4', + [ACTION_RUNLEVEL5] = '5', + [ACTION_RESCUE] = '1' + }; + + assert(arg_action < _ACTION_MAX); + + return table[arg_action]; +} + +static int talk_upstart(void) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + int previous, rl, r; + char + env1_buf[] = "RUNLEVEL=X", + env2_buf[] = "PREVLEVEL=X"; + char *env1 = env1_buf, *env2 = env2_buf; + const char *emit = "runlevel"; + dbus_bool_t b_false = FALSE; + DBusMessageIter iter, sub; + DBusConnection *bus; + + dbus_error_init(&error); + + if (!(rl = action_to_runlevel())) + return 0; + + if (utmp_get_runlevel(&previous, NULL) < 0) + previous = 'N'; + + if (!(bus = dbus_connection_open_private("unix:abstract=/com/ubuntu/upstart", &error))) { + if (dbus_error_has_name(&error, DBUS_ERROR_NO_SERVER)) { + r = 0; + goto finish; + } + + log_error("Failed to connect to Upstart bus: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if ((r = bus_check_peercred(bus)) < 0) { + log_error("Failed to verify owner of bus."); + goto finish; + } + + if (!(m = dbus_message_new_method_call( + "com.ubuntu.Upstart", + "/com/ubuntu/Upstart", + "com.ubuntu.Upstart0_6", + "EmitEvent"))) { + + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + dbus_message_iter_init_append(m, &iter); + + env1_buf[sizeof(env1_buf)-2] = rl; + env2_buf[sizeof(env2_buf)-2] = previous; + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &emit) || + !dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "s", &sub) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &env1) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &env2) || + !dbus_message_iter_close_container(&iter, &sub) || + !dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &b_false)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + + if (error_is_no_service(&error)) { + r = -EADDRNOTAVAIL; + goto finish; + } + + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + r = 1; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + dbus_error_free(&error); + + return r; +} + +static int talk_initctl(void) { + struct init_request request; + int r, fd; + char rl; + + if (!(rl = action_to_runlevel())) + return 0; + + zero(request); + request.magic = INIT_MAGIC; + request.sleeptime = 0; + request.cmd = INIT_CMD_RUNLVL; + request.runlevel = rl; + + if ((fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY)) < 0) { + + if (errno == ENOENT) + return 0; + + log_error("Failed to open "INIT_FIFO": %m"); + return -errno; + } + + errno = 0; + r = loop_write(fd, &request, sizeof(request), false) != sizeof(request); + close_nointr_nofail(fd); + + if (r < 0) { + log_error("Failed to write to "INIT_FIFO": %m"); + return errno ? -errno : -EIO; + } + + return 1; +} + +static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) { + + static const struct { + const char* verb; + const enum { + MORE, + LESS, + EQUAL + } argc_cmp; + const int argc; + int (* const dispatch)(DBusConnection *bus, char **args); + } verbs[] = { + { "list-units", LESS, 1, list_units }, + { "list-unit-files", EQUAL, 1, list_unit_files }, + { "list-jobs", EQUAL, 1, list_jobs }, + { "clear-jobs", EQUAL, 1, daemon_reload }, + { "load", MORE, 2, load_unit }, + { "cancel", MORE, 2, cancel_job }, + { "start", MORE, 2, start_unit }, + { "stop", MORE, 2, start_unit }, + { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */ + { "reload", MORE, 2, start_unit }, + { "restart", MORE, 2, start_unit }, + { "try-restart", MORE, 2, start_unit }, + { "reload-or-restart", MORE, 2, start_unit }, + { "reload-or-try-restart", MORE, 2, start_unit }, + { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */ + { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */ + { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */ + { "isolate", EQUAL, 2, start_unit }, + { "kill", MORE, 2, kill_unit }, + { "is-active", MORE, 2, check_unit }, + { "check", MORE, 2, check_unit }, + { "show", MORE, 1, show }, + { "status", MORE, 2, show }, + { "dump", EQUAL, 1, dump }, + { "dot", EQUAL, 1, dot }, + { "snapshot", LESS, 2, snapshot }, + { "delete", MORE, 2, delete_snapshot }, + { "daemon-reload", EQUAL, 1, daemon_reload }, + { "daemon-reexec", EQUAL, 1, daemon_reload }, + { "show-environment", EQUAL, 1, show_enviroment }, + { "set-environment", MORE, 2, set_environment }, + { "unset-environment", MORE, 2, set_environment }, + { "halt", EQUAL, 1, start_special }, + { "poweroff", EQUAL, 1, start_special }, + { "reboot", EQUAL, 1, start_special }, + { "kexec", EQUAL, 1, start_special }, + { "default", EQUAL, 1, start_special }, + { "rescue", EQUAL, 1, start_special }, + { "emergency", EQUAL, 1, start_special }, + { "exit", EQUAL, 1, start_special }, + { "reset-failed", MORE, 1, reset_failed }, + { "enable", MORE, 2, enable_unit }, + { "disable", MORE, 2, enable_unit }, + { "is-enabled", MORE, 2, unit_is_enabled }, + { "reenable", MORE, 2, enable_unit }, + { "preset", MORE, 2, enable_unit }, + { "mask", MORE, 2, enable_unit }, + { "unmask", MORE, 2, enable_unit }, + { "link", MORE, 2, enable_unit } + }; + + int left; + unsigned i; + + assert(argc >= 0); + assert(argv); + assert(error); + + left = argc - optind; + + if (left <= 0) + /* Special rule: no arguments means "list-units" */ + i = 0; + else { + if (streq(argv[optind], "help")) { + systemctl_help(); + return 0; + } + + for (i = 0; i < ELEMENTSOF(verbs); i++) + if (streq(argv[optind], verbs[i].verb)) + break; + + if (i >= ELEMENTSOF(verbs)) { + log_error("Unknown operation %s", argv[optind]); + return -EINVAL; + } + } + + switch (verbs[i].argc_cmp) { + + case EQUAL: + if (left != verbs[i].argc) { + log_error("Invalid number of arguments."); + return -EINVAL; + } + + break; + + case MORE: + if (left < verbs[i].argc) { + log_error("Too few arguments."); + return -EINVAL; + } + + break; + + case LESS: + if (left > verbs[i].argc) { + log_error("Too many arguments."); + return -EINVAL; + } + + break; + + default: + assert_not_reached("Unknown comparison operator."); + } + + /* Require a bus connection for all operations but + * enable/disable */ + if (!streq(verbs[i].verb, "enable") && + !streq(verbs[i].verb, "disable") && + !streq(verbs[i].verb, "is-enabled") && + !streq(verbs[i].verb, "list-unit-files") && + !streq(verbs[i].verb, "reenable") && + !streq(verbs[i].verb, "preset") && + !streq(verbs[i].verb, "mask") && + !streq(verbs[i].verb, "unmask") && + !streq(verbs[i].verb, "link")) { + + if (running_in_chroot() > 0) { + log_info("Running in chroot, ignoring request."); + return 0; + } + + if (!bus) { + log_error("Failed to get D-Bus connection: %s", + dbus_error_is_set(error) ? error->message : "No connection to service manager."); + return -EIO; + } + + } else { + + if (!bus && !avoid_bus()) { + log_error("Failed to get D-Bus connection: %s", + dbus_error_is_set(error) ? error->message : "No connection to service manager."); + return -EIO; + } + } + + return verbs[i].dispatch(bus, argv + optind); +} + +static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) { + int fd = -1; + struct msghdr msghdr; + struct iovec iovec; + union sockaddr_union sockaddr; + struct shutdownd_command c; + + zero(c); + c.elapse = t; + c.mode = mode; + c.dry_run = dry_run; + c.warn_wall = warn; + + if (message) + strncpy(c.wall_message, message, sizeof(c.wall_message)); + + if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) + return -errno; + + zero(sockaddr); + sockaddr.sa.sa_family = AF_UNIX; + sockaddr.un.sun_path[0] = 0; + strncpy(sockaddr.un.sun_path, "/run/systemd/shutdownd", sizeof(sockaddr.un.sun_path)); + + zero(iovec); + iovec.iov_base = (char*) &c; + iovec.iov_len = sizeof(c); + + zero(msghdr); + msghdr.msg_name = &sockaddr; + msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + sizeof("/run/systemd/shutdownd") - 1; + + msghdr.msg_iov = &iovec; + msghdr.msg_iovlen = 1; + + if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) { + close_nointr_nofail(fd); + return -errno; + } + + close_nointr_nofail(fd); + return 0; +} + +static int reload_with_fallback(DBusConnection *bus) { + + if (bus) { + /* First, try systemd via D-Bus. */ + if (daemon_reload(bus, NULL) >= 0) + return 0; + } + + /* Nothing else worked, so let's try signals */ + assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC); + + if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) { + log_error("kill() failed: %m"); + return -errno; + } + + return 0; +} + +static int start_with_fallback(DBusConnection *bus) { + + if (bus) { + /* First, try systemd via D-Bus. */ + if (start_unit(bus, NULL) >= 0) + goto done; + } + + /* Hmm, talking to systemd via D-Bus didn't work. Then + * let's try to talk to Upstart via D-Bus. */ + if (talk_upstart() > 0) + goto done; + + /* Nothing else worked, so let's try + * /dev/initctl */ + if (talk_initctl() > 0) + goto done; + + log_error("Failed to talk to init daemon."); + return -EIO; + +done: + warn_wall(arg_action); + return 0; +} + +static int halt_main(DBusConnection *bus) { + int r; + + if (geteuid() != 0) { + log_error("Must be root."); + return -EPERM; + } + + if (arg_when > 0) { + char *m; + char date[FORMAT_TIMESTAMP_MAX]; + + m = strv_join(arg_wall, " "); + r = send_shutdownd(arg_when, + arg_action == ACTION_HALT ? 'H' : + arg_action == ACTION_POWEROFF ? 'P' : + 'r', + arg_dry, + !arg_no_wall, + m); + free(m); + + if (r < 0) + log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r)); + else { + log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", + format_timestamp(date, sizeof(date), arg_when)); + return 0; + } + } + + if (!arg_dry && !arg_immediate) + return start_with_fallback(bus); + + if (!arg_no_wtmp) { + if (sd_booted() > 0) + log_debug("Not writing utmp record, assuming that systemd-update-utmp is used."); + else if ((r = utmp_put_shutdown()) < 0) + log_warning("Failed to write utmp record: %s", strerror(-r)); + } + + if (!arg_no_sync) + sync(); + + if (arg_dry) + return 0; + + /* Make sure C-A-D is handled by the kernel from this + * point on... */ + reboot(RB_ENABLE_CAD); + + switch (arg_action) { + + case ACTION_HALT: + log_info("Halting."); + reboot(RB_HALT_SYSTEM); + break; + + case ACTION_POWEROFF: + log_info("Powering off."); + reboot(RB_POWER_OFF); + break; + + case ACTION_REBOOT: + log_info("Rebooting."); + reboot(RB_AUTOBOOT); + break; + + default: + assert_not_reached("Unknown halt action."); + } + + /* We should never reach this. */ + return -ENOSYS; +} + +static int runlevel_main(void) { + int r, runlevel, previous; + + r = utmp_get_runlevel(&runlevel, &previous); + if (r < 0) { + puts("unknown"); + return r; + } + + printf("%c %c\n", + previous <= 0 ? 'N' : previous, + runlevel <= 0 ? 'N' : runlevel); + + return 0; +} + +int main(int argc, char*argv[]) { + int r, retval = EXIT_FAILURE; + DBusConnection *bus = NULL; + DBusError error; + + dbus_error_init(&error); + + log_parse_environment(); + log_open(); + + if ((r = parse_argv(argc, argv)) < 0) + goto finish; + else if (r == 0) { + retval = EXIT_SUCCESS; + goto finish; + } + + /* /sbin/runlevel doesn't need to communicate via D-Bus, so + * let's shortcut this */ + if (arg_action == ACTION_RUNLEVEL) { + r = runlevel_main(); + retval = r < 0 ? EXIT_FAILURE : r; + goto finish; + } + + if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) { + log_info("Running in chroot, ignoring request."); + retval = 0; + goto finish; + } + + if (!avoid_bus()) { + if (arg_transport == TRANSPORT_NORMAL) + bus_connect(arg_scope == UNIT_FILE_SYSTEM ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, &bus, &private_bus, &error); + else if (arg_transport == TRANSPORT_POLKIT) { + bus_connect_system_polkit(&bus, &error); + private_bus = false; + } else if (arg_transport == TRANSPORT_SSH) { + bus_connect_system_ssh(NULL, arg_host, &bus, &error); + private_bus = false; + } else + assert_not_reached("Uh, invalid transport..."); + } + + switch (arg_action) { + + case ACTION_SYSTEMCTL: + r = systemctl_main(bus, argc, argv, &error); + break; + + case ACTION_HALT: + case ACTION_POWEROFF: + case ACTION_REBOOT: + case ACTION_KEXEC: + r = halt_main(bus); + break; + + case ACTION_RUNLEVEL2: + case ACTION_RUNLEVEL3: + case ACTION_RUNLEVEL4: + case ACTION_RUNLEVEL5: + case ACTION_RESCUE: + case ACTION_EMERGENCY: + case ACTION_DEFAULT: + r = start_with_fallback(bus); + break; + + case ACTION_RELOAD: + case ACTION_REEXEC: + r = reload_with_fallback(bus); + break; + + case ACTION_CANCEL_SHUTDOWN: + r = send_shutdownd(0, 0, false, false, NULL); + break; + + case ACTION_INVALID: + case ACTION_RUNLEVEL: + default: + assert_not_reached("Unknown action"); + } + + retval = r < 0 ? EXIT_FAILURE : r; + +finish: + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + dbus_error_free(&error); + + dbus_shutdown(); + + strv_free(arg_property); + + pager_close(); + agent_close(); + + return retval; +} diff --git a/src/systemd-analyze b/src/systemd-analyze new file mode 100755 index 0000000..729aa05 --- /dev/null +++ b/src/systemd-analyze @@ -0,0 +1,264 @@ +#!/usr/bin/python + +import dbus, sys + +def acquire_time_data(): + + manager = dbus.Interface(bus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1'), 'org.freedesktop.systemd1.Manager') + units = manager.ListUnits() + + l = [] + + for i in units: + if i[5] != "": + continue + + properties = dbus.Interface(bus.get_object('org.freedesktop.systemd1', i[6]), 'org.freedesktop.DBus.Properties') + + ixt = int(properties.Get('org.freedesktop.systemd1.Unit', 'InactiveExitTimestampMonotonic')) + aet = int(properties.Get('org.freedesktop.systemd1.Unit', 'ActiveEnterTimestampMonotonic')) + axt = int(properties.Get('org.freedesktop.systemd1.Unit', 'ActiveExitTimestampMonotonic')) + iet = int(properties.Get('org.freedesktop.systemd1.Unit', 'InactiveEnterTimestampMonotonic')) + + l.append((str(i[0]), ixt, aet, axt, iet)) + + return l + +def acquire_start_time(): + properties = dbus.Interface(bus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1'), 'org.freedesktop.DBus.Properties') + + initrd_time = int(properties.Get('org.freedesktop.systemd1.Manager', 'InitRDTimestampMonotonic')) + startup_time = int(properties.Get('org.freedesktop.systemd1.Manager', 'StartupTimestampMonotonic')) + finish_time = int(properties.Get('org.freedesktop.systemd1.Manager', 'FinishTimestampMonotonic')) + + assert initrd_time <= startup_time + assert startup_time <= finish_time + + return initrd_time, startup_time, finish_time + +def draw_box(context, j, k, l, m, r = 0, g = 0, b = 0): + context.save() + context.set_source_rgb(r, g, b) + context.rectangle(j, k, l, m) + context.fill() + context.restore() + +def draw_text(context, x, y, text, size = 12, r = 0, g = 0, b = 0, vcenter = 0.5, hcenter = 0.5): + context.save() + + context.set_source_rgb(r, g, b) + context.select_font_face("Sans", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) + context.set_font_size(size) + + if vcenter or hcenter: + x_bearing, y_bearing, width, height = context.text_extents(text)[:4] + + if hcenter: + x = x - width*hcenter - x_bearing + + if vcenter: + y = y - height*vcenter - y_bearing + + context.move_to(x, y) + context.show_text(text) + + context.restore() + +def help(): + sys.stdout.write("""systemd-analyze time +systemd-analyze blame +systemd-analyze plot + +Process systemd profiling information + + -h --help Show this help +""") + + +bus = dbus.SystemBus() + +if len(sys.argv) <= 1 or sys.argv[1] == 'time': + + initrd_time, start_time, finish_time = acquire_start_time() + + if initrd_time > 0: + print "Startup finished in %lums (kernel) + %lums (initramfs) + %lums (userspace) = %lums" % ( \ + initrd_time/1000, \ + (start_time - initrd_time)/1000, \ + (finish_time - start_time)/1000, \ + finish_time/1000) + else: + print "Startup finished in %lums (kernel) + %lums (userspace) = %lums" % ( \ + start_time/1000, \ + (finish_time - start_time)/1000, \ + finish_time/1000) + + +elif sys.argv[1] == 'blame': + + data = acquire_time_data() + s = sorted(data, key = lambda i: i[2] - i[1], reverse = True) + + for name, ixt, aet, axt, iet in s: + + if ixt <= 0 or aet <= 0: + continue + + if aet <= ixt: + continue + + sys.stdout.write("%6lums %s\n" % ((aet - ixt) / 1000, name)) + +elif sys.argv[1] == 'plot': + import cairo, os + + initrd_time, start_time, finish_time = acquire_start_time() + data = acquire_time_data() + s = sorted(data, key = lambda i: i[1]) + + # Account for kernel and initramfs bars if they exist + if initrd_time > 0: + count = 3 + else: + count = 2 + + for name, ixt, aet, axt, iet in s: + + if (ixt >= start_time and ixt <= finish_time) or \ + (aet >= start_time and aet <= finish_time) or \ + (axt >= start_time and axt <= finish_time): + count += 1 + + border = 100 + bar_height = 20 + bar_space = bar_height * 0.1 + + # 1000px = 10s, 1px = 10ms + width = finish_time/10000 + border*2 + height = count * (bar_height + bar_space) + border * 2 + + if width < 1000: + width = 1000 + + surface = cairo.SVGSurface(sys.stdout, width, height) + context = cairo.Context(surface) + + draw_box(context, 0, 0, width, height, 1, 1, 1) + + context.translate(border + 0.5, border + 0.5) + + context.save() + context.set_line_width(1) + context.set_source_rgb(0.7, 0.7, 0.7) + + for x in range(0, finish_time/10000 + 100, 100): + context.move_to(x, 0) + context.line_to(x, height-border*2) + + context.move_to(0, 0) + context.line_to(width-border*2, 0) + + context.move_to(0, height-border*2) + context.line_to(width-border*2, height-border*2) + + context.stroke() + context.restore() + + banner = "Running on %s (%s %s) %s" % (os.uname()[1], os.uname()[2], os.uname()[3], os.uname()[4]) + draw_text(context, 0, -15, banner, hcenter = 0, vcenter = 1) + + for x in range(0, finish_time/10000 + 100, 100): + draw_text(context, x, -5, "%lus" % (x/100), vcenter = 0, hcenter = 0) + + y = 0 + + # draw boxes for kernel and initramfs boot time + if initrd_time > 0: + draw_box(context, 0, y, initrd_time/10000, bar_height, 0.7, 0.7, 0.7) + draw_text(context, 10, y + bar_height/2, "kernel", hcenter = 0) + y += bar_height + bar_space + + draw_box(context, initrd_time/10000, y, start_time/10000-initrd_time/10000, bar_height, 0.7, 0.7, 0.7) + draw_text(context, initrd_time/10000 + 10, y + bar_height/2, "initramfs", hcenter = 0) + y += bar_height + bar_space + + else: + draw_box(context, 0, y, start_time/10000, bar_height, 0.6, 0.6, 0.6) + draw_text(context, 10, y + bar_height/2, "kernel", hcenter = 0) + y += bar_height + bar_space + + draw_box(context, start_time/10000, y, finish_time/10000-start_time/10000, bar_height, 0.7, 0.7, 0.7) + draw_text(context, start_time/10000 + 10, y + bar_height/2, "userspace", hcenter = 0) + y += bar_height + bar_space + + for name, ixt, aet, axt, iet in s: + + drawn = False + left = -1 + + if ixt >= start_time and ixt <= finish_time: + + # Activating + a = ixt + b = min(filter(lambda x: x >= ixt, (aet, axt, iet, finish_time))) - ixt + + draw_box(context, a/10000, y, b/10000, bar_height, 1, 0, 0) + drawn = True + + if left < 0: + left = a + + if aet >= start_time and aet <= finish_time: + + # Active + a = aet + b = min(filter(lambda x: x >= aet, (axt, iet, finish_time))) - aet + + draw_box(context, a/10000, y, b/10000, bar_height, .8, .6, .6) + drawn = True + + if left < 0: + left = a + + if axt >= start_time and axt <= finish_time: + + # Deactivating + a = axt + b = min(filter(lambda x: x >= axt, (iet, finish_time))) - axt + + draw_box(context, a/10000, y, b/10000, bar_height, .6, .4, .4) + drawn = True + + if left < 0: + left = a + + if drawn: + x = left/10000 + + if x < width/2-border: + draw_text(context, x + 10, y + bar_height/2, name, hcenter = 0) + else: + draw_text(context, x - 10, y + bar_height/2, name, hcenter = 1) + + y += bar_height + bar_space + + draw_text(context, 0, height-border*2, "Legend: Red = Activating; Pink = Active; Dark Pink = Deactivating", hcenter = 0, vcenter = -1) + + if initrd_time > 0: + draw_text(context, 0, height-border*2 + bar_height, "Startup finished in %lums (kernel) + %lums (initramfs) + %lums (userspace) = %lums" % ( \ + initrd_time/1000, \ + (start_time - initrd_time)/1000, \ + (finish_time - start_time)/1000, \ + finish_time/1000), hcenter = 0, vcenter = -1) + else: + draw_text(context, 0, height-border*2 + bar_height, "Startup finished in %lums (kernel) + %lums (userspace) = %lums" % ( \ + start_time/1000, \ + (finish_time - start_time)/1000, \ + finish_time/1000), hcenter = 0, vcenter = -1) + + surface.finish() +elif sys.argv[1] in ("help", "--help", "-h"): + help() +else: + sys.stderr.write("Unknown verb '%s'.\n" % sys.argv[1]) + sys.exit(1) diff --git a/src/systemd-bash-completion.sh b/src/systemd-bash-completion.sh new file mode 100644 index 0000000..176591f --- /dev/null +++ b/src/systemd-bash-completion.sh @@ -0,0 +1,264 @@ +# This file is part of systemd. +# +# Copyright 2010 Ran Benita +# +# systemd 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. +# +# systemd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with systemd; If not, see . + +__systemctl() { + systemctl --full --no-legend "$@" +} + +__contains_word () { + local word=$1; shift + for w in $*; do [[ $w = $word ]] && return 0; done + return 1 +} + +__filter_units_by_property () { + local property=$1 value=$2 ; shift ; shift + local -a units=( $* ) + local -a props=( $(__systemctl show --property "$property" -- ${units[*]} | grep -v ^$) ) + for ((i=0; $i < ${#units[*]}; i++)); do + if [[ "${props[i]}" = "$property=$value" ]]; then + echo "${units[i]}" + fi + done +} + +__get_all_units () { __systemctl list-units --all | awk ' {print $1}' ; } +__get_active_units () { __systemctl list-units | awk ' {print $1}' ; } +__get_inactive_units () { __systemctl list-units --all | awk '$3 == "inactive" {print $1}' ; } +__get_failed_units () { __systemctl list-units | awk '$3 == "failed" {print $1}' ; } +__get_enabled_units () { __systemctl list-unit-files | awk '$2 == "enabled" {print $1}' ; } +__get_disabled_units () { __systemctl list-unit-files | awk '$2 == "disabled" {print $1}' ; } +__get_masked_units () { __systemctl list-unit-files | awk '$2 == "masked" {print $1}' ; } + +_systemctl () { + local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} + local verb comps + + local -A OPTS=( + [STANDALONE]='--all -a --defaults --fail --ignore-dependencies --failed --force -f --full --global + --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall + --order --require --quiet -q --privileged -P --system --user --version --runtime' + [ARG]='--host -H --kill-mode --kill-who --property -p --signal -s --type -t --root' + ) + + if __contains_word "$prev" ${OPTS[ARG]}; then + case $prev in + --signal|-s) + comps=$(compgen -A signal) + ;; + --type|-t) + comps='automount device mount path service snapshot socket swap target timer' + ;; + --kill-who) + comps='all control main' + ;; + --kill-mode) + comps='control-group process' + ;; + --root) + comps=$(compgen -A directory -- "$cur" ) + compopt -o filenames + ;; + --host|-H) + comps=$(compgen -A hostname) + ;; + --property|-p) + comps='' + ;; + esac + COMPREPLY=( $(compgen -W "$comps" -- "$cur") ) + return 0 + fi + + + if [[ "$cur" = -* ]]; then + COMPREPLY=( $(compgen -W "${OPTS[*]}" -- "$cur") ) + return 0 + fi + + local -A VERBS=( + [ALL_UNITS]='is-active is-enabled status show mask preset' + [ENABLED_UNITS]='disable reenable' + [DISABLED_UNITS]='enable' + [FAILED_UNITS]='reset-failed' + [STARTABLE_UNITS]='start' + [STOPPABLE_UNITS]='stop condstop kill try-restart condrestart' + [ISOLATABLE_UNITS]='isolate' + [RELOADABLE_UNITS]='reload condreload reload-or-try-restart force-reload' + [RESTARTABLE_UNITS]='restart reload-or-restart' + [MASKED_UNITS]='unmask' + [JOBS]='cancel' + [SNAPSHOTS]='delete' + [ENVS]='set-environment unset-environment' + [STANDALONE]='daemon-reexec daemon-reload default dot dump + emergency exit halt kexec list-jobs list-units + list-unit-files poweroff reboot rescue show-environment' + [NAME]='snapshot load' + [FILE]='link' + ) + + for ((i=0; $i <= $COMP_CWORD; i++)); do + if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} && + ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then + verb=${COMP_WORDS[i]} + break + fi + done + + if [[ -z $verb ]]; then + comps="${VERBS[*]}" + + elif __contains_word "$verb" ${VERBS[ALL_UNITS]}; then + comps=$( __get_all_units ) + + elif __contains_word "$verb" ${VERBS[ENABLED_UNITS]}; then + comps=$( __get_enabled_units ) + + elif __contains_word "$verb" ${VERBS[DISABLED_UNITS]}; then + comps=$( __get_disabled_units ) + + elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then + comps=$( __filter_units_by_property CanStart yes \ + $( __get_inactive_units | grep -Ev '\.(device|snapshot)$' )) + + elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then + comps=$( __filter_units_by_property CanStart yes \ + $( __get_all_units | grep -Ev '\.(device|snapshot|socket|timer)$' )) + + elif __contains_word "$verb" ${VERBS[STOPPABLE_UNITS]}; then + comps=$( __filter_units_by_property CanStop yes \ + $( __get_active_units ) ) + + elif __contains_word "$verb" ${VERBS[RELOADABLE_UNITS]}; then + comps=$( __filter_units_by_property CanReload yes \ + $( __get_active_units ) ) + + elif __contains_word "$verb" ${VERBS[ISOLATABLE_UNITS]}; then + comps=$( __filter_units_by_property AllowIsolate yes \ + $( __get_all_units ) ) + + elif __contains_word "$verb" ${VERBS[FAILED_UNITS]}; then + comps=$( __get_failed_units ) + + elif __contains_word "$verb" ${VERBS[MASKED_UNITS]}; then + comps=$( __get_masked_units ) + + elif __contains_word "$verb" ${VERBS[STANDALONE]} ${VERBS[NAME]}; then + comps='' + + elif __contains_word "$verb" ${VERBS[JOBS]}; then + comps=$( __systemctl list-jobs | awk '{print $1}' ) + + elif __contains_word "$verb" ${VERBS[SNAPSHOTS]}; then + comps=$( __systemctl list-units --type snapshot --full --all | awk '{print $1}' ) + + elif __contains_word "$verb" ${VERBS[ENVS]}; then + comps=$( __systemctl show-environment | sed 's_\([^=]\+=\).*_\1_' ) + compopt -o nospace + + elif __contains_word "$verb" ${VERBS[FILE]}; then + comps=$( compgen -A file -- "$cur" ) + compopt -o filenames + fi + + COMPREPLY=( $(compgen -W "$comps" -- "$cur") ) + return 0 +} +complete -F _systemctl systemctl + +__get_all_sessions () { systemd-loginctl list-sessions | awk '{print $1}' ; } +__get_all_users () { systemd-loginctl list-users | awk '{print $2}' ; } +__get_all_seats () { systemd-loginctl list-seats | awk '{print $1}' ; } + +_systemd_loginctl () { + local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} + local verb comps + + local -A OPTS=( + [STANDALONE]='--all -a --help -h --no-pager --privileged -P --version' + [ARG]='--host -H --kill-who --property -p --signal -s' + ) + + if __contains_word "$prev" ${OPTS[ARG]}; then + case $prev in + --signal|-s) + comps=$(compgen -A signal) + ;; + --kill-who) + comps='all leader' + ;; + --host|-H) + comps=$(compgen -A hostname) + ;; + --property|-p) + comps='' + ;; + esac + COMPREPLY=( $(compgen -W "$comps" -- "$cur") ) + return 0 + fi + + + if [[ "$cur" = -* ]]; then + COMPREPLY=( $(compgen -W "${OPTS[*]}" -- "$cur") ) + return 0 + fi + + local -A VERBS=( + [SESSIONS]='session-status show-session activate lock-session unlock-session terminate-session kill-session' + [USERS]='user-status show-user enable-linger disable-linger terminate-user kill-user' + [SEATS]='seat-status show-seat terminate-seat' + [STANDALONE]='list-sessions list-users list-seats flush-devices' + [ATTACH]='attach' + ) + + for ((i=0; $i <= $COMP_CWORD; i++)); do + if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} && + ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG}]}; then + verb=${COMP_WORDS[i]} + break + fi + done + + if [[ -z $verb ]]; then + comps="${VERBS[*]}" + + elif __contains_word "$verb" ${VERBS[SESSIONS]}; then + comps=$( __get_all_sessions ) + + elif __contains_word "$verb" ${VERBS[USERS]}; then + comps=$( __get_all_users ) + + elif __contains_word "$verb" ${VERBS[SEATS]}; then + comps=$( __get_all_seats ) + + elif __contains_word "$verb" ${VERBS[STANDALONE]}; then + comps='' + + elif __contains_word "$verb" ${VERBS[ATTACH]}; then + if [[ $prev = $verb ]]; then + comps=$( __get_all_seats ) + else + comps=$(compgen -A file -- "$cur" ) + compopt -o filenames + fi + fi + + COMPREPLY=( $(compgen -W "$comps" -- "$cur") ) + return 0 +} +complete -F _systemd_loginctl systemd-loginctl diff --git a/src/systemd-interfaces.c b/src/systemd-interfaces.c new file mode 100644 index 0000000..b7ff772 --- /dev/null +++ b/src/systemd-interfaces.c @@ -0,0 +1,7501 @@ +/* systemd-interfaces.c generated by valac 0.15.1, the Vala compiler + * generated from systemd-interfaces.vala, do not modify */ + + +#include +#include +#include +#include +#include + + +#define TYPE_MANAGER (manager_get_type ()) +#define MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MANAGER, Manager)) +#define IS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MANAGER)) +#define MANAGER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TYPE_MANAGER, ManagerIface)) + +typedef struct _Manager Manager; +typedef struct _ManagerIface ManagerIface; + +#define TYPE_MANAGER_PROXY (manager_proxy_get_type ()) + +#define MANAGER_TYPE_UNIT_INFO (manager_unit_info_get_type ()) +typedef struct _ManagerUnitInfo ManagerUnitInfo; + +#define MANAGER_TYPE_JOB_INFO (manager_job_info_get_type ()) +typedef struct _ManagerJobInfo ManagerJobInfo; +#define _g_free0(var) (var = (g_free (var), NULL)) +typedef GDBusProxy ManagerProxy; +typedef GDBusProxyClass ManagerProxyClass; + +#define TYPE_UNIT (unit_get_type ()) +#define UNIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_UNIT, Unit)) +#define IS_UNIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_UNIT)) +#define UNIT_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TYPE_UNIT, UnitIface)) + +typedef struct _Unit Unit; +typedef struct _UnitIface UnitIface; + +#define TYPE_UNIT_PROXY (unit_proxy_get_type ()) + +#define UNIT_TYPE_JOB_LINK (unit_job_link_get_type ()) +typedef struct _UnitJobLink UnitJobLink; +typedef GDBusProxy UnitProxy; +typedef GDBusProxyClass UnitProxyClass; + +#define TYPE_JOB (job_get_type ()) +#define JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_JOB, Job)) +#define IS_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_JOB)) +#define JOB_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TYPE_JOB, JobIface)) + +typedef struct _Job Job; +typedef struct _JobIface JobIface; + +#define TYPE_JOB_PROXY (job_proxy_get_type ()) + +#define JOB_TYPE_UNIT_LINK (job_unit_link_get_type ()) +typedef struct _JobUnitLink JobUnitLink; +typedef GDBusProxy JobProxy; +typedef GDBusProxyClass JobProxyClass; + +#define TYPE_PROPERTIES (properties_get_type ()) +#define PROPERTIES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_PROPERTIES, Properties)) +#define IS_PROPERTIES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_PROPERTIES)) +#define PROPERTIES_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TYPE_PROPERTIES, PropertiesIface)) + +typedef struct _Properties Properties; +typedef struct _PropertiesIface PropertiesIface; + +#define TYPE_PROPERTIES_PROXY (properties_proxy_get_type ()) +typedef GDBusProxy PropertiesProxy; +typedef GDBusProxyClass PropertiesProxyClass; +#define _g_hash_table_unref0(var) ((var == NULL) ? NULL : (var = (g_hash_table_unref (var), NULL))) +#define _g_variant_unref0(var) ((var == NULL) ? NULL : (var = (g_variant_unref (var), NULL))) + +struct _ManagerUnitInfo { + gchar* id; + gchar* description; + gchar* load_state; + gchar* active_state; + gchar* sub_state; + gchar* following; + char* unit_path; + guint32 job_id; + gchar* job_type; + char* job_path; +}; + +struct _ManagerJobInfo { + guint32 id; + gchar* name; + gchar* type; + gchar* state; + char* job_path; + char* unit_path; +}; + +struct _ManagerIface { + GTypeInterface parent_iface; + ManagerUnitInfo* (*list_units) (Manager* self, int* result_length1, GError** error); + ManagerJobInfo* (*list_jobs) (Manager* self, int* result_length1, GError** error); + char* (*get_unit) (Manager* self, const gchar* name, GError** error); + char* (*get_unit_by_pid) (Manager* self, guint32 pid, GError** error); + char* (*load_unit) (Manager* self, const gchar* name, GError** error); + char* (*get_job) (Manager* self, guint32 id, GError** error); + char* (*start_unit) (Manager* self, const gchar* name, const gchar* mode, GError** error); + char* (*stop_unit) (Manager* self, const gchar* name, const gchar* mode, GError** error); + char* (*reload_unit) (Manager* self, const gchar* name, const gchar* mode, GError** error); + char* (*restart_unit) (Manager* self, const gchar* name, const gchar* mode, GError** error); + char* (*try_restart_unit) (Manager* self, const gchar* name, const gchar* mode, GError** error); + char* (*reload_or_restart_unit) (Manager* self, const gchar* name, const gchar* mode, GError** error); + char* (*reload_or_try_restart_unit) (Manager* self, const gchar* name, const gchar* mode, GError** error); + void (*reset_failed_unit) (Manager* self, const gchar* name, GError** error); + void (*clear_jobs) (Manager* self, GError** error); + void (*subscribe) (Manager* self, GError** error); + void (*unsubscribe) (Manager* self, GError** error); + gchar* (*dump) (Manager* self, GError** error); + void (*reload) (Manager* self, GError** error); + void (*reexecute) (Manager* self, GError** error); + void (*exit) (Manager* self, GError** error); + void (*halt) (Manager* self, GError** error); + void (*power_off) (Manager* self, GError** error); + void (*reboot) (Manager* self, GError** error); + void (*kexec) (Manager* self, GError** error); + char* (*create_snapshot) (Manager* self, const gchar* name, gboolean cleanup, GError** error); + void (*set_environment) (Manager* self, gchar** names, int names_length1, GError** error); + void (*unset_environment) (Manager* self, gchar** names, int names_length1, GError** error); + gchar** (*get_environment) (Manager* self, int* result_length1); +}; + +struct _UnitJobLink { + guint32 id; + char* path; +}; + +struct _UnitIface { + GTypeInterface parent_iface; + char* (*start) (Unit* self, const gchar* mode, GError** error); + char* (*stop) (Unit* self, const gchar* mode, GError** error); + char* (*reload) (Unit* self, const gchar* mode, GError** error); + char* (*restart) (Unit* self, const gchar* mode, GError** error); + char* (*try_restart) (Unit* self, const gchar* mode, GError** error); + char* (*reload_or_restart) (Unit* self, const gchar* mode, GError** error); + char* (*reload_or_try_restart) (Unit* self, const gchar* mode, GError** error); + void (*reset_failed) (Unit* self, GError** error); + gchar* (*get_id) (Unit* self); + gchar** (*get_names) (Unit* self, int* result_length1); + gchar* (*get_following) (Unit* self); + gchar** (*get_requires) (Unit* self, int* result_length1); + gchar** (*get_requires_overridable) (Unit* self, int* result_length1); + gchar** (*get_requisite) (Unit* self, int* result_length1); + gchar** (*get_requisite_overridable) (Unit* self, int* result_length1); + gchar** (*get_wants) (Unit* self, int* result_length1); + gchar** (*get_required_by) (Unit* self, int* result_length1); + gchar** (*get_required_by_overridable) (Unit* self, int* result_length1); + gchar** (*get_wanted_by) (Unit* self, int* result_length1); + gchar** (*get_conflicts) (Unit* self, int* result_length1); + gchar** (*get_conflicted_by) (Unit* self, int* result_length1); + gchar** (*get_before) (Unit* self, int* result_length1); + gchar** (*get_after) (Unit* self, int* result_length1); + gchar** (*get_on_failure) (Unit* self, int* result_length1); + gchar* (*get_description) (Unit* self); + gchar* (*get_load_state) (Unit* self); + gchar* (*get_active_state) (Unit* self); + gchar* (*get_sub_state) (Unit* self); + gchar* (*get_fragment_path) (Unit* self); + guint64 (*get_inactive_exit_timestamp) (Unit* self); + guint64 (*get_active_enter_timestamp) (Unit* self); + guint64 (*get_active_exit_timestamp) (Unit* self); + guint64 (*get_inactive_enter_timestamp) (Unit* self); + gboolean (*get_can_start) (Unit* self); + gboolean (*get_can_stop) (Unit* self); + gboolean (*get_can_reload) (Unit* self); + void (*get_job) (Unit* self, UnitJobLink* value); + gboolean (*get_recursive_stop) (Unit* self); + gboolean (*get_stop_when_unneeded) (Unit* self); + gboolean (*get_refuse_manual_start) (Unit* self); + gboolean (*get_refuse_manual_stop) (Unit* self); + gboolean (*get_default_dependencies) (Unit* self); + gchar* (*get_default_control_group) (Unit* self); + gchar** (*get_control_groups) (Unit* self, int* result_length1); + gboolean (*get_need_daemon_reload) (Unit* self); + guint64 (*get_job_timeout_usec) (Unit* self); +}; + +struct _JobUnitLink { + gchar* id; + char* path; +}; + +struct _JobIface { + GTypeInterface parent_iface; + void (*cancel) (Job* self, GError** error); + guint32 (*get_id) (Job* self); + gchar* (*get_state) (Job* self); + gchar* (*get_job_type) (Job* self); + void (*get_unit) (Job* self, JobUnitLink* value); +}; + +struct _PropertiesIface { + GTypeInterface parent_iface; + GVariant* (*get) (Properties* self, const gchar* iface, const gchar* property, GError** error); +}; + + + +GType manager_proxy_get_type (void) G_GNUC_CONST; +guint manager_register_object (void* object, GDBusConnection* connection, const gchar* path, GError** error); +GType manager_unit_info_get_type (void) G_GNUC_CONST; +ManagerUnitInfo* manager_unit_info_dup (const ManagerUnitInfo* self); +void manager_unit_info_free (ManagerUnitInfo* self); +void manager_unit_info_copy (const ManagerUnitInfo* self, ManagerUnitInfo* dest); +void manager_unit_info_destroy (ManagerUnitInfo* self); +GType manager_job_info_get_type (void) G_GNUC_CONST; +ManagerJobInfo* manager_job_info_dup (const ManagerJobInfo* self); +void manager_job_info_free (ManagerJobInfo* self); +void manager_job_info_copy (const ManagerJobInfo* self, ManagerJobInfo* dest); +void manager_job_info_destroy (ManagerJobInfo* self); +GType manager_get_type (void) G_GNUC_CONST; +ManagerUnitInfo* manager_list_units (Manager* self, int* result_length1, GError** error); +ManagerJobInfo* manager_list_jobs (Manager* self, int* result_length1, GError** error); +char* manager_get_unit (Manager* self, const gchar* name, GError** error); +char* manager_get_unit_by_pid (Manager* self, guint32 pid, GError** error); +char* manager_load_unit (Manager* self, const gchar* name, GError** error); +char* manager_get_job (Manager* self, guint32 id, GError** error); +char* manager_start_unit (Manager* self, const gchar* name, const gchar* mode, GError** error); +char* manager_stop_unit (Manager* self, const gchar* name, const gchar* mode, GError** error); +char* manager_reload_unit (Manager* self, const gchar* name, const gchar* mode, GError** error); +char* manager_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error); +char* manager_try_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error); +char* manager_reload_or_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error); +char* manager_reload_or_try_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error); +void manager_reset_failed_unit (Manager* self, const gchar* name, GError** error); +void manager_clear_jobs (Manager* self, GError** error); +void manager_subscribe (Manager* self, GError** error); +void manager_unsubscribe (Manager* self, GError** error); +gchar* manager_dump (Manager* self, GError** error); +void manager_reload (Manager* self, GError** error); +void manager_reexecute (Manager* self, GError** error); +void manager_exit (Manager* self, GError** error); +void manager_halt (Manager* self, GError** error); +void manager_power_off (Manager* self, GError** error); +void manager_reboot (Manager* self, GError** error); +void manager_kexec (Manager* self, GError** error); +char* manager_create_snapshot (Manager* self, const gchar* name, gboolean cleanup, GError** error); +void manager_set_environment (Manager* self, gchar** names, int names_length1, GError** error); +void manager_unset_environment (Manager* self, gchar** names, int names_length1, GError** error); +gchar** manager_get_environment (Manager* self, int* result_length1); +static void g_cclosure_user_marshal_VOID__STRING_STRING (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data); +static void g_cclosure_user_marshal_VOID__UINT_STRING (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data); +static void g_cclosure_user_marshal_VOID__UINT_STRING_STRING (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data); +static void manager_proxy_g_signal (GDBusProxy* proxy, const gchar* sender_name, const gchar* signal_name, GVariant* parameters); +static void _dbus_handle_manager_unit_new (Manager* self, GVariant* parameters); +static void _dbus_handle_manager_unit_removed (Manager* self, GVariant* parameters); +static void _dbus_handle_manager_job_new (Manager* self, GVariant* parameters); +static void _dbus_handle_manager_job_removed (Manager* self, GVariant* parameters); +static ManagerUnitInfo* manager_proxy_list_units (Manager* self, int* result_length1, GError** error); +static ManagerJobInfo* manager_proxy_list_jobs (Manager* self, int* result_length1, GError** error); +static char* manager_proxy_get_unit (Manager* self, const gchar* name, GError** error); +static char* manager_proxy_get_unit_by_pid (Manager* self, guint32 pid, GError** error); +static char* manager_proxy_load_unit (Manager* self, const gchar* name, GError** error); +static char* manager_proxy_get_job (Manager* self, guint32 id, GError** error); +static char* manager_proxy_start_unit (Manager* self, const gchar* name, const gchar* mode, GError** error); +static char* manager_proxy_stop_unit (Manager* self, const gchar* name, const gchar* mode, GError** error); +static char* manager_proxy_reload_unit (Manager* self, const gchar* name, const gchar* mode, GError** error); +static char* manager_proxy_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error); +static char* manager_proxy_try_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error); +static char* manager_proxy_reload_or_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error); +static char* manager_proxy_reload_or_try_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error); +static void manager_proxy_reset_failed_unit (Manager* self, const gchar* name, GError** error); +static void manager_proxy_clear_jobs (Manager* self, GError** error); +static void manager_proxy_subscribe (Manager* self, GError** error); +static void manager_proxy_unsubscribe (Manager* self, GError** error); +static gchar* manager_proxy_dump (Manager* self, GError** error); +static void manager_proxy_reload (Manager* self, GError** error); +static void manager_proxy_reexecute (Manager* self, GError** error); +static void manager_proxy_exit (Manager* self, GError** error); +static void manager_proxy_halt (Manager* self, GError** error); +static void manager_proxy_power_off (Manager* self, GError** error); +static void manager_proxy_reboot (Manager* self, GError** error); +static void manager_proxy_kexec (Manager* self, GError** error); +static char* manager_proxy_create_snapshot (Manager* self, const gchar* name, gboolean cleanup, GError** error); +static void manager_proxy_set_environment (Manager* self, gchar** names, int names_length1, GError** error); +static void manager_proxy_unset_environment (Manager* self, gchar** names, int names_length1, GError** error); +static gchar** manager_dbus_proxy_get_environment (Manager* self, int* result_length1); +static void manager_proxy_manager_interface_init (ManagerIface* iface); +static void _vala_ManagerUnitInfo_array_free (ManagerUnitInfo* array, gint array_length); +static void _dbus_manager_list_units (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _vala_ManagerJobInfo_array_free (ManagerJobInfo* array, gint array_length); +static void _dbus_manager_list_jobs (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_get_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_get_unit_by_pid (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_load_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_get_job (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_start_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_stop_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_reload_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_restart_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_try_restart_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_reload_or_restart_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_reload_or_try_restart_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_reset_failed_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_clear_jobs (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_subscribe (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_unsubscribe (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_dump (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_reload (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_reexecute (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_exit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_halt (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_power_off (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_reboot (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_kexec (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_create_snapshot (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_set_environment (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_manager_unset_environment (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void manager_dbus_interface_method_call (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data); +static GVariant* manager_dbus_interface_get_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GError** error, gpointer user_data); +static GVariant* _dbus_manager_get_environment (Manager* self); +static gboolean manager_dbus_interface_set_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GVariant* value, GError** error, gpointer user_data); +static void _dbus_manager_unit_new (GObject* _sender, const gchar* id, const char* path, gpointer* _data); +static void _dbus_manager_unit_removed (GObject* _sender, const gchar* id, const char* path, gpointer* _data); +static void _dbus_manager_job_new (GObject* _sender, guint32 id, const char* path, gpointer* _data); +static void _dbus_manager_job_removed (GObject* _sender, guint32 id, const char* path, const gchar* res, gpointer* _data); +static void _manager_unregister_object (gpointer user_data); +GType unit_proxy_get_type (void) G_GNUC_CONST; +guint unit_register_object (void* object, GDBusConnection* connection, const gchar* path, GError** error); +GType unit_job_link_get_type (void) G_GNUC_CONST; +UnitJobLink* unit_job_link_dup (const UnitJobLink* self); +void unit_job_link_free (UnitJobLink* self); +void unit_job_link_copy (const UnitJobLink* self, UnitJobLink* dest); +void unit_job_link_destroy (UnitJobLink* self); +GType unit_get_type (void) G_GNUC_CONST; +char* unit_start (Unit* self, const gchar* mode, GError** error); +char* unit_stop (Unit* self, const gchar* mode, GError** error); +char* unit_reload (Unit* self, const gchar* mode, GError** error); +char* unit_restart (Unit* self, const gchar* mode, GError** error); +char* unit_try_restart (Unit* self, const gchar* mode, GError** error); +char* unit_reload_or_restart (Unit* self, const gchar* mode, GError** error); +char* unit_reload_or_try_restart (Unit* self, const gchar* mode, GError** error); +void unit_reset_failed (Unit* self, GError** error); +gchar* unit_get_id (Unit* self); +gchar** unit_get_names (Unit* self, int* result_length1); +gchar* unit_get_following (Unit* self); +gchar** unit_get_requires (Unit* self, int* result_length1); +gchar** unit_get_requires_overridable (Unit* self, int* result_length1); +gchar** unit_get_requisite (Unit* self, int* result_length1); +gchar** unit_get_requisite_overridable (Unit* self, int* result_length1); +gchar** unit_get_wants (Unit* self, int* result_length1); +gchar** unit_get_required_by (Unit* self, int* result_length1); +gchar** unit_get_required_by_overridable (Unit* self, int* result_length1); +gchar** unit_get_wanted_by (Unit* self, int* result_length1); +gchar** unit_get_conflicts (Unit* self, int* result_length1); +gchar** unit_get_conflicted_by (Unit* self, int* result_length1); +gchar** unit_get_before (Unit* self, int* result_length1); +gchar** unit_get_after (Unit* self, int* result_length1); +gchar** unit_get_on_failure (Unit* self, int* result_length1); +gchar* unit_get_description (Unit* self); +gchar* unit_get_load_state (Unit* self); +gchar* unit_get_active_state (Unit* self); +gchar* unit_get_sub_state (Unit* self); +gchar* unit_get_fragment_path (Unit* self); +guint64 unit_get_inactive_exit_timestamp (Unit* self); +guint64 unit_get_active_enter_timestamp (Unit* self); +guint64 unit_get_active_exit_timestamp (Unit* self); +guint64 unit_get_inactive_enter_timestamp (Unit* self); +gboolean unit_get_can_start (Unit* self); +gboolean unit_get_can_stop (Unit* self); +gboolean unit_get_can_reload (Unit* self); +void unit_get_job (Unit* self, UnitJobLink* result); +gboolean unit_get_recursive_stop (Unit* self); +gboolean unit_get_stop_when_unneeded (Unit* self); +gboolean unit_get_refuse_manual_start (Unit* self); +gboolean unit_get_refuse_manual_stop (Unit* self); +gboolean unit_get_default_dependencies (Unit* self); +gchar* unit_get_default_control_group (Unit* self); +gchar** unit_get_control_groups (Unit* self, int* result_length1); +gboolean unit_get_need_daemon_reload (Unit* self); +guint64 unit_get_job_timeout_usec (Unit* self); +static void unit_proxy_g_signal (GDBusProxy* proxy, const gchar* sender_name, const gchar* signal_name, GVariant* parameters); +static char* unit_proxy_start (Unit* self, const gchar* mode, GError** error); +static char* unit_proxy_stop (Unit* self, const gchar* mode, GError** error); +static char* unit_proxy_reload (Unit* self, const gchar* mode, GError** error); +static char* unit_proxy_restart (Unit* self, const gchar* mode, GError** error); +static char* unit_proxy_try_restart (Unit* self, const gchar* mode, GError** error); +static char* unit_proxy_reload_or_restart (Unit* self, const gchar* mode, GError** error); +static char* unit_proxy_reload_or_try_restart (Unit* self, const gchar* mode, GError** error); +static void unit_proxy_reset_failed (Unit* self, GError** error); +static gchar* unit_dbus_proxy_get_id (Unit* self); +static gchar** unit_dbus_proxy_get_names (Unit* self, int* result_length1); +static gchar* unit_dbus_proxy_get_following (Unit* self); +static gchar** unit_dbus_proxy_get_requires (Unit* self, int* result_length1); +static gchar** unit_dbus_proxy_get_requires_overridable (Unit* self, int* result_length1); +static gchar** unit_dbus_proxy_get_requisite (Unit* self, int* result_length1); +static gchar** unit_dbus_proxy_get_requisite_overridable (Unit* self, int* result_length1); +static gchar** unit_dbus_proxy_get_wants (Unit* self, int* result_length1); +static gchar** unit_dbus_proxy_get_required_by (Unit* self, int* result_length1); +static gchar** unit_dbus_proxy_get_required_by_overridable (Unit* self, int* result_length1); +static gchar** unit_dbus_proxy_get_wanted_by (Unit* self, int* result_length1); +static gchar** unit_dbus_proxy_get_conflicts (Unit* self, int* result_length1); +static gchar** unit_dbus_proxy_get_conflicted_by (Unit* self, int* result_length1); +static gchar** unit_dbus_proxy_get_before (Unit* self, int* result_length1); +static gchar** unit_dbus_proxy_get_after (Unit* self, int* result_length1); +static gchar** unit_dbus_proxy_get_on_failure (Unit* self, int* result_length1); +static gchar* unit_dbus_proxy_get_description (Unit* self); +static gchar* unit_dbus_proxy_get_load_state (Unit* self); +static gchar* unit_dbus_proxy_get_active_state (Unit* self); +static gchar* unit_dbus_proxy_get_sub_state (Unit* self); +static gchar* unit_dbus_proxy_get_fragment_path (Unit* self); +static guint64 unit_dbus_proxy_get_inactive_exit_timestamp (Unit* self); +static guint64 unit_dbus_proxy_get_active_enter_timestamp (Unit* self); +static guint64 unit_dbus_proxy_get_active_exit_timestamp (Unit* self); +static guint64 unit_dbus_proxy_get_inactive_enter_timestamp (Unit* self); +static gboolean unit_dbus_proxy_get_can_start (Unit* self); +static gboolean unit_dbus_proxy_get_can_stop (Unit* self); +static gboolean unit_dbus_proxy_get_can_reload (Unit* self); +static void unit_dbus_proxy_get_job (Unit* self, UnitJobLink* result); +static gboolean unit_dbus_proxy_get_recursive_stop (Unit* self); +static gboolean unit_dbus_proxy_get_stop_when_unneeded (Unit* self); +static gboolean unit_dbus_proxy_get_refuse_manual_start (Unit* self); +static gboolean unit_dbus_proxy_get_refuse_manual_stop (Unit* self); +static gboolean unit_dbus_proxy_get_default_dependencies (Unit* self); +static gchar* unit_dbus_proxy_get_default_control_group (Unit* self); +static gchar** unit_dbus_proxy_get_control_groups (Unit* self, int* result_length1); +static gboolean unit_dbus_proxy_get_need_daemon_reload (Unit* self); +static guint64 unit_dbus_proxy_get_job_timeout_usec (Unit* self); +static void unit_proxy_unit_interface_init (UnitIface* iface); +static void _dbus_unit_start (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_unit_stop (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_unit_reload (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_unit_restart (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_unit_try_restart (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_unit_reload_or_restart (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_unit_reload_or_try_restart (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void _dbus_unit_reset_failed (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void unit_dbus_interface_method_call (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data); +static GVariant* unit_dbus_interface_get_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GError** error, gpointer user_data); +static GVariant* _dbus_unit_get_id (Unit* self); +static GVariant* _dbus_unit_get_names (Unit* self); +static GVariant* _dbus_unit_get_following (Unit* self); +static GVariant* _dbus_unit_get_requires (Unit* self); +static GVariant* _dbus_unit_get_requires_overridable (Unit* self); +static GVariant* _dbus_unit_get_requisite (Unit* self); +static GVariant* _dbus_unit_get_requisite_overridable (Unit* self); +static GVariant* _dbus_unit_get_wants (Unit* self); +static GVariant* _dbus_unit_get_required_by (Unit* self); +static GVariant* _dbus_unit_get_required_by_overridable (Unit* self); +static GVariant* _dbus_unit_get_wanted_by (Unit* self); +static GVariant* _dbus_unit_get_conflicts (Unit* self); +static GVariant* _dbus_unit_get_conflicted_by (Unit* self); +static GVariant* _dbus_unit_get_before (Unit* self); +static GVariant* _dbus_unit_get_after (Unit* self); +static GVariant* _dbus_unit_get_on_failure (Unit* self); +static GVariant* _dbus_unit_get_description (Unit* self); +static GVariant* _dbus_unit_get_load_state (Unit* self); +static GVariant* _dbus_unit_get_active_state (Unit* self); +static GVariant* _dbus_unit_get_sub_state (Unit* self); +static GVariant* _dbus_unit_get_fragment_path (Unit* self); +static GVariant* _dbus_unit_get_inactive_exit_timestamp (Unit* self); +static GVariant* _dbus_unit_get_active_enter_timestamp (Unit* self); +static GVariant* _dbus_unit_get_active_exit_timestamp (Unit* self); +static GVariant* _dbus_unit_get_inactive_enter_timestamp (Unit* self); +static GVariant* _dbus_unit_get_can_start (Unit* self); +static GVariant* _dbus_unit_get_can_stop (Unit* self); +static GVariant* _dbus_unit_get_can_reload (Unit* self); +static GVariant* _dbus_unit_get_job (Unit* self); +static GVariant* _dbus_unit_get_recursive_stop (Unit* self); +static GVariant* _dbus_unit_get_stop_when_unneeded (Unit* self); +static GVariant* _dbus_unit_get_refuse_manual_start (Unit* self); +static GVariant* _dbus_unit_get_refuse_manual_stop (Unit* self); +static GVariant* _dbus_unit_get_default_dependencies (Unit* self); +static GVariant* _dbus_unit_get_default_control_group (Unit* self); +static GVariant* _dbus_unit_get_control_groups (Unit* self); +static GVariant* _dbus_unit_get_need_daemon_reload (Unit* self); +static GVariant* _dbus_unit_get_job_timeout_usec (Unit* self); +static gboolean unit_dbus_interface_set_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GVariant* value, GError** error, gpointer user_data); +static void _unit_unregister_object (gpointer user_data); +GType job_proxy_get_type (void) G_GNUC_CONST; +guint job_register_object (void* object, GDBusConnection* connection, const gchar* path, GError** error); +GType job_unit_link_get_type (void) G_GNUC_CONST; +JobUnitLink* job_unit_link_dup (const JobUnitLink* self); +void job_unit_link_free (JobUnitLink* self); +void job_unit_link_copy (const JobUnitLink* self, JobUnitLink* dest); +void job_unit_link_destroy (JobUnitLink* self); +GType job_get_type (void) G_GNUC_CONST; +void job_cancel (Job* self, GError** error); +guint32 job_get_id (Job* self); +gchar* job_get_state (Job* self); +gchar* job_get_job_type (Job* self); +void job_get_unit (Job* self, JobUnitLink* result); +static void job_proxy_g_signal (GDBusProxy* proxy, const gchar* sender_name, const gchar* signal_name, GVariant* parameters); +static void job_proxy_cancel (Job* self, GError** error); +static guint32 job_dbus_proxy_get_id (Job* self); +static gchar* job_dbus_proxy_get_state (Job* self); +static gchar* job_dbus_proxy_get_job_type (Job* self); +static void job_dbus_proxy_get_unit (Job* self, JobUnitLink* result); +static void job_proxy_job_interface_init (JobIface* iface); +static void _dbus_job_cancel (Job* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void job_dbus_interface_method_call (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data); +static GVariant* job_dbus_interface_get_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GError** error, gpointer user_data); +static GVariant* _dbus_job_get_id (Job* self); +static GVariant* _dbus_job_get_state (Job* self); +static GVariant* _dbus_job_get_job_type (Job* self); +static GVariant* _dbus_job_get_unit (Job* self); +static gboolean job_dbus_interface_set_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GVariant* value, GError** error, gpointer user_data); +static void _job_unregister_object (gpointer user_data); +GType properties_proxy_get_type (void) G_GNUC_CONST; +guint properties_register_object (void* object, GDBusConnection* connection, const gchar* path, GError** error); +GType properties_get_type (void) G_GNUC_CONST; +GVariant* properties_get (Properties* self, const gchar* iface, const gchar* property, GError** error); +static void g_cclosure_user_marshal_VOID__STRING_BOXED_BOXED_INT (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data); +static void properties_proxy_g_signal (GDBusProxy* proxy, const gchar* sender_name, const gchar* signal_name, GVariant* parameters); +static void _dbus_handle_properties_properties_changed (Properties* self, GVariant* parameters); +static GVariant* properties_proxy_get (Properties* self, const gchar* iface, const gchar* property, GError** error); +static void properties_proxy_properties_interface_init (PropertiesIface* iface); +static void _dbus_properties_get (Properties* self, GVariant* parameters, GDBusMethodInvocation* invocation); +static void properties_dbus_interface_method_call (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data); +static GVariant* properties_dbus_interface_get_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GError** error, gpointer user_data); +static gboolean properties_dbus_interface_set_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GVariant* value, GError** error, gpointer user_data); +static void _dbus_properties_properties_changed (GObject* _sender, const gchar* iface, GHashTable* changed_properties, gchar** invalidated_properties, int invalidated_properties_length1, gpointer* _data); +static void _properties_unregister_object (gpointer user_data); +static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func); +static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func); + +static const GDBusArgInfo _manager_dbus_arg_info_list_units_result = {-1, "result", "a(ssssssouso)"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_list_units_in[] = {NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_list_units_out[] = {&_manager_dbus_arg_info_list_units_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_list_units = {-1, "ListUnits", (GDBusArgInfo **) (&_manager_dbus_arg_info_list_units_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_list_units_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_list_jobs_result = {-1, "result", "a(usssoo)"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_list_jobs_in[] = {NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_list_jobs_out[] = {&_manager_dbus_arg_info_list_jobs_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_list_jobs = {-1, "ListJobs", (GDBusArgInfo **) (&_manager_dbus_arg_info_list_jobs_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_list_jobs_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_get_unit_name = {-1, "name", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_get_unit_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_get_unit_in[] = {&_manager_dbus_arg_info_get_unit_name, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_get_unit_out[] = {&_manager_dbus_arg_info_get_unit_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_get_unit = {-1, "GetUnit", (GDBusArgInfo **) (&_manager_dbus_arg_info_get_unit_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_get_unit_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_get_unit_by_pid_pid = {-1, "pid", "u"}; +static const GDBusArgInfo _manager_dbus_arg_info_get_unit_by_pid_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_get_unit_by_pid_in[] = {&_manager_dbus_arg_info_get_unit_by_pid_pid, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_get_unit_by_pid_out[] = {&_manager_dbus_arg_info_get_unit_by_pid_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_get_unit_by_pid = {-1, "GetUnitByPid", (GDBusArgInfo **) (&_manager_dbus_arg_info_get_unit_by_pid_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_get_unit_by_pid_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_load_unit_name = {-1, "name", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_load_unit_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_load_unit_in[] = {&_manager_dbus_arg_info_load_unit_name, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_load_unit_out[] = {&_manager_dbus_arg_info_load_unit_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_load_unit = {-1, "LoadUnit", (GDBusArgInfo **) (&_manager_dbus_arg_info_load_unit_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_load_unit_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_get_job_id = {-1, "id", "u"}; +static const GDBusArgInfo _manager_dbus_arg_info_get_job_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_get_job_in[] = {&_manager_dbus_arg_info_get_job_id, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_get_job_out[] = {&_manager_dbus_arg_info_get_job_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_get_job = {-1, "GetJob", (GDBusArgInfo **) (&_manager_dbus_arg_info_get_job_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_get_job_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_start_unit_name = {-1, "name", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_start_unit_mode = {-1, "mode", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_start_unit_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_start_unit_in[] = {&_manager_dbus_arg_info_start_unit_name, &_manager_dbus_arg_info_start_unit_mode, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_start_unit_out[] = {&_manager_dbus_arg_info_start_unit_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_start_unit = {-1, "StartUnit", (GDBusArgInfo **) (&_manager_dbus_arg_info_start_unit_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_start_unit_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_stop_unit_name = {-1, "name", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_stop_unit_mode = {-1, "mode", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_stop_unit_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_stop_unit_in[] = {&_manager_dbus_arg_info_stop_unit_name, &_manager_dbus_arg_info_stop_unit_mode, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_stop_unit_out[] = {&_manager_dbus_arg_info_stop_unit_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_stop_unit = {-1, "StopUnit", (GDBusArgInfo **) (&_manager_dbus_arg_info_stop_unit_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_stop_unit_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_reload_unit_name = {-1, "name", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_reload_unit_mode = {-1, "mode", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_reload_unit_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_reload_unit_in[] = {&_manager_dbus_arg_info_reload_unit_name, &_manager_dbus_arg_info_reload_unit_mode, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_reload_unit_out[] = {&_manager_dbus_arg_info_reload_unit_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_reload_unit = {-1, "ReloadUnit", (GDBusArgInfo **) (&_manager_dbus_arg_info_reload_unit_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_reload_unit_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_restart_unit_name = {-1, "name", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_restart_unit_mode = {-1, "mode", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_restart_unit_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_restart_unit_in[] = {&_manager_dbus_arg_info_restart_unit_name, &_manager_dbus_arg_info_restart_unit_mode, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_restart_unit_out[] = {&_manager_dbus_arg_info_restart_unit_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_restart_unit = {-1, "RestartUnit", (GDBusArgInfo **) (&_manager_dbus_arg_info_restart_unit_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_restart_unit_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_try_restart_unit_name = {-1, "name", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_try_restart_unit_mode = {-1, "mode", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_try_restart_unit_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_try_restart_unit_in[] = {&_manager_dbus_arg_info_try_restart_unit_name, &_manager_dbus_arg_info_try_restart_unit_mode, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_try_restart_unit_out[] = {&_manager_dbus_arg_info_try_restart_unit_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_try_restart_unit = {-1, "TryRestartUnit", (GDBusArgInfo **) (&_manager_dbus_arg_info_try_restart_unit_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_try_restart_unit_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_reload_or_restart_unit_name = {-1, "name", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_reload_or_restart_unit_mode = {-1, "mode", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_reload_or_restart_unit_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_reload_or_restart_unit_in[] = {&_manager_dbus_arg_info_reload_or_restart_unit_name, &_manager_dbus_arg_info_reload_or_restart_unit_mode, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_reload_or_restart_unit_out[] = {&_manager_dbus_arg_info_reload_or_restart_unit_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_reload_or_restart_unit = {-1, "ReloadOrRestartUnit", (GDBusArgInfo **) (&_manager_dbus_arg_info_reload_or_restart_unit_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_reload_or_restart_unit_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_reload_or_try_restart_unit_name = {-1, "name", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_reload_or_try_restart_unit_mode = {-1, "mode", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_reload_or_try_restart_unit_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_reload_or_try_restart_unit_in[] = {&_manager_dbus_arg_info_reload_or_try_restart_unit_name, &_manager_dbus_arg_info_reload_or_try_restart_unit_mode, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_reload_or_try_restart_unit_out[] = {&_manager_dbus_arg_info_reload_or_try_restart_unit_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_reload_or_try_restart_unit = {-1, "ReloadOrTryRestartUnit", (GDBusArgInfo **) (&_manager_dbus_arg_info_reload_or_try_restart_unit_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_reload_or_try_restart_unit_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_reset_failed_unit_name = {-1, "name", "s"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_reset_failed_unit_in[] = {&_manager_dbus_arg_info_reset_failed_unit_name, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_reset_failed_unit_out[] = {NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_reset_failed_unit = {-1, "ResetFailedUnit", (GDBusArgInfo **) (&_manager_dbus_arg_info_reset_failed_unit_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_reset_failed_unit_out)}; +static const GDBusArgInfo * const _manager_dbus_arg_info_clear_jobs_in[] = {NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_clear_jobs_out[] = {NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_clear_jobs = {-1, "ClearJobs", (GDBusArgInfo **) (&_manager_dbus_arg_info_clear_jobs_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_clear_jobs_out)}; +static const GDBusArgInfo * const _manager_dbus_arg_info_subscribe_in[] = {NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_subscribe_out[] = {NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_subscribe = {-1, "Subscribe", (GDBusArgInfo **) (&_manager_dbus_arg_info_subscribe_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_subscribe_out)}; +static const GDBusArgInfo * const _manager_dbus_arg_info_unsubscribe_in[] = {NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_unsubscribe_out[] = {NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_unsubscribe = {-1, "Unsubscribe", (GDBusArgInfo **) (&_manager_dbus_arg_info_unsubscribe_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_unsubscribe_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_dump_result = {-1, "result", "s"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_dump_in[] = {NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_dump_out[] = {&_manager_dbus_arg_info_dump_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_dump = {-1, "Dump", (GDBusArgInfo **) (&_manager_dbus_arg_info_dump_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_dump_out)}; +static const GDBusArgInfo * const _manager_dbus_arg_info_reload_in[] = {NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_reload_out[] = {NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_reload = {-1, "Reload", (GDBusArgInfo **) (&_manager_dbus_arg_info_reload_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_reload_out)}; +static const GDBusArgInfo * const _manager_dbus_arg_info_reexecute_in[] = {NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_reexecute_out[] = {NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_reexecute = {-1, "Reexecute", (GDBusArgInfo **) (&_manager_dbus_arg_info_reexecute_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_reexecute_out)}; +static const GDBusArgInfo * const _manager_dbus_arg_info_exit_in[] = {NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_exit_out[] = {NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_exit = {-1, "Exit", (GDBusArgInfo **) (&_manager_dbus_arg_info_exit_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_exit_out)}; +static const GDBusArgInfo * const _manager_dbus_arg_info_halt_in[] = {NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_halt_out[] = {NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_halt = {-1, "Halt", (GDBusArgInfo **) (&_manager_dbus_arg_info_halt_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_halt_out)}; +static const GDBusArgInfo * const _manager_dbus_arg_info_power_off_in[] = {NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_power_off_out[] = {NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_power_off = {-1, "PowerOff", (GDBusArgInfo **) (&_manager_dbus_arg_info_power_off_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_power_off_out)}; +static const GDBusArgInfo * const _manager_dbus_arg_info_reboot_in[] = {NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_reboot_out[] = {NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_reboot = {-1, "Reboot", (GDBusArgInfo **) (&_manager_dbus_arg_info_reboot_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_reboot_out)}; +static const GDBusArgInfo * const _manager_dbus_arg_info_kexec_in[] = {NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_kexec_out[] = {NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_kexec = {-1, "Kexec", (GDBusArgInfo **) (&_manager_dbus_arg_info_kexec_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_kexec_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_create_snapshot_name = {-1, "name", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_create_snapshot_cleanup = {-1, "cleanup", "b"}; +static const GDBusArgInfo _manager_dbus_arg_info_create_snapshot_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_create_snapshot_in[] = {&_manager_dbus_arg_info_create_snapshot_name, &_manager_dbus_arg_info_create_snapshot_cleanup, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_create_snapshot_out[] = {&_manager_dbus_arg_info_create_snapshot_result, NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_create_snapshot = {-1, "CreateSnapshot", (GDBusArgInfo **) (&_manager_dbus_arg_info_create_snapshot_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_create_snapshot_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_set_environment_names = {-1, "names", "as"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_set_environment_in[] = {&_manager_dbus_arg_info_set_environment_names, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_set_environment_out[] = {NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_set_environment = {-1, "SetEnvironment", (GDBusArgInfo **) (&_manager_dbus_arg_info_set_environment_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_set_environment_out)}; +static const GDBusArgInfo _manager_dbus_arg_info_unset_environment_names = {-1, "names", "as"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_unset_environment_in[] = {&_manager_dbus_arg_info_unset_environment_names, NULL}; +static const GDBusArgInfo * const _manager_dbus_arg_info_unset_environment_out[] = {NULL}; +static const GDBusMethodInfo _manager_dbus_method_info_unset_environment = {-1, "UnsetEnvironment", (GDBusArgInfo **) (&_manager_dbus_arg_info_unset_environment_in), (GDBusArgInfo **) (&_manager_dbus_arg_info_unset_environment_out)}; +static const GDBusMethodInfo * const _manager_dbus_method_info[] = {&_manager_dbus_method_info_list_units, &_manager_dbus_method_info_list_jobs, &_manager_dbus_method_info_get_unit, &_manager_dbus_method_info_get_unit_by_pid, &_manager_dbus_method_info_load_unit, &_manager_dbus_method_info_get_job, &_manager_dbus_method_info_start_unit, &_manager_dbus_method_info_stop_unit, &_manager_dbus_method_info_reload_unit, &_manager_dbus_method_info_restart_unit, &_manager_dbus_method_info_try_restart_unit, &_manager_dbus_method_info_reload_or_restart_unit, &_manager_dbus_method_info_reload_or_try_restart_unit, &_manager_dbus_method_info_reset_failed_unit, &_manager_dbus_method_info_clear_jobs, &_manager_dbus_method_info_subscribe, &_manager_dbus_method_info_unsubscribe, &_manager_dbus_method_info_dump, &_manager_dbus_method_info_reload, &_manager_dbus_method_info_reexecute, &_manager_dbus_method_info_exit, &_manager_dbus_method_info_halt, &_manager_dbus_method_info_power_off, &_manager_dbus_method_info_reboot, &_manager_dbus_method_info_kexec, &_manager_dbus_method_info_create_snapshot, &_manager_dbus_method_info_set_environment, &_manager_dbus_method_info_unset_environment, NULL}; +static const GDBusArgInfo _manager_dbus_arg_info_unit_new_id = {-1, "id", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_unit_new_path = {-1, "path", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_unit_new[] = {&_manager_dbus_arg_info_unit_new_id, &_manager_dbus_arg_info_unit_new_path, NULL}; +static const GDBusSignalInfo _manager_dbus_signal_info_unit_new = {-1, "UnitNew", (GDBusArgInfo **) (&_manager_dbus_arg_info_unit_new)}; +static const GDBusArgInfo _manager_dbus_arg_info_unit_removed_id = {-1, "id", "s"}; +static const GDBusArgInfo _manager_dbus_arg_info_unit_removed_path = {-1, "path", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_unit_removed[] = {&_manager_dbus_arg_info_unit_removed_id, &_manager_dbus_arg_info_unit_removed_path, NULL}; +static const GDBusSignalInfo _manager_dbus_signal_info_unit_removed = {-1, "UnitRemoved", (GDBusArgInfo **) (&_manager_dbus_arg_info_unit_removed)}; +static const GDBusArgInfo _manager_dbus_arg_info_job_new_id = {-1, "id", "u"}; +static const GDBusArgInfo _manager_dbus_arg_info_job_new_path = {-1, "path", "o"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_job_new[] = {&_manager_dbus_arg_info_job_new_id, &_manager_dbus_arg_info_job_new_path, NULL}; +static const GDBusSignalInfo _manager_dbus_signal_info_job_new = {-1, "JobNew", (GDBusArgInfo **) (&_manager_dbus_arg_info_job_new)}; +static const GDBusArgInfo _manager_dbus_arg_info_job_removed_id = {-1, "id", "u"}; +static const GDBusArgInfo _manager_dbus_arg_info_job_removed_path = {-1, "path", "o"}; +static const GDBusArgInfo _manager_dbus_arg_info_job_removed_res = {-1, "res", "s"}; +static const GDBusArgInfo * const _manager_dbus_arg_info_job_removed[] = {&_manager_dbus_arg_info_job_removed_id, &_manager_dbus_arg_info_job_removed_path, &_manager_dbus_arg_info_job_removed_res, NULL}; +static const GDBusSignalInfo _manager_dbus_signal_info_job_removed = {-1, "JobRemoved", (GDBusArgInfo **) (&_manager_dbus_arg_info_job_removed)}; +static const GDBusSignalInfo * const _manager_dbus_signal_info[] = {&_manager_dbus_signal_info_unit_new, &_manager_dbus_signal_info_unit_removed, &_manager_dbus_signal_info_job_new, &_manager_dbus_signal_info_job_removed, NULL}; +static const GDBusPropertyInfo _manager_dbus_property_info_environment = {-1, "Environment", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo * const _manager_dbus_property_info[] = {&_manager_dbus_property_info_environment, NULL}; +static const GDBusInterfaceInfo _manager_dbus_interface_info = {-1, "org.freedesktop.systemd1.Manager", (GDBusMethodInfo **) (&_manager_dbus_method_info), (GDBusSignalInfo **) (&_manager_dbus_signal_info), (GDBusPropertyInfo **) (&_manager_dbus_property_info)}; +static const GDBusInterfaceVTable _manager_dbus_interface_vtable = {manager_dbus_interface_method_call, manager_dbus_interface_get_property, manager_dbus_interface_set_property}; +static const GDBusArgInfo _unit_dbus_arg_info_start_mode = {-1, "mode", "s"}; +static const GDBusArgInfo _unit_dbus_arg_info_start_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _unit_dbus_arg_info_start_in[] = {&_unit_dbus_arg_info_start_mode, NULL}; +static const GDBusArgInfo * const _unit_dbus_arg_info_start_out[] = {&_unit_dbus_arg_info_start_result, NULL}; +static const GDBusMethodInfo _unit_dbus_method_info_start = {-1, "Start", (GDBusArgInfo **) (&_unit_dbus_arg_info_start_in), (GDBusArgInfo **) (&_unit_dbus_arg_info_start_out)}; +static const GDBusArgInfo _unit_dbus_arg_info_stop_mode = {-1, "mode", "s"}; +static const GDBusArgInfo _unit_dbus_arg_info_stop_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _unit_dbus_arg_info_stop_in[] = {&_unit_dbus_arg_info_stop_mode, NULL}; +static const GDBusArgInfo * const _unit_dbus_arg_info_stop_out[] = {&_unit_dbus_arg_info_stop_result, NULL}; +static const GDBusMethodInfo _unit_dbus_method_info_stop = {-1, "Stop", (GDBusArgInfo **) (&_unit_dbus_arg_info_stop_in), (GDBusArgInfo **) (&_unit_dbus_arg_info_stop_out)}; +static const GDBusArgInfo _unit_dbus_arg_info_reload_mode = {-1, "mode", "s"}; +static const GDBusArgInfo _unit_dbus_arg_info_reload_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _unit_dbus_arg_info_reload_in[] = {&_unit_dbus_arg_info_reload_mode, NULL}; +static const GDBusArgInfo * const _unit_dbus_arg_info_reload_out[] = {&_unit_dbus_arg_info_reload_result, NULL}; +static const GDBusMethodInfo _unit_dbus_method_info_reload = {-1, "Reload", (GDBusArgInfo **) (&_unit_dbus_arg_info_reload_in), (GDBusArgInfo **) (&_unit_dbus_arg_info_reload_out)}; +static const GDBusArgInfo _unit_dbus_arg_info_restart_mode = {-1, "mode", "s"}; +static const GDBusArgInfo _unit_dbus_arg_info_restart_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _unit_dbus_arg_info_restart_in[] = {&_unit_dbus_arg_info_restart_mode, NULL}; +static const GDBusArgInfo * const _unit_dbus_arg_info_restart_out[] = {&_unit_dbus_arg_info_restart_result, NULL}; +static const GDBusMethodInfo _unit_dbus_method_info_restart = {-1, "Restart", (GDBusArgInfo **) (&_unit_dbus_arg_info_restart_in), (GDBusArgInfo **) (&_unit_dbus_arg_info_restart_out)}; +static const GDBusArgInfo _unit_dbus_arg_info_try_restart_mode = {-1, "mode", "s"}; +static const GDBusArgInfo _unit_dbus_arg_info_try_restart_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _unit_dbus_arg_info_try_restart_in[] = {&_unit_dbus_arg_info_try_restart_mode, NULL}; +static const GDBusArgInfo * const _unit_dbus_arg_info_try_restart_out[] = {&_unit_dbus_arg_info_try_restart_result, NULL}; +static const GDBusMethodInfo _unit_dbus_method_info_try_restart = {-1, "TryRestart", (GDBusArgInfo **) (&_unit_dbus_arg_info_try_restart_in), (GDBusArgInfo **) (&_unit_dbus_arg_info_try_restart_out)}; +static const GDBusArgInfo _unit_dbus_arg_info_reload_or_restart_mode = {-1, "mode", "s"}; +static const GDBusArgInfo _unit_dbus_arg_info_reload_or_restart_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _unit_dbus_arg_info_reload_or_restart_in[] = {&_unit_dbus_arg_info_reload_or_restart_mode, NULL}; +static const GDBusArgInfo * const _unit_dbus_arg_info_reload_or_restart_out[] = {&_unit_dbus_arg_info_reload_or_restart_result, NULL}; +static const GDBusMethodInfo _unit_dbus_method_info_reload_or_restart = {-1, "ReloadOrRestart", (GDBusArgInfo **) (&_unit_dbus_arg_info_reload_or_restart_in), (GDBusArgInfo **) (&_unit_dbus_arg_info_reload_or_restart_out)}; +static const GDBusArgInfo _unit_dbus_arg_info_reload_or_try_restart_mode = {-1, "mode", "s"}; +static const GDBusArgInfo _unit_dbus_arg_info_reload_or_try_restart_result = {-1, "result", "o"}; +static const GDBusArgInfo * const _unit_dbus_arg_info_reload_or_try_restart_in[] = {&_unit_dbus_arg_info_reload_or_try_restart_mode, NULL}; +static const GDBusArgInfo * const _unit_dbus_arg_info_reload_or_try_restart_out[] = {&_unit_dbus_arg_info_reload_or_try_restart_result, NULL}; +static const GDBusMethodInfo _unit_dbus_method_info_reload_or_try_restart = {-1, "ReloadOrTryRestart", (GDBusArgInfo **) (&_unit_dbus_arg_info_reload_or_try_restart_in), (GDBusArgInfo **) (&_unit_dbus_arg_info_reload_or_try_restart_out)}; +static const GDBusArgInfo * const _unit_dbus_arg_info_reset_failed_in[] = {NULL}; +static const GDBusArgInfo * const _unit_dbus_arg_info_reset_failed_out[] = {NULL}; +static const GDBusMethodInfo _unit_dbus_method_info_reset_failed = {-1, "ResetFailed", (GDBusArgInfo **) (&_unit_dbus_arg_info_reset_failed_in), (GDBusArgInfo **) (&_unit_dbus_arg_info_reset_failed_out)}; +static const GDBusMethodInfo * const _unit_dbus_method_info[] = {&_unit_dbus_method_info_start, &_unit_dbus_method_info_stop, &_unit_dbus_method_info_reload, &_unit_dbus_method_info_restart, &_unit_dbus_method_info_try_restart, &_unit_dbus_method_info_reload_or_restart, &_unit_dbus_method_info_reload_or_try_restart, &_unit_dbus_method_info_reset_failed, NULL}; +static const GDBusSignalInfo * const _unit_dbus_signal_info[] = {NULL}; +static const GDBusPropertyInfo _unit_dbus_property_info_id = {-1, "Id", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_names = {-1, "Names", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_following = {-1, "Following", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_requires = {-1, "Requires", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_requires_overridable = {-1, "RequiresOverridable", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_requisite = {-1, "Requisite", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_requisite_overridable = {-1, "RequisiteOverridable", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_wants = {-1, "Wants", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_required_by = {-1, "RequiredBy", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_required_by_overridable = {-1, "RequiredByOverridable", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_wanted_by = {-1, "WantedBy", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_conflicts = {-1, "Conflicts", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_conflicted_by = {-1, "ConflictedBy", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_before = {-1, "Before", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_after = {-1, "After", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_on_failure = {-1, "OnFailure", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_description = {-1, "Description", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_load_state = {-1, "LoadState", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_active_state = {-1, "ActiveState", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_sub_state = {-1, "SubState", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_fragment_path = {-1, "FragmentPath", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_inactive_exit_timestamp = {-1, "InactiveExitTimestamp", "t", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_active_enter_timestamp = {-1, "ActiveEnterTimestamp", "t", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_active_exit_timestamp = {-1, "ActiveExitTimestamp", "t", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_inactive_enter_timestamp = {-1, "InactiveEnterTimestamp", "t", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_can_start = {-1, "CanStart", "b", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_can_stop = {-1, "CanStop", "b", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_can_reload = {-1, "CanReload", "b", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_job = {-1, "Job", "(uo)", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_recursive_stop = {-1, "RecursiveStop", "b", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_stop_when_unneeded = {-1, "StopWhenUnneeded", "b", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_refuse_manual_start = {-1, "RefuseManualStart", "b", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_refuse_manual_stop = {-1, "RefuseManualStop", "b", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_default_dependencies = {-1, "DefaultDependencies", "b", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_default_control_group = {-1, "DefaultControlGroup", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_control_groups = {-1, "ControlGroups", "as", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_need_daemon_reload = {-1, "NeedDaemonReload", "b", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _unit_dbus_property_info_job_timeout_usec = {-1, "JobTimeoutUsec", "t", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo * const _unit_dbus_property_info[] = {&_unit_dbus_property_info_id, &_unit_dbus_property_info_names, &_unit_dbus_property_info_following, &_unit_dbus_property_info_requires, &_unit_dbus_property_info_requires_overridable, &_unit_dbus_property_info_requisite, &_unit_dbus_property_info_requisite_overridable, &_unit_dbus_property_info_wants, &_unit_dbus_property_info_required_by, &_unit_dbus_property_info_required_by_overridable, &_unit_dbus_property_info_wanted_by, &_unit_dbus_property_info_conflicts, &_unit_dbus_property_info_conflicted_by, &_unit_dbus_property_info_before, &_unit_dbus_property_info_after, &_unit_dbus_property_info_on_failure, &_unit_dbus_property_info_description, &_unit_dbus_property_info_load_state, &_unit_dbus_property_info_active_state, &_unit_dbus_property_info_sub_state, &_unit_dbus_property_info_fragment_path, &_unit_dbus_property_info_inactive_exit_timestamp, &_unit_dbus_property_info_active_enter_timestamp, &_unit_dbus_property_info_active_exit_timestamp, &_unit_dbus_property_info_inactive_enter_timestamp, &_unit_dbus_property_info_can_start, &_unit_dbus_property_info_can_stop, &_unit_dbus_property_info_can_reload, &_unit_dbus_property_info_job, &_unit_dbus_property_info_recursive_stop, &_unit_dbus_property_info_stop_when_unneeded, &_unit_dbus_property_info_refuse_manual_start, &_unit_dbus_property_info_refuse_manual_stop, &_unit_dbus_property_info_default_dependencies, &_unit_dbus_property_info_default_control_group, &_unit_dbus_property_info_control_groups, &_unit_dbus_property_info_need_daemon_reload, &_unit_dbus_property_info_job_timeout_usec, NULL}; +static const GDBusInterfaceInfo _unit_dbus_interface_info = {-1, "org.freedesktop.systemd1.Unit", (GDBusMethodInfo **) (&_unit_dbus_method_info), (GDBusSignalInfo **) (&_unit_dbus_signal_info), (GDBusPropertyInfo **) (&_unit_dbus_property_info)}; +static const GDBusInterfaceVTable _unit_dbus_interface_vtable = {unit_dbus_interface_method_call, unit_dbus_interface_get_property, unit_dbus_interface_set_property}; +static const GDBusArgInfo * const _job_dbus_arg_info_cancel_in[] = {NULL}; +static const GDBusArgInfo * const _job_dbus_arg_info_cancel_out[] = {NULL}; +static const GDBusMethodInfo _job_dbus_method_info_cancel = {-1, "Cancel", (GDBusArgInfo **) (&_job_dbus_arg_info_cancel_in), (GDBusArgInfo **) (&_job_dbus_arg_info_cancel_out)}; +static const GDBusMethodInfo * const _job_dbus_method_info[] = {&_job_dbus_method_info_cancel, NULL}; +static const GDBusSignalInfo * const _job_dbus_signal_info[] = {NULL}; +static const GDBusPropertyInfo _job_dbus_property_info_id = {-1, "Id", "u", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _job_dbus_property_info_state = {-1, "State", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _job_dbus_property_info_job_type = {-1, "JobType", "s", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo _job_dbus_property_info_unit = {-1, "Unit", "(so)", G_DBUS_PROPERTY_INFO_FLAGS_READABLE}; +static const GDBusPropertyInfo * const _job_dbus_property_info[] = {&_job_dbus_property_info_id, &_job_dbus_property_info_state, &_job_dbus_property_info_job_type, &_job_dbus_property_info_unit, NULL}; +static const GDBusInterfaceInfo _job_dbus_interface_info = {-1, "org.freedesktop.systemd1.Job", (GDBusMethodInfo **) (&_job_dbus_method_info), (GDBusSignalInfo **) (&_job_dbus_signal_info), (GDBusPropertyInfo **) (&_job_dbus_property_info)}; +static const GDBusInterfaceVTable _job_dbus_interface_vtable = {job_dbus_interface_method_call, job_dbus_interface_get_property, job_dbus_interface_set_property}; +static const GDBusArgInfo _properties_dbus_arg_info_get_iface = {-1, "iface", "s"}; +static const GDBusArgInfo _properties_dbus_arg_info_get_property = {-1, "property", "s"}; +static const GDBusArgInfo _properties_dbus_arg_info_get_result = {-1, "result", "v"}; +static const GDBusArgInfo * const _properties_dbus_arg_info_get_in[] = {&_properties_dbus_arg_info_get_iface, &_properties_dbus_arg_info_get_property, NULL}; +static const GDBusArgInfo * const _properties_dbus_arg_info_get_out[] = {&_properties_dbus_arg_info_get_result, NULL}; +static const GDBusMethodInfo _properties_dbus_method_info_get = {-1, "Get", (GDBusArgInfo **) (&_properties_dbus_arg_info_get_in), (GDBusArgInfo **) (&_properties_dbus_arg_info_get_out)}; +static const GDBusMethodInfo * const _properties_dbus_method_info[] = {&_properties_dbus_method_info_get, NULL}; +static const GDBusArgInfo _properties_dbus_arg_info_properties_changed_iface = {-1, "iface", "s"}; +static const GDBusArgInfo _properties_dbus_arg_info_properties_changed_changed_properties = {-1, "changed_properties", "a{sv}"}; +static const GDBusArgInfo _properties_dbus_arg_info_properties_changed_invalidated_properties = {-1, "invalidated_properties", "as"}; +static const GDBusArgInfo * const _properties_dbus_arg_info_properties_changed[] = {&_properties_dbus_arg_info_properties_changed_iface, &_properties_dbus_arg_info_properties_changed_changed_properties, &_properties_dbus_arg_info_properties_changed_invalidated_properties, NULL}; +static const GDBusSignalInfo _properties_dbus_signal_info_properties_changed = {-1, "PropertiesChanged", (GDBusArgInfo **) (&_properties_dbus_arg_info_properties_changed)}; +static const GDBusSignalInfo * const _properties_dbus_signal_info[] = {&_properties_dbus_signal_info_properties_changed, NULL}; +static const GDBusPropertyInfo * const _properties_dbus_property_info[] = {NULL}; +static const GDBusInterfaceInfo _properties_dbus_interface_info = {-1, "org.freedesktop.Properties", (GDBusMethodInfo **) (&_properties_dbus_method_info), (GDBusSignalInfo **) (&_properties_dbus_signal_info), (GDBusPropertyInfo **) (&_properties_dbus_property_info)}; +static const GDBusInterfaceVTable _properties_dbus_interface_vtable = {properties_dbus_interface_method_call, properties_dbus_interface_get_property, properties_dbus_interface_set_property}; + +ManagerUnitInfo* manager_list_units (Manager* self, int* result_length1, GError** error) { +#line 47 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 47 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->list_units (self, result_length1, error); +#line 785 "systemd-interfaces.c" +} + + +ManagerJobInfo* manager_list_jobs (Manager* self, int* result_length1, GError** error) { +#line 48 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 48 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->list_jobs (self, result_length1, error); +#line 794 "systemd-interfaces.c" +} + + +char* manager_get_unit (Manager* self, const gchar* name, GError** error) { +#line 50 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 50 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->get_unit (self, name, error); +#line 803 "systemd-interfaces.c" +} + + +char* manager_get_unit_by_pid (Manager* self, guint32 pid, GError** error) { +#line 51 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 51 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->get_unit_by_pid (self, pid, error); +#line 812 "systemd-interfaces.c" +} + + +char* manager_load_unit (Manager* self, const gchar* name, GError** error) { +#line 52 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 52 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->load_unit (self, name, error); +#line 821 "systemd-interfaces.c" +} + + +char* manager_get_job (Manager* self, guint32 id, GError** error) { +#line 53 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 53 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->get_job (self, id, error); +#line 830 "systemd-interfaces.c" +} + + +char* manager_start_unit (Manager* self, const gchar* name, const gchar* mode, GError** error) { +#line 55 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 55 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->start_unit (self, name, mode, error); +#line 839 "systemd-interfaces.c" +} + + +char* manager_stop_unit (Manager* self, const gchar* name, const gchar* mode, GError** error) { +#line 56 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 56 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->stop_unit (self, name, mode, error); +#line 848 "systemd-interfaces.c" +} + + +char* manager_reload_unit (Manager* self, const gchar* name, const gchar* mode, GError** error) { +#line 57 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 57 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->reload_unit (self, name, mode, error); +#line 857 "systemd-interfaces.c" +} + + +char* manager_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error) { +#line 58 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 58 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->restart_unit (self, name, mode, error); +#line 866 "systemd-interfaces.c" +} + + +char* manager_try_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error) { +#line 59 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 59 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->try_restart_unit (self, name, mode, error); +#line 875 "systemd-interfaces.c" +} + + +char* manager_reload_or_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error) { +#line 60 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 60 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->reload_or_restart_unit (self, name, mode, error); +#line 884 "systemd-interfaces.c" +} + + +char* manager_reload_or_try_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error) { +#line 61 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 61 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->reload_or_try_restart_unit (self, name, mode, error); +#line 893 "systemd-interfaces.c" +} + + +void manager_reset_failed_unit (Manager* self, const gchar* name, GError** error) { +#line 63 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 63 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + MANAGER_GET_INTERFACE (self)->reset_failed_unit (self, name, error); +#line 902 "systemd-interfaces.c" +} + + +void manager_clear_jobs (Manager* self, GError** error) { +#line 65 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 65 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + MANAGER_GET_INTERFACE (self)->clear_jobs (self, error); +#line 911 "systemd-interfaces.c" +} + + +void manager_subscribe (Manager* self, GError** error) { +#line 67 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 67 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + MANAGER_GET_INTERFACE (self)->subscribe (self, error); +#line 920 "systemd-interfaces.c" +} + + +void manager_unsubscribe (Manager* self, GError** error) { +#line 68 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 68 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + MANAGER_GET_INTERFACE (self)->unsubscribe (self, error); +#line 929 "systemd-interfaces.c" +} + + +gchar* manager_dump (Manager* self, GError** error) { +#line 70 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 70 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->dump (self, error); +#line 938 "systemd-interfaces.c" +} + + +void manager_reload (Manager* self, GError** error) { +#line 72 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 72 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + MANAGER_GET_INTERFACE (self)->reload (self, error); +#line 947 "systemd-interfaces.c" +} + + +void manager_reexecute (Manager* self, GError** error) { +#line 73 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 73 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + MANAGER_GET_INTERFACE (self)->reexecute (self, error); +#line 956 "systemd-interfaces.c" +} + + +void manager_exit (Manager* self, GError** error) { +#line 74 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 74 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + MANAGER_GET_INTERFACE (self)->exit (self, error); +#line 965 "systemd-interfaces.c" +} + + +void manager_halt (Manager* self, GError** error) { +#line 75 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 75 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + MANAGER_GET_INTERFACE (self)->halt (self, error); +#line 974 "systemd-interfaces.c" +} + + +void manager_power_off (Manager* self, GError** error) { +#line 76 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 76 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + MANAGER_GET_INTERFACE (self)->power_off (self, error); +#line 983 "systemd-interfaces.c" +} + + +void manager_reboot (Manager* self, GError** error) { +#line 77 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 77 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + MANAGER_GET_INTERFACE (self)->reboot (self, error); +#line 992 "systemd-interfaces.c" +} + + +void manager_kexec (Manager* self, GError** error) { +#line 78 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 78 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + MANAGER_GET_INTERFACE (self)->kexec (self, error); +#line 1001 "systemd-interfaces.c" +} + + +char* manager_create_snapshot (Manager* self, const gchar* name, gboolean cleanup, GError** error) { +#line 80 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 80 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->create_snapshot (self, name, cleanup, error); +#line 1010 "systemd-interfaces.c" +} + + +void manager_set_environment (Manager* self, gchar** names, int names_length1, GError** error) { +#line 82 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 82 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + MANAGER_GET_INTERFACE (self)->set_environment (self, names, names_length1, error); +#line 1019 "systemd-interfaces.c" +} + + +void manager_unset_environment (Manager* self, gchar** names, int names_length1, GError** error) { +#line 83 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 83 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + MANAGER_GET_INTERFACE (self)->unset_environment (self, names, names_length1, error); +#line 1028 "systemd-interfaces.c" +} + + +gchar** manager_get_environment (Manager* self, int* result_length1) { +#line 45 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 45 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return MANAGER_GET_INTERFACE (self)->get_environment (self, result_length1); +#line 1037 "systemd-interfaces.c" +} + + +static void g_cclosure_user_marshal_VOID__STRING_STRING (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) { + typedef void (*GMarshalFunc_VOID__STRING_STRING) (gpointer data1, const char* arg_1, gpointer arg_2, gpointer data2); + register GMarshalFunc_VOID__STRING_STRING callback; + register GCClosure * cc; + register gpointer data1; + register gpointer data2; + cc = (GCClosure *) closure; +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (n_param_values == 3); +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + if (G_CCLOSURE_SWAP_DATA (closure)) { +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data1 = closure->data; +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data2 = param_values->data[0].v_pointer; +#line 1056 "systemd-interfaces.c" + } else { +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data1 = param_values->data[0].v_pointer; +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data2 = closure->data; +#line 1062 "systemd-interfaces.c" + } +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + callback = (GMarshalFunc_VOID__STRING_STRING) (marshal_data ? marshal_data : cc->callback); +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + callback (data1, g_value_get_string (param_values + 1), g_value_get_string (param_values + 2), data2); +#line 1068 "systemd-interfaces.c" +} + + +static void g_cclosure_user_marshal_VOID__UINT_STRING (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) { + typedef void (*GMarshalFunc_VOID__UINT_STRING) (gpointer data1, guint32 arg_1, gpointer arg_2, gpointer data2); + register GMarshalFunc_VOID__UINT_STRING callback; + register GCClosure * cc; + register gpointer data1; + register gpointer data2; + cc = (GCClosure *) closure; +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (n_param_values == 3); +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + if (G_CCLOSURE_SWAP_DATA (closure)) { +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data1 = closure->data; +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data2 = param_values->data[0].v_pointer; +#line 1087 "systemd-interfaces.c" + } else { +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data1 = param_values->data[0].v_pointer; +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data2 = closure->data; +#line 1093 "systemd-interfaces.c" + } +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + callback = (GMarshalFunc_VOID__UINT_STRING) (marshal_data ? marshal_data : cc->callback); +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + callback (data1, g_value_get_uint (param_values + 1), g_value_get_string (param_values + 2), data2); +#line 1099 "systemd-interfaces.c" +} + + +static void g_cclosure_user_marshal_VOID__UINT_STRING_STRING (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) { + typedef void (*GMarshalFunc_VOID__UINT_STRING_STRING) (gpointer data1, guint32 arg_1, gpointer arg_2, const char* arg_3, gpointer data2); + register GMarshalFunc_VOID__UINT_STRING_STRING callback; + register GCClosure * cc; + register gpointer data1; + register gpointer data2; + cc = (GCClosure *) closure; +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (n_param_values == 4); +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + if (G_CCLOSURE_SWAP_DATA (closure)) { +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data1 = closure->data; +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data2 = param_values->data[0].v_pointer; +#line 1118 "systemd-interfaces.c" + } else { +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data1 = param_values->data[0].v_pointer; +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data2 = closure->data; +#line 1124 "systemd-interfaces.c" + } +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + callback = (GMarshalFunc_VOID__UINT_STRING_STRING) (marshal_data ? marshal_data : cc->callback); +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + callback (data1, g_value_get_uint (param_values + 1), g_value_get_string (param_values + 2), g_value_get_string (param_values + 3), data2); +#line 1130 "systemd-interfaces.c" +} + + +void manager_unit_info_copy (const ManagerUnitInfo* self, ManagerUnitInfo* dest) { + const gchar* _tmp0_; + gchar* _tmp1_; + const gchar* _tmp2_; + gchar* _tmp3_; + const gchar* _tmp4_; + gchar* _tmp5_; + const gchar* _tmp6_; + gchar* _tmp7_; + const gchar* _tmp8_; + gchar* _tmp9_; + const gchar* _tmp10_; + gchar* _tmp11_; + const char* _tmp12_; + char* _tmp13_; + guint32 _tmp14_; + const gchar* _tmp15_; + gchar* _tmp16_; + const char* _tmp17_; + char* _tmp18_; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp0_ = (*self).id; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp1_ = g_strdup (_tmp0_); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).id); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).id = _tmp1_; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp2_ = (*self).description; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp3_ = g_strdup (_tmp2_); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).description); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).description = _tmp3_; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp4_ = (*self).load_state; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp5_ = g_strdup (_tmp4_); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).load_state); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).load_state = _tmp5_; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp6_ = (*self).active_state; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp7_ = g_strdup (_tmp6_); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).active_state); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).active_state = _tmp7_; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp8_ = (*self).sub_state; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp9_ = g_strdup (_tmp8_); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).sub_state); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).sub_state = _tmp9_; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp10_ = (*self).following; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp11_ = g_strdup (_tmp10_); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).following); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).following = _tmp11_; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp12_ = (*self).unit_path; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp13_ = g_strdup (_tmp12_); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).unit_path); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).unit_path = _tmp13_; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp14_ = (*self).job_id; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).job_id = _tmp14_; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp15_ = (*self).job_type; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp16_ = g_strdup (_tmp15_); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).job_type); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).job_type = _tmp16_; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp17_ = (*self).job_path; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp18_ = g_strdup (_tmp17_); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).job_path); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).job_path = _tmp18_; +#line 1230 "systemd-interfaces.c" +} + + +void manager_unit_info_destroy (ManagerUnitInfo* self) { +#line 24 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).id); +#line 25 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).description); +#line 26 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).load_state); +#line 27 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).active_state); +#line 28 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).sub_state); +#line 29 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).following); +#line 30 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).unit_path); +#line 32 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).job_type); +#line 33 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).job_path); +#line 1253 "systemd-interfaces.c" +} + + +ManagerUnitInfo* manager_unit_info_dup (const ManagerUnitInfo* self) { + ManagerUnitInfo* dup; +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + dup = g_new0 (ManagerUnitInfo, 1); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + manager_unit_info_copy (self, dup); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return dup; +#line 1265 "systemd-interfaces.c" +} + + +void manager_unit_info_free (ManagerUnitInfo* self) { +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + manager_unit_info_destroy (self); +#line 23 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_free (self); +#line 1274 "systemd-interfaces.c" +} + + +GType manager_unit_info_get_type (void) { + static volatile gsize manager_unit_info_type_id__volatile = 0; + if (g_once_init_enter (&manager_unit_info_type_id__volatile)) { + GType manager_unit_info_type_id; + manager_unit_info_type_id = g_boxed_type_register_static ("ManagerUnitInfo", (GBoxedCopyFunc) manager_unit_info_dup, (GBoxedFreeFunc) manager_unit_info_free); + g_once_init_leave (&manager_unit_info_type_id__volatile, manager_unit_info_type_id); + } + return manager_unit_info_type_id__volatile; +} + + +void manager_job_info_copy (const ManagerJobInfo* self, ManagerJobInfo* dest) { + guint32 _tmp0_; + const gchar* _tmp1_; + gchar* _tmp2_; + const gchar* _tmp3_; + gchar* _tmp4_; + const gchar* _tmp5_; + gchar* _tmp6_; + const char* _tmp7_; + char* _tmp8_; + const char* _tmp9_; + char* _tmp10_; +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp0_ = (*self).id; +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).id = _tmp0_; +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp1_ = (*self).name; +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp2_ = g_strdup (_tmp1_); +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).name); +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).name = _tmp2_; +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp3_ = (*self).type; +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp4_ = g_strdup (_tmp3_); +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).type); +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).type = _tmp4_; +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp5_ = (*self).state; +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp6_ = g_strdup (_tmp5_); +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).state); +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).state = _tmp6_; +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp7_ = (*self).job_path; +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp8_ = g_strdup (_tmp7_); +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).job_path); +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).job_path = _tmp8_; +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp9_ = (*self).unit_path; +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp10_ = g_strdup (_tmp9_); +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).unit_path); +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).unit_path = _tmp10_; +#line 1345 "systemd-interfaces.c" +} + + +void manager_job_info_destroy (ManagerJobInfo* self) { +#line 38 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).name); +#line 39 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).type); +#line 40 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).state); +#line 41 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).job_path); +#line 42 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).unit_path); +#line 1360 "systemd-interfaces.c" +} + + +ManagerJobInfo* manager_job_info_dup (const ManagerJobInfo* self) { + ManagerJobInfo* dup; +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + dup = g_new0 (ManagerJobInfo, 1); +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + manager_job_info_copy (self, dup); +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return dup; +#line 1372 "systemd-interfaces.c" +} + + +void manager_job_info_free (ManagerJobInfo* self) { +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + manager_job_info_destroy (self); +#line 36 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_free (self); +#line 1381 "systemd-interfaces.c" +} + + +GType manager_job_info_get_type (void) { + static volatile gsize manager_job_info_type_id__volatile = 0; + if (g_once_init_enter (&manager_job_info_type_id__volatile)) { + GType manager_job_info_type_id; + manager_job_info_type_id = g_boxed_type_register_static ("ManagerJobInfo", (GBoxedCopyFunc) manager_job_info_dup, (GBoxedFreeFunc) manager_job_info_free); + g_once_init_leave (&manager_job_info_type_id__volatile, manager_job_info_type_id); + } + return manager_job_info_type_id__volatile; +} + + +static void manager_base_init (ManagerIface * iface) { +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + static gboolean initialized = FALSE; +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + if (!initialized) { +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + initialized = TRUE; +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_signal_new ("unit_new", TYPE_MANAGER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__STRING_STRING, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_signal_new ("unit_removed", TYPE_MANAGER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__STRING_STRING, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_signal_new ("job_new", TYPE_MANAGER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__UINT_STRING, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_STRING); +#line 21 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_signal_new ("job_removed", TYPE_MANAGER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__UINT_STRING_STRING, G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING); +#line 1411 "systemd-interfaces.c" + } +} + + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ +GType manager_get_type (void) { + static volatile gsize manager_type_id__volatile = 0; + if (g_once_init_enter (&manager_type_id__volatile)) { + static const GTypeInfo g_define_type_info = { sizeof (ManagerIface), (GBaseInitFunc) manager_base_init, (GBaseFinalizeFunc) NULL, (GClassInitFunc) NULL, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL }; + GType manager_type_id; + manager_type_id = g_type_register_static (G_TYPE_INTERFACE, "Manager", &g_define_type_info, 0); + g_type_interface_add_prerequisite (manager_type_id, G_TYPE_DBUS_PROXY); + g_type_set_qdata (manager_type_id, g_quark_from_static_string ("vala-dbus-proxy-type"), (void*) manager_proxy_get_type); + g_type_set_qdata (manager_type_id, g_quark_from_static_string ("vala-dbus-interface-name"), "org.freedesktop.systemd1.Manager"); + g_type_set_qdata (manager_type_id, g_quark_from_static_string ("vala-dbus-register-object"), (void*) manager_register_object); + g_once_init_leave (&manager_type_id__volatile, manager_type_id); + } + return manager_type_id__volatile; +} + + +G_DEFINE_TYPE_EXTENDED (ManagerProxy, manager_proxy, G_TYPE_DBUS_PROXY, 0, G_IMPLEMENT_INTERFACE (TYPE_MANAGER, manager_proxy_manager_interface_init) ) +static void manager_proxy_class_init (ManagerProxyClass* klass) { + G_DBUS_PROXY_CLASS (klass)->g_signal = manager_proxy_g_signal; +} + + +static void _dbus_handle_manager_unit_new (Manager* self, GVariant* parameters) { + GVariantIter _arguments_iter; + gchar* id = NULL; + GVariant* _tmp0_; + char* path = NULL; + GVariant* _tmp1_; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp0_ = g_variant_iter_next_value (&_arguments_iter); + id = g_variant_dup_string (_tmp0_, NULL); + g_variant_unref (_tmp0_); + _tmp1_ = g_variant_iter_next_value (&_arguments_iter); + path = g_variant_dup_string (_tmp1_, NULL); + g_variant_unref (_tmp1_); + g_signal_emit_by_name (self, "unit-new", id, path); + _g_free0 (id); + _g_free0 (path); +} + + +static void _dbus_handle_manager_unit_removed (Manager* self, GVariant* parameters) { + GVariantIter _arguments_iter; + gchar* id = NULL; + GVariant* _tmp2_; + char* path = NULL; + GVariant* _tmp3_; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp2_ = g_variant_iter_next_value (&_arguments_iter); + id = g_variant_dup_string (_tmp2_, NULL); + g_variant_unref (_tmp2_); + _tmp3_ = g_variant_iter_next_value (&_arguments_iter); + path = g_variant_dup_string (_tmp3_, NULL); + g_variant_unref (_tmp3_); + g_signal_emit_by_name (self, "unit-removed", id, path); + _g_free0 (id); + _g_free0 (path); +} + + +static void _dbus_handle_manager_job_new (Manager* self, GVariant* parameters) { + GVariantIter _arguments_iter; + guint32 id = 0U; + GVariant* _tmp4_; + char* path = NULL; + GVariant* _tmp5_; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp4_ = g_variant_iter_next_value (&_arguments_iter); + id = g_variant_get_uint32 (_tmp4_); + g_variant_unref (_tmp4_); + _tmp5_ = g_variant_iter_next_value (&_arguments_iter); + path = g_variant_dup_string (_tmp5_, NULL); + g_variant_unref (_tmp5_); + g_signal_emit_by_name (self, "job-new", id, path); + _g_free0 (path); +} + + +static void _dbus_handle_manager_job_removed (Manager* self, GVariant* parameters) { + GVariantIter _arguments_iter; + guint32 id = 0U; + GVariant* _tmp6_; + char* path = NULL; + GVariant* _tmp7_; + gchar* res = NULL; + GVariant* _tmp8_; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp6_ = g_variant_iter_next_value (&_arguments_iter); + id = g_variant_get_uint32 (_tmp6_); + g_variant_unref (_tmp6_); + _tmp7_ = g_variant_iter_next_value (&_arguments_iter); + path = g_variant_dup_string (_tmp7_, NULL); + g_variant_unref (_tmp7_); + _tmp8_ = g_variant_iter_next_value (&_arguments_iter); + res = g_variant_dup_string (_tmp8_, NULL); + g_variant_unref (_tmp8_); + g_signal_emit_by_name (self, "job-removed", id, path, res); + _g_free0 (path); + _g_free0 (res); +} + + +static void manager_proxy_g_signal (GDBusProxy* proxy, const gchar* sender_name, const gchar* signal_name, GVariant* parameters) { + if (strcmp (signal_name, "UnitNew") == 0) { + _dbus_handle_manager_unit_new ((Manager*) proxy, parameters); + } else if (strcmp (signal_name, "UnitRemoved") == 0) { + _dbus_handle_manager_unit_removed ((Manager*) proxy, parameters); + } else if (strcmp (signal_name, "JobNew") == 0) { + _dbus_handle_manager_job_new ((Manager*) proxy, parameters); + } else if (strcmp (signal_name, "JobRemoved") == 0) { + _dbus_handle_manager_job_removed ((Manager*) proxy, parameters); + } +} + + +static void manager_proxy_init (ManagerProxy* self) { +} + + +static ManagerUnitInfo* manager_proxy_list_units (Manager* self, int* result_length1, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + ManagerUnitInfo* _result; + int _result_length1; + GVariant* _tmp9_; + ManagerUnitInfo* _tmp10_; + int _tmp10__length; + int _tmp10__size; + int _tmp10__length1; + GVariantIter _tmp11_; + GVariant* _tmp12_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "ListUnits"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _result_length1 = 0; + _tmp9_ = g_variant_iter_next_value (&_reply_iter); + _tmp10_ = g_new (ManagerUnitInfo, 5); + _tmp10__length = 0; + _tmp10__size = 4; + _tmp10__length1 = 0; + g_variant_iter_init (&_tmp11_, _tmp9_); + for (; (_tmp12_ = g_variant_iter_next_value (&_tmp11_)) != NULL; _tmp10__length1++) { + ManagerUnitInfo _tmp13_; + GVariantIter _tmp14_; + GVariant* _tmp15_; + GVariant* _tmp16_; + GVariant* _tmp17_; + GVariant* _tmp18_; + GVariant* _tmp19_; + GVariant* _tmp20_; + GVariant* _tmp21_; + GVariant* _tmp22_; + GVariant* _tmp23_; + GVariant* _tmp24_; + if (_tmp10__size == _tmp10__length) { + _tmp10__size = 2 * _tmp10__size; + _tmp10_ = g_renew (ManagerUnitInfo, _tmp10_, _tmp10__size + 1); + } + g_variant_iter_init (&_tmp14_, _tmp12_); + _tmp15_ = g_variant_iter_next_value (&_tmp14_); + _tmp13_.id = g_variant_dup_string (_tmp15_, NULL); + g_variant_unref (_tmp15_); + _tmp16_ = g_variant_iter_next_value (&_tmp14_); + _tmp13_.description = g_variant_dup_string (_tmp16_, NULL); + g_variant_unref (_tmp16_); + _tmp17_ = g_variant_iter_next_value (&_tmp14_); + _tmp13_.load_state = g_variant_dup_string (_tmp17_, NULL); + g_variant_unref (_tmp17_); + _tmp18_ = g_variant_iter_next_value (&_tmp14_); + _tmp13_.active_state = g_variant_dup_string (_tmp18_, NULL); + g_variant_unref (_tmp18_); + _tmp19_ = g_variant_iter_next_value (&_tmp14_); + _tmp13_.sub_state = g_variant_dup_string (_tmp19_, NULL); + g_variant_unref (_tmp19_); + _tmp20_ = g_variant_iter_next_value (&_tmp14_); + _tmp13_.following = g_variant_dup_string (_tmp20_, NULL); + g_variant_unref (_tmp20_); + _tmp21_ = g_variant_iter_next_value (&_tmp14_); + _tmp13_.unit_path = g_variant_dup_string (_tmp21_, NULL); + g_variant_unref (_tmp21_); + _tmp22_ = g_variant_iter_next_value (&_tmp14_); + _tmp13_.job_id = g_variant_get_uint32 (_tmp22_); + g_variant_unref (_tmp22_); + _tmp23_ = g_variant_iter_next_value (&_tmp14_); + _tmp13_.job_type = g_variant_dup_string (_tmp23_, NULL); + g_variant_unref (_tmp23_); + _tmp24_ = g_variant_iter_next_value (&_tmp14_); + _tmp13_.job_path = g_variant_dup_string (_tmp24_, NULL); + g_variant_unref (_tmp24_); + _tmp10_[_tmp10__length++] = _tmp13_; + g_variant_unref (_tmp12_); + } + _result_length1 = _tmp10__length1; + _result = _tmp10_; + g_variant_unref (_tmp9_); + *result_length1 = _result_length1; + g_object_unref (_reply_message); + return _result; +} + + +static ManagerJobInfo* manager_proxy_list_jobs (Manager* self, int* result_length1, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + ManagerJobInfo* _result; + int _result_length1; + GVariant* _tmp25_; + ManagerJobInfo* _tmp26_; + int _tmp26__length; + int _tmp26__size; + int _tmp26__length1; + GVariantIter _tmp27_; + GVariant* _tmp28_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "ListJobs"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _result_length1 = 0; + _tmp25_ = g_variant_iter_next_value (&_reply_iter); + _tmp26_ = g_new (ManagerJobInfo, 5); + _tmp26__length = 0; + _tmp26__size = 4; + _tmp26__length1 = 0; + g_variant_iter_init (&_tmp27_, _tmp25_); + for (; (_tmp28_ = g_variant_iter_next_value (&_tmp27_)) != NULL; _tmp26__length1++) { + ManagerJobInfo _tmp29_; + GVariantIter _tmp30_; + GVariant* _tmp31_; + GVariant* _tmp32_; + GVariant* _tmp33_; + GVariant* _tmp34_; + GVariant* _tmp35_; + GVariant* _tmp36_; + if (_tmp26__size == _tmp26__length) { + _tmp26__size = 2 * _tmp26__size; + _tmp26_ = g_renew (ManagerJobInfo, _tmp26_, _tmp26__size + 1); + } + g_variant_iter_init (&_tmp30_, _tmp28_); + _tmp31_ = g_variant_iter_next_value (&_tmp30_); + _tmp29_.id = g_variant_get_uint32 (_tmp31_); + g_variant_unref (_tmp31_); + _tmp32_ = g_variant_iter_next_value (&_tmp30_); + _tmp29_.name = g_variant_dup_string (_tmp32_, NULL); + g_variant_unref (_tmp32_); + _tmp33_ = g_variant_iter_next_value (&_tmp30_); + _tmp29_.type = g_variant_dup_string (_tmp33_, NULL); + g_variant_unref (_tmp33_); + _tmp34_ = g_variant_iter_next_value (&_tmp30_); + _tmp29_.state = g_variant_dup_string (_tmp34_, NULL); + g_variant_unref (_tmp34_); + _tmp35_ = g_variant_iter_next_value (&_tmp30_); + _tmp29_.job_path = g_variant_dup_string (_tmp35_, NULL); + g_variant_unref (_tmp35_); + _tmp36_ = g_variant_iter_next_value (&_tmp30_); + _tmp29_.unit_path = g_variant_dup_string (_tmp36_, NULL); + g_variant_unref (_tmp36_); + _tmp26_[_tmp26__length++] = _tmp29_; + g_variant_unref (_tmp28_); + } + _result_length1 = _tmp26__length1; + _result = _tmp26_; + g_variant_unref (_tmp25_); + *result_length1 = _result_length1; + g_object_unref (_reply_message); + return _result; +} + + +static char* manager_proxy_get_unit (Manager* self, const gchar* name, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp37_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "GetUnit"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (name)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp37_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp37_, NULL); + g_variant_unref (_tmp37_); + g_object_unref (_reply_message); + return _result; +} + + +static char* manager_proxy_get_unit_by_pid (Manager* self, guint32 pid, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp38_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "GetUnitByPid"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_uint32 (pid)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp38_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp38_, NULL); + g_variant_unref (_tmp38_); + g_object_unref (_reply_message); + return _result; +} + + +static char* manager_proxy_load_unit (Manager* self, const gchar* name, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp39_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "LoadUnit"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (name)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp39_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp39_, NULL); + g_variant_unref (_tmp39_); + g_object_unref (_reply_message); + return _result; +} + + +static char* manager_proxy_get_job (Manager* self, guint32 id, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp40_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "GetJob"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_uint32 (id)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp40_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp40_, NULL); + g_variant_unref (_tmp40_); + g_object_unref (_reply_message); + return _result; +} + + +static char* manager_proxy_start_unit (Manager* self, const gchar* name, const gchar* mode, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp41_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "StartUnit"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (name)); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (mode)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp41_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp41_, NULL); + g_variant_unref (_tmp41_); + g_object_unref (_reply_message); + return _result; +} + + +static char* manager_proxy_stop_unit (Manager* self, const gchar* name, const gchar* mode, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp42_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "StopUnit"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (name)); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (mode)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp42_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp42_, NULL); + g_variant_unref (_tmp42_); + g_object_unref (_reply_message); + return _result; +} + + +static char* manager_proxy_reload_unit (Manager* self, const gchar* name, const gchar* mode, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp43_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "ReloadUnit"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (name)); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (mode)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp43_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp43_, NULL); + g_variant_unref (_tmp43_); + g_object_unref (_reply_message); + return _result; +} + + +static char* manager_proxy_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp44_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "RestartUnit"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (name)); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (mode)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp44_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp44_, NULL); + g_variant_unref (_tmp44_); + g_object_unref (_reply_message); + return _result; +} + + +static char* manager_proxy_try_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp45_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "TryRestartUnit"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (name)); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (mode)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp45_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp45_, NULL); + g_variant_unref (_tmp45_); + g_object_unref (_reply_message); + return _result; +} + + +static char* manager_proxy_reload_or_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp46_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "ReloadOrRestartUnit"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (name)); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (mode)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp46_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp46_, NULL); + g_variant_unref (_tmp46_); + g_object_unref (_reply_message); + return _result; +} + + +static char* manager_proxy_reload_or_try_restart_unit (Manager* self, const gchar* name, const gchar* mode, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp47_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "ReloadOrTryRestartUnit"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (name)); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (mode)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp47_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp47_, NULL); + g_variant_unref (_tmp47_); + g_object_unref (_reply_message); + return _result; +} + + +static void manager_proxy_reset_failed_unit (Manager* self, const gchar* name, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "ResetFailedUnit"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (name)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static void manager_proxy_clear_jobs (Manager* self, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "ClearJobs"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static void manager_proxy_subscribe (Manager* self, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "Subscribe"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static void manager_proxy_unsubscribe (Manager* self, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "Unsubscribe"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static gchar* manager_proxy_dump (Manager* self, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + gchar* _result; + GVariant* _tmp48_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "Dump"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp48_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp48_, NULL); + g_variant_unref (_tmp48_); + g_object_unref (_reply_message); + return _result; +} + + +static void manager_proxy_reload (Manager* self, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "Reload"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static void manager_proxy_reexecute (Manager* self, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "Reexecute"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static void manager_proxy_exit (Manager* self, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "Exit"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static void manager_proxy_halt (Manager* self, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "Halt"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static void manager_proxy_power_off (Manager* self, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "PowerOff"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static void manager_proxy_reboot (Manager* self, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "Reboot"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static void manager_proxy_kexec (Manager* self, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "Kexec"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static char* manager_proxy_create_snapshot (Manager* self, const gchar* name, gboolean cleanup, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp49_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "CreateSnapshot"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (name)); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_boolean (cleanup)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp49_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp49_, NULL); + g_variant_unref (_tmp49_); + g_object_unref (_reply_message); + return _result; +} + + +static void manager_proxy_set_environment (Manager* self, gchar** names, int names_length1, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + gchar** _tmp50_; + GVariantBuilder _tmp51_; + int _tmp52_; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "SetEnvironment"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _tmp50_ = names; + g_variant_builder_init (&_tmp51_, G_VARIANT_TYPE ("as")); + for (_tmp52_ = 0; _tmp52_ < names_length1; _tmp52_++) { + g_variant_builder_add_value (&_tmp51_, g_variant_new_string (*_tmp50_)); + _tmp50_++; + } + g_variant_builder_add_value (&_arguments_builder, g_variant_builder_end (&_tmp51_)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static void manager_proxy_unset_environment (Manager* self, gchar** names, int names_length1, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + gchar** _tmp53_; + GVariantBuilder _tmp54_; + int _tmp55_; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Manager", "UnsetEnvironment"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _tmp53_ = names; + g_variant_builder_init (&_tmp54_, G_VARIANT_TYPE ("as")); + for (_tmp55_ = 0; _tmp55_ < names_length1; _tmp55_++) { + g_variant_builder_add_value (&_tmp54_, g_variant_new_string (*_tmp53_)); + _tmp53_++; + } + g_variant_builder_add_value (&_arguments_builder, g_variant_builder_end (&_tmp54_)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static gchar** manager_dbus_proxy_get_environment (Manager* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp56_; + int _tmp56__length; + int _tmp56__size; + int _tmp56__length1; + GVariantIter _tmp57_; + GVariant* _tmp58_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "Environment"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Manager")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("Environment")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp56_ = g_new (gchar*, 5); + _tmp56__length = 0; + _tmp56__size = 4; + _tmp56__length1 = 0; + g_variant_iter_init (&_tmp57_, _inner_reply); + for (; (_tmp58_ = g_variant_iter_next_value (&_tmp57_)) != NULL; _tmp56__length1++) { + if (_tmp56__size == _tmp56__length) { + _tmp56__size = 2 * _tmp56__size; + _tmp56_ = g_renew (gchar*, _tmp56_, _tmp56__size + 1); + } + _tmp56_[_tmp56__length++] = g_variant_dup_string (_tmp58_, NULL); + g_variant_unref (_tmp58_); + } + _result_length1 = _tmp56__length1; + _tmp56_[_tmp56__length] = NULL; + _result = _tmp56_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static void manager_proxy_manager_interface_init (ManagerIface* iface) { + iface->list_units = manager_proxy_list_units; + iface->list_jobs = manager_proxy_list_jobs; + iface->get_unit = manager_proxy_get_unit; + iface->get_unit_by_pid = manager_proxy_get_unit_by_pid; + iface->load_unit = manager_proxy_load_unit; + iface->get_job = manager_proxy_get_job; + iface->start_unit = manager_proxy_start_unit; + iface->stop_unit = manager_proxy_stop_unit; + iface->reload_unit = manager_proxy_reload_unit; + iface->restart_unit = manager_proxy_restart_unit; + iface->try_restart_unit = manager_proxy_try_restart_unit; + iface->reload_or_restart_unit = manager_proxy_reload_or_restart_unit; + iface->reload_or_try_restart_unit = manager_proxy_reload_or_try_restart_unit; + iface->reset_failed_unit = manager_proxy_reset_failed_unit; + iface->clear_jobs = manager_proxy_clear_jobs; + iface->subscribe = manager_proxy_subscribe; + iface->unsubscribe = manager_proxy_unsubscribe; + iface->dump = manager_proxy_dump; + iface->reload = manager_proxy_reload; + iface->reexecute = manager_proxy_reexecute; + iface->exit = manager_proxy_exit; + iface->halt = manager_proxy_halt; + iface->power_off = manager_proxy_power_off; + iface->reboot = manager_proxy_reboot; + iface->kexec = manager_proxy_kexec; + iface->create_snapshot = manager_proxy_create_snapshot; + iface->set_environment = manager_proxy_set_environment; + iface->unset_environment = manager_proxy_unset_environment; + iface->get_environment = manager_dbus_proxy_get_environment; +} + + +static void _vala_ManagerUnitInfo_array_free (ManagerUnitInfo* array, gint array_length) { + if (array != NULL) { + int i; + for (i = 0; i < array_length; i = i + 1) { + manager_unit_info_destroy (&array[i]); + } + } + g_free (array); +} + + +static void _dbus_manager_list_units (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + ManagerUnitInfo* result; + int result_length1 = 0; + ManagerUnitInfo* _tmp59_; + GVariantBuilder _tmp60_; + int _tmp61_; + g_variant_iter_init (&_arguments_iter, parameters); + result = manager_list_units (self, &result_length1, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _tmp59_ = result; + g_variant_builder_init (&_tmp60_, G_VARIANT_TYPE ("a(ssssssouso)")); + for (_tmp61_ = 0; _tmp61_ < result_length1; _tmp61_++) { + GVariantBuilder _tmp62_; + g_variant_builder_init (&_tmp62_, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_tmp62_, g_variant_new_string ((*_tmp59_).id)); + g_variant_builder_add_value (&_tmp62_, g_variant_new_string ((*_tmp59_).description)); + g_variant_builder_add_value (&_tmp62_, g_variant_new_string ((*_tmp59_).load_state)); + g_variant_builder_add_value (&_tmp62_, g_variant_new_string ((*_tmp59_).active_state)); + g_variant_builder_add_value (&_tmp62_, g_variant_new_string ((*_tmp59_).sub_state)); + g_variant_builder_add_value (&_tmp62_, g_variant_new_string ((*_tmp59_).following)); + g_variant_builder_add_value (&_tmp62_, g_variant_new_object_path ((*_tmp59_).unit_path)); + g_variant_builder_add_value (&_tmp62_, g_variant_new_uint32 ((*_tmp59_).job_id)); + g_variant_builder_add_value (&_tmp62_, g_variant_new_string ((*_tmp59_).job_type)); + g_variant_builder_add_value (&_tmp62_, g_variant_new_object_path ((*_tmp59_).job_path)); + g_variant_builder_add_value (&_tmp60_, g_variant_builder_end (&_tmp62_)); + _tmp59_++; + } + g_variant_builder_add_value (&_reply_builder, g_variant_builder_end (&_tmp60_)); + result = (_vala_ManagerUnitInfo_array_free (result, result_length1), NULL); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _vala_ManagerJobInfo_array_free (ManagerJobInfo* array, gint array_length) { + if (array != NULL) { + int i; + for (i = 0; i < array_length; i = i + 1) { + manager_job_info_destroy (&array[i]); + } + } + g_free (array); +} + + +static void _dbus_manager_list_jobs (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + ManagerJobInfo* result; + int result_length1 = 0; + ManagerJobInfo* _tmp63_; + GVariantBuilder _tmp64_; + int _tmp65_; + g_variant_iter_init (&_arguments_iter, parameters); + result = manager_list_jobs (self, &result_length1, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _tmp63_ = result; + g_variant_builder_init (&_tmp64_, G_VARIANT_TYPE ("a(usssoo)")); + for (_tmp65_ = 0; _tmp65_ < result_length1; _tmp65_++) { + GVariantBuilder _tmp66_; + g_variant_builder_init (&_tmp66_, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_tmp66_, g_variant_new_uint32 ((*_tmp63_).id)); + g_variant_builder_add_value (&_tmp66_, g_variant_new_string ((*_tmp63_).name)); + g_variant_builder_add_value (&_tmp66_, g_variant_new_string ((*_tmp63_).type)); + g_variant_builder_add_value (&_tmp66_, g_variant_new_string ((*_tmp63_).state)); + g_variant_builder_add_value (&_tmp66_, g_variant_new_object_path ((*_tmp63_).job_path)); + g_variant_builder_add_value (&_tmp66_, g_variant_new_object_path ((*_tmp63_).unit_path)); + g_variant_builder_add_value (&_tmp64_, g_variant_builder_end (&_tmp66_)); + _tmp63_++; + } + g_variant_builder_add_value (&_reply_builder, g_variant_builder_end (&_tmp64_)); + result = (_vala_ManagerJobInfo_array_free (result, result_length1), NULL); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_get_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* name = NULL; + GVariant* _tmp67_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp67_ = g_variant_iter_next_value (&_arguments_iter); + name = g_variant_dup_string (_tmp67_, NULL); + g_variant_unref (_tmp67_); + result = manager_get_unit (self, name, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (name); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_get_unit_by_pid (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + guint32 pid = 0U; + GVariant* _tmp68_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp68_ = g_variant_iter_next_value (&_arguments_iter); + pid = g_variant_get_uint32 (_tmp68_); + g_variant_unref (_tmp68_); + result = manager_get_unit_by_pid (self, pid, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_load_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* name = NULL; + GVariant* _tmp69_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp69_ = g_variant_iter_next_value (&_arguments_iter); + name = g_variant_dup_string (_tmp69_, NULL); + g_variant_unref (_tmp69_); + result = manager_load_unit (self, name, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (name); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_get_job (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + guint32 id = 0U; + GVariant* _tmp70_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp70_ = g_variant_iter_next_value (&_arguments_iter); + id = g_variant_get_uint32 (_tmp70_); + g_variant_unref (_tmp70_); + result = manager_get_job (self, id, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_start_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* name = NULL; + GVariant* _tmp71_; + gchar* mode = NULL; + GVariant* _tmp72_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp71_ = g_variant_iter_next_value (&_arguments_iter); + name = g_variant_dup_string (_tmp71_, NULL); + g_variant_unref (_tmp71_); + _tmp72_ = g_variant_iter_next_value (&_arguments_iter); + mode = g_variant_dup_string (_tmp72_, NULL); + g_variant_unref (_tmp72_); + result = manager_start_unit (self, name, mode, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (name); + _g_free0 (mode); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_stop_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* name = NULL; + GVariant* _tmp73_; + gchar* mode = NULL; + GVariant* _tmp74_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp73_ = g_variant_iter_next_value (&_arguments_iter); + name = g_variant_dup_string (_tmp73_, NULL); + g_variant_unref (_tmp73_); + _tmp74_ = g_variant_iter_next_value (&_arguments_iter); + mode = g_variant_dup_string (_tmp74_, NULL); + g_variant_unref (_tmp74_); + result = manager_stop_unit (self, name, mode, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (name); + _g_free0 (mode); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_reload_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* name = NULL; + GVariant* _tmp75_; + gchar* mode = NULL; + GVariant* _tmp76_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp75_ = g_variant_iter_next_value (&_arguments_iter); + name = g_variant_dup_string (_tmp75_, NULL); + g_variant_unref (_tmp75_); + _tmp76_ = g_variant_iter_next_value (&_arguments_iter); + mode = g_variant_dup_string (_tmp76_, NULL); + g_variant_unref (_tmp76_); + result = manager_reload_unit (self, name, mode, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (name); + _g_free0 (mode); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_restart_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* name = NULL; + GVariant* _tmp77_; + gchar* mode = NULL; + GVariant* _tmp78_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp77_ = g_variant_iter_next_value (&_arguments_iter); + name = g_variant_dup_string (_tmp77_, NULL); + g_variant_unref (_tmp77_); + _tmp78_ = g_variant_iter_next_value (&_arguments_iter); + mode = g_variant_dup_string (_tmp78_, NULL); + g_variant_unref (_tmp78_); + result = manager_restart_unit (self, name, mode, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (name); + _g_free0 (mode); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_try_restart_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* name = NULL; + GVariant* _tmp79_; + gchar* mode = NULL; + GVariant* _tmp80_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp79_ = g_variant_iter_next_value (&_arguments_iter); + name = g_variant_dup_string (_tmp79_, NULL); + g_variant_unref (_tmp79_); + _tmp80_ = g_variant_iter_next_value (&_arguments_iter); + mode = g_variant_dup_string (_tmp80_, NULL); + g_variant_unref (_tmp80_); + result = manager_try_restart_unit (self, name, mode, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (name); + _g_free0 (mode); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_reload_or_restart_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* name = NULL; + GVariant* _tmp81_; + gchar* mode = NULL; + GVariant* _tmp82_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp81_ = g_variant_iter_next_value (&_arguments_iter); + name = g_variant_dup_string (_tmp81_, NULL); + g_variant_unref (_tmp81_); + _tmp82_ = g_variant_iter_next_value (&_arguments_iter); + mode = g_variant_dup_string (_tmp82_, NULL); + g_variant_unref (_tmp82_); + result = manager_reload_or_restart_unit (self, name, mode, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (name); + _g_free0 (mode); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_reload_or_try_restart_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* name = NULL; + GVariant* _tmp83_; + gchar* mode = NULL; + GVariant* _tmp84_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp83_ = g_variant_iter_next_value (&_arguments_iter); + name = g_variant_dup_string (_tmp83_, NULL); + g_variant_unref (_tmp83_); + _tmp84_ = g_variant_iter_next_value (&_arguments_iter); + mode = g_variant_dup_string (_tmp84_, NULL); + g_variant_unref (_tmp84_); + result = manager_reload_or_try_restart_unit (self, name, mode, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (name); + _g_free0 (mode); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_reset_failed_unit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* name = NULL; + GVariant* _tmp85_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp85_ = g_variant_iter_next_value (&_arguments_iter); + name = g_variant_dup_string (_tmp85_, NULL); + g_variant_unref (_tmp85_); + manager_reset_failed_unit (self, name, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (name); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_clear_jobs (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + manager_clear_jobs (self, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_subscribe (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + manager_subscribe (self, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_unsubscribe (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + manager_unsubscribe (self, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_dump (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + gchar* result; + g_variant_iter_init (&_arguments_iter, parameters); + result = manager_dump (self, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_string (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_reload (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + manager_reload (self, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_reexecute (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + manager_reexecute (self, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_exit (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + manager_exit (self, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_halt (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + manager_halt (self, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_power_off (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + manager_power_off (self, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_reboot (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + manager_reboot (self, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_kexec (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + manager_kexec (self, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_create_snapshot (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* name = NULL; + GVariant* _tmp86_; + gboolean cleanup = FALSE; + GVariant* _tmp87_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp86_ = g_variant_iter_next_value (&_arguments_iter); + name = g_variant_dup_string (_tmp86_, NULL); + g_variant_unref (_tmp86_); + _tmp87_ = g_variant_iter_next_value (&_arguments_iter); + cleanup = g_variant_get_boolean (_tmp87_); + g_variant_unref (_tmp87_); + result = manager_create_snapshot (self, name, cleanup, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (name); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_set_environment (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar** names = NULL; + int names_length1 = 0; + GVariant* _tmp88_; + gchar** _tmp89_; + int _tmp89__length; + int _tmp89__size; + int _tmp89__length1; + GVariantIter _tmp90_; + GVariant* _tmp91_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp88_ = g_variant_iter_next_value (&_arguments_iter); + _tmp89_ = g_new (gchar*, 5); + _tmp89__length = 0; + _tmp89__size = 4; + _tmp89__length1 = 0; + g_variant_iter_init (&_tmp90_, _tmp88_); + for (; (_tmp91_ = g_variant_iter_next_value (&_tmp90_)) != NULL; _tmp89__length1++) { + if (_tmp89__size == _tmp89__length) { + _tmp89__size = 2 * _tmp89__size; + _tmp89_ = g_renew (gchar*, _tmp89_, _tmp89__size + 1); + } + _tmp89_[_tmp89__length++] = g_variant_dup_string (_tmp91_, NULL); + g_variant_unref (_tmp91_); + } + names_length1 = _tmp89__length1; + _tmp89_[_tmp89__length] = NULL; + names = _tmp89_; + g_variant_unref (_tmp88_); + manager_set_environment (self, names, names_length1, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + names = (_vala_array_free (names, names_length1, (GDestroyNotify) g_free), NULL); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_manager_unset_environment (Manager* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar** names = NULL; + int names_length1 = 0; + GVariant* _tmp92_; + gchar** _tmp93_; + int _tmp93__length; + int _tmp93__size; + int _tmp93__length1; + GVariantIter _tmp94_; + GVariant* _tmp95_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp92_ = g_variant_iter_next_value (&_arguments_iter); + _tmp93_ = g_new (gchar*, 5); + _tmp93__length = 0; + _tmp93__size = 4; + _tmp93__length1 = 0; + g_variant_iter_init (&_tmp94_, _tmp92_); + for (; (_tmp95_ = g_variant_iter_next_value (&_tmp94_)) != NULL; _tmp93__length1++) { + if (_tmp93__size == _tmp93__length) { + _tmp93__size = 2 * _tmp93__size; + _tmp93_ = g_renew (gchar*, _tmp93_, _tmp93__size + 1); + } + _tmp93_[_tmp93__length++] = g_variant_dup_string (_tmp95_, NULL); + g_variant_unref (_tmp95_); + } + names_length1 = _tmp93__length1; + _tmp93_[_tmp93__length] = NULL; + names = _tmp93_; + g_variant_unref (_tmp92_); + manager_unset_environment (self, names, names_length1, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + names = (_vala_array_free (names, names_length1, (GDestroyNotify) g_free), NULL); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void manager_dbus_interface_method_call (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data) { + gpointer* data; + gpointer object; + data = user_data; + object = data[0]; + if (strcmp (method_name, "ListUnits") == 0) { + _dbus_manager_list_units (object, parameters, invocation); + } else if (strcmp (method_name, "ListJobs") == 0) { + _dbus_manager_list_jobs (object, parameters, invocation); + } else if (strcmp (method_name, "GetUnit") == 0) { + _dbus_manager_get_unit (object, parameters, invocation); + } else if (strcmp (method_name, "GetUnitByPid") == 0) { + _dbus_manager_get_unit_by_pid (object, parameters, invocation); + } else if (strcmp (method_name, "LoadUnit") == 0) { + _dbus_manager_load_unit (object, parameters, invocation); + } else if (strcmp (method_name, "GetJob") == 0) { + _dbus_manager_get_job (object, parameters, invocation); + } else if (strcmp (method_name, "StartUnit") == 0) { + _dbus_manager_start_unit (object, parameters, invocation); + } else if (strcmp (method_name, "StopUnit") == 0) { + _dbus_manager_stop_unit (object, parameters, invocation); + } else if (strcmp (method_name, "ReloadUnit") == 0) { + _dbus_manager_reload_unit (object, parameters, invocation); + } else if (strcmp (method_name, "RestartUnit") == 0) { + _dbus_manager_restart_unit (object, parameters, invocation); + } else if (strcmp (method_name, "TryRestartUnit") == 0) { + _dbus_manager_try_restart_unit (object, parameters, invocation); + } else if (strcmp (method_name, "ReloadOrRestartUnit") == 0) { + _dbus_manager_reload_or_restart_unit (object, parameters, invocation); + } else if (strcmp (method_name, "ReloadOrTryRestartUnit") == 0) { + _dbus_manager_reload_or_try_restart_unit (object, parameters, invocation); + } else if (strcmp (method_name, "ResetFailedUnit") == 0) { + _dbus_manager_reset_failed_unit (object, parameters, invocation); + } else if (strcmp (method_name, "ClearJobs") == 0) { + _dbus_manager_clear_jobs (object, parameters, invocation); + } else if (strcmp (method_name, "Subscribe") == 0) { + _dbus_manager_subscribe (object, parameters, invocation); + } else if (strcmp (method_name, "Unsubscribe") == 0) { + _dbus_manager_unsubscribe (object, parameters, invocation); + } else if (strcmp (method_name, "Dump") == 0) { + _dbus_manager_dump (object, parameters, invocation); + } else if (strcmp (method_name, "Reload") == 0) { + _dbus_manager_reload (object, parameters, invocation); + } else if (strcmp (method_name, "Reexecute") == 0) { + _dbus_manager_reexecute (object, parameters, invocation); + } else if (strcmp (method_name, "Exit") == 0) { + _dbus_manager_exit (object, parameters, invocation); + } else if (strcmp (method_name, "Halt") == 0) { + _dbus_manager_halt (object, parameters, invocation); + } else if (strcmp (method_name, "PowerOff") == 0) { + _dbus_manager_power_off (object, parameters, invocation); + } else if (strcmp (method_name, "Reboot") == 0) { + _dbus_manager_reboot (object, parameters, invocation); + } else if (strcmp (method_name, "Kexec") == 0) { + _dbus_manager_kexec (object, parameters, invocation); + } else if (strcmp (method_name, "CreateSnapshot") == 0) { + _dbus_manager_create_snapshot (object, parameters, invocation); + } else if (strcmp (method_name, "SetEnvironment") == 0) { + _dbus_manager_set_environment (object, parameters, invocation); + } else if (strcmp (method_name, "UnsetEnvironment") == 0) { + _dbus_manager_unset_environment (object, parameters, invocation); + } else { + g_object_unref (invocation); + } +} + + +static GVariant* _dbus_manager_get_environment (Manager* self) { + gchar** result; + int result_length1; + gchar** _tmp96_; + GVariantBuilder _tmp97_; + int _tmp98_; + GVariant* _reply; + result = manager_get_environment (self, &result_length1); + _tmp96_ = result; + g_variant_builder_init (&_tmp97_, G_VARIANT_TYPE ("as")); + for (_tmp98_ = 0; _tmp98_ < result_length1; _tmp98_++) { + g_variant_builder_add_value (&_tmp97_, g_variant_new_string (*_tmp96_)); + _tmp96_++; + } + _reply = g_variant_builder_end (&_tmp97_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* manager_dbus_interface_get_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GError** error, gpointer user_data) { + gpointer* data; + gpointer object; + data = user_data; + object = data[0]; + if (strcmp (property_name, "Environment") == 0) { + return _dbus_manager_get_environment (object); + } + return NULL; +} + + +static gboolean manager_dbus_interface_set_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GVariant* value, GError** error, gpointer user_data) { + gpointer* data; + gpointer object; + data = user_data; + object = data[0]; + return FALSE; +} + + +static void _dbus_manager_unit_new (GObject* _sender, const gchar* id, const char* path, gpointer* _data) { + GDBusConnection * _connection; + const gchar * _path; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + _connection = _data[1]; + _path = _data[2]; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (id)); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_object_path (path)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_connection_emit_signal (_connection, NULL, _path, "org.freedesktop.systemd1.Manager", "UnitNew", _arguments, NULL); +} + + +static void _dbus_manager_unit_removed (GObject* _sender, const gchar* id, const char* path, gpointer* _data) { + GDBusConnection * _connection; + const gchar * _path; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + _connection = _data[1]; + _path = _data[2]; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (id)); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_object_path (path)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_connection_emit_signal (_connection, NULL, _path, "org.freedesktop.systemd1.Manager", "UnitRemoved", _arguments, NULL); +} + + +static void _dbus_manager_job_new (GObject* _sender, guint32 id, const char* path, gpointer* _data) { + GDBusConnection * _connection; + const gchar * _path; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + _connection = _data[1]; + _path = _data[2]; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_uint32 (id)); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_object_path (path)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_connection_emit_signal (_connection, NULL, _path, "org.freedesktop.systemd1.Manager", "JobNew", _arguments, NULL); +} + + +static void _dbus_manager_job_removed (GObject* _sender, guint32 id, const char* path, const gchar* res, gpointer* _data) { + GDBusConnection * _connection; + const gchar * _path; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + _connection = _data[1]; + _path = _data[2]; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_uint32 (id)); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_object_path (path)); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (res)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_connection_emit_signal (_connection, NULL, _path, "org.freedesktop.systemd1.Manager", "JobRemoved", _arguments, NULL); +} + + +guint manager_register_object (gpointer object, GDBusConnection* connection, const gchar* path, GError** error) { + guint result; + gpointer *data; + data = g_new (gpointer, 3); + data[0] = g_object_ref (object); + data[1] = g_object_ref (connection); + data[2] = g_strdup (path); + result = g_dbus_connection_register_object (connection, path, (GDBusInterfaceInfo *) (&_manager_dbus_interface_info), &_manager_dbus_interface_vtable, data, _manager_unregister_object, error); + if (!result) { + return 0; + } + g_signal_connect (object, "unit-new", (GCallback) _dbus_manager_unit_new, data); + g_signal_connect (object, "unit-removed", (GCallback) _dbus_manager_unit_removed, data); + g_signal_connect (object, "job-new", (GCallback) _dbus_manager_job_new, data); + g_signal_connect (object, "job-removed", (GCallback) _dbus_manager_job_removed, data); + return result; +} + + +static void _manager_unregister_object (gpointer user_data) { + gpointer* data; + data = user_data; + g_signal_handlers_disconnect_by_func (data[0], _dbus_manager_unit_new, data); + g_signal_handlers_disconnect_by_func (data[0], _dbus_manager_unit_removed, data); + g_signal_handlers_disconnect_by_func (data[0], _dbus_manager_job_new, data); + g_signal_handlers_disconnect_by_func (data[0], _dbus_manager_job_removed, data); + g_object_unref (data[0]); + g_object_unref (data[1]); + g_free (data[2]); + g_free (data); +} + + +char* unit_start (Unit* self, const gchar* mode, GError** error) { +#line 137 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 137 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->start (self, mode, error); +#line 3695 "systemd-interfaces.c" +} + + +char* unit_stop (Unit* self, const gchar* mode, GError** error) { +#line 138 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 138 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->stop (self, mode, error); +#line 3704 "systemd-interfaces.c" +} + + +char* unit_reload (Unit* self, const gchar* mode, GError** error) { +#line 139 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 139 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->reload (self, mode, error); +#line 3713 "systemd-interfaces.c" +} + + +char* unit_restart (Unit* self, const gchar* mode, GError** error) { +#line 140 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 140 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->restart (self, mode, error); +#line 3722 "systemd-interfaces.c" +} + + +char* unit_try_restart (Unit* self, const gchar* mode, GError** error) { +#line 141 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 141 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->try_restart (self, mode, error); +#line 3731 "systemd-interfaces.c" +} + + +char* unit_reload_or_restart (Unit* self, const gchar* mode, GError** error) { +#line 142 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 142 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->reload_or_restart (self, mode, error); +#line 3740 "systemd-interfaces.c" +} + + +char* unit_reload_or_try_restart (Unit* self, const gchar* mode, GError** error) { +#line 143 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 143 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->reload_or_try_restart (self, mode, error); +#line 3749 "systemd-interfaces.c" +} + + +void unit_reset_failed (Unit* self, GError** error) { +#line 145 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 145 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + UNIT_GET_INTERFACE (self)->reset_failed (self, error); +#line 3758 "systemd-interfaces.c" +} + + +gchar* unit_get_id (Unit* self) { +#line 98 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 98 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_id (self); +#line 3767 "systemd-interfaces.c" +} + + +gchar** unit_get_names (Unit* self, int* result_length1) { +#line 99 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 99 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_names (self, result_length1); +#line 3776 "systemd-interfaces.c" +} + + +gchar* unit_get_following (Unit* self) { +#line 100 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 100 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_following (self); +#line 3785 "systemd-interfaces.c" +} + + +gchar** unit_get_requires (Unit* self, int* result_length1) { +#line 101 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 101 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_requires (self, result_length1); +#line 3794 "systemd-interfaces.c" +} + + +gchar** unit_get_requires_overridable (Unit* self, int* result_length1) { +#line 102 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 102 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_requires_overridable (self, result_length1); +#line 3803 "systemd-interfaces.c" +} + + +gchar** unit_get_requisite (Unit* self, int* result_length1) { +#line 103 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 103 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_requisite (self, result_length1); +#line 3812 "systemd-interfaces.c" +} + + +gchar** unit_get_requisite_overridable (Unit* self, int* result_length1) { +#line 104 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 104 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_requisite_overridable (self, result_length1); +#line 3821 "systemd-interfaces.c" +} + + +gchar** unit_get_wants (Unit* self, int* result_length1) { +#line 105 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 105 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_wants (self, result_length1); +#line 3830 "systemd-interfaces.c" +} + + +gchar** unit_get_required_by (Unit* self, int* result_length1) { +#line 106 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 106 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_required_by (self, result_length1); +#line 3839 "systemd-interfaces.c" +} + + +gchar** unit_get_required_by_overridable (Unit* self, int* result_length1) { +#line 107 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 107 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_required_by_overridable (self, result_length1); +#line 3848 "systemd-interfaces.c" +} + + +gchar** unit_get_wanted_by (Unit* self, int* result_length1) { +#line 108 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 108 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_wanted_by (self, result_length1); +#line 3857 "systemd-interfaces.c" +} + + +gchar** unit_get_conflicts (Unit* self, int* result_length1) { +#line 109 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 109 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_conflicts (self, result_length1); +#line 3866 "systemd-interfaces.c" +} + + +gchar** unit_get_conflicted_by (Unit* self, int* result_length1) { +#line 110 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 110 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_conflicted_by (self, result_length1); +#line 3875 "systemd-interfaces.c" +} + + +gchar** unit_get_before (Unit* self, int* result_length1) { +#line 111 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 111 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_before (self, result_length1); +#line 3884 "systemd-interfaces.c" +} + + +gchar** unit_get_after (Unit* self, int* result_length1) { +#line 112 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 112 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_after (self, result_length1); +#line 3893 "systemd-interfaces.c" +} + + +gchar** unit_get_on_failure (Unit* self, int* result_length1) { +#line 113 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 113 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_on_failure (self, result_length1); +#line 3902 "systemd-interfaces.c" +} + + +gchar* unit_get_description (Unit* self) { +#line 114 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 114 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_description (self); +#line 3911 "systemd-interfaces.c" +} + + +gchar* unit_get_load_state (Unit* self) { +#line 115 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 115 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_load_state (self); +#line 3920 "systemd-interfaces.c" +} + + +gchar* unit_get_active_state (Unit* self) { +#line 116 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 116 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_active_state (self); +#line 3929 "systemd-interfaces.c" +} + + +gchar* unit_get_sub_state (Unit* self) { +#line 117 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 117 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_sub_state (self); +#line 3938 "systemd-interfaces.c" +} + + +gchar* unit_get_fragment_path (Unit* self) { +#line 118 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 118 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_fragment_path (self); +#line 3947 "systemd-interfaces.c" +} + + +guint64 unit_get_inactive_exit_timestamp (Unit* self) { +#line 119 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, 0ULL); +#line 119 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_inactive_exit_timestamp (self); +#line 3956 "systemd-interfaces.c" +} + + +guint64 unit_get_active_enter_timestamp (Unit* self) { +#line 120 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, 0ULL); +#line 120 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_active_enter_timestamp (self); +#line 3965 "systemd-interfaces.c" +} + + +guint64 unit_get_active_exit_timestamp (Unit* self) { +#line 121 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, 0ULL); +#line 121 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_active_exit_timestamp (self); +#line 3974 "systemd-interfaces.c" +} + + +guint64 unit_get_inactive_enter_timestamp (Unit* self) { +#line 122 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, 0ULL); +#line 122 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_inactive_enter_timestamp (self); +#line 3983 "systemd-interfaces.c" +} + + +gboolean unit_get_can_start (Unit* self) { +#line 123 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, FALSE); +#line 123 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_can_start (self); +#line 3992 "systemd-interfaces.c" +} + + +gboolean unit_get_can_stop (Unit* self) { +#line 124 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, FALSE); +#line 124 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_can_stop (self); +#line 4001 "systemd-interfaces.c" +} + + +gboolean unit_get_can_reload (Unit* self) { +#line 125 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, FALSE); +#line 125 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_can_reload (self); +#line 4010 "systemd-interfaces.c" +} + + +void unit_get_job (Unit* self, UnitJobLink* result) { +#line 126 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 126 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + UNIT_GET_INTERFACE (self)->get_job (self, result); +#line 4019 "systemd-interfaces.c" +} + + +gboolean unit_get_recursive_stop (Unit* self) { +#line 127 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, FALSE); +#line 127 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_recursive_stop (self); +#line 4028 "systemd-interfaces.c" +} + + +gboolean unit_get_stop_when_unneeded (Unit* self) { +#line 128 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, FALSE); +#line 128 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_stop_when_unneeded (self); +#line 4037 "systemd-interfaces.c" +} + + +gboolean unit_get_refuse_manual_start (Unit* self) { +#line 129 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, FALSE); +#line 129 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_refuse_manual_start (self); +#line 4046 "systemd-interfaces.c" +} + + +gboolean unit_get_refuse_manual_stop (Unit* self) { +#line 130 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, FALSE); +#line 130 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_refuse_manual_stop (self); +#line 4055 "systemd-interfaces.c" +} + + +gboolean unit_get_default_dependencies (Unit* self) { +#line 131 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, FALSE); +#line 131 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_default_dependencies (self); +#line 4064 "systemd-interfaces.c" +} + + +gchar* unit_get_default_control_group (Unit* self) { +#line 132 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 132 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_default_control_group (self); +#line 4073 "systemd-interfaces.c" +} + + +gchar** unit_get_control_groups (Unit* self, int* result_length1) { +#line 133 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 133 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_control_groups (self, result_length1); +#line 4082 "systemd-interfaces.c" +} + + +gboolean unit_get_need_daemon_reload (Unit* self) { +#line 134 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, FALSE); +#line 134 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_need_daemon_reload (self); +#line 4091 "systemd-interfaces.c" +} + + +guint64 unit_get_job_timeout_usec (Unit* self) { +#line 135 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, 0ULL); +#line 135 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return UNIT_GET_INTERFACE (self)->get_job_timeout_usec (self); +#line 4100 "systemd-interfaces.c" +} + + +void unit_job_link_copy (const UnitJobLink* self, UnitJobLink* dest) { + guint32 _tmp0_; + const char* _tmp1_; + char* _tmp2_; +#line 93 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp0_ = (*self).id; +#line 93 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).id = _tmp0_; +#line 93 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp1_ = (*self).path; +#line 93 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp2_ = g_strdup (_tmp1_); +#line 93 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).path); +#line 93 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).path = _tmp2_; +#line 4120 "systemd-interfaces.c" +} + + +void unit_job_link_destroy (UnitJobLink* self) { +#line 95 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).path); +#line 4127 "systemd-interfaces.c" +} + + +UnitJobLink* unit_job_link_dup (const UnitJobLink* self) { + UnitJobLink* dup; +#line 93 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + dup = g_new0 (UnitJobLink, 1); +#line 93 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + unit_job_link_copy (self, dup); +#line 93 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return dup; +#line 4139 "systemd-interfaces.c" +} + + +void unit_job_link_free (UnitJobLink* self) { +#line 93 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + unit_job_link_destroy (self); +#line 93 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_free (self); +#line 4148 "systemd-interfaces.c" +} + + +GType unit_job_link_get_type (void) { + static volatile gsize unit_job_link_type_id__volatile = 0; + if (g_once_init_enter (&unit_job_link_type_id__volatile)) { + GType unit_job_link_type_id; + unit_job_link_type_id = g_boxed_type_register_static ("UnitJobLink", (GBoxedCopyFunc) unit_job_link_dup, (GBoxedFreeFunc) unit_job_link_free); + g_once_init_leave (&unit_job_link_type_id__volatile, unit_job_link_type_id); + } + return unit_job_link_type_id__volatile; +} + + +static void unit_base_init (UnitIface * iface) { +#line 92 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + static gboolean initialized = FALSE; +#line 92 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + if (!initialized) { +#line 92 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + initialized = TRUE; +#line 4170 "systemd-interfaces.c" + } +} + + +GType unit_get_type (void) { + static volatile gsize unit_type_id__volatile = 0; + if (g_once_init_enter (&unit_type_id__volatile)) { + static const GTypeInfo g_define_type_info = { sizeof (UnitIface), (GBaseInitFunc) unit_base_init, (GBaseFinalizeFunc) NULL, (GClassInitFunc) NULL, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL }; + GType unit_type_id; + unit_type_id = g_type_register_static (G_TYPE_INTERFACE, "Unit", &g_define_type_info, 0); + g_type_interface_add_prerequisite (unit_type_id, G_TYPE_DBUS_PROXY); + g_type_set_qdata (unit_type_id, g_quark_from_static_string ("vala-dbus-proxy-type"), (void*) unit_proxy_get_type); + g_type_set_qdata (unit_type_id, g_quark_from_static_string ("vala-dbus-interface-name"), "org.freedesktop.systemd1.Unit"); + g_type_set_qdata (unit_type_id, g_quark_from_static_string ("vala-dbus-register-object"), (void*) unit_register_object); + g_once_init_leave (&unit_type_id__volatile, unit_type_id); + } + return unit_type_id__volatile; +} + + +G_DEFINE_TYPE_EXTENDED (UnitProxy, unit_proxy, G_TYPE_DBUS_PROXY, 0, G_IMPLEMENT_INTERFACE (TYPE_UNIT, unit_proxy_unit_interface_init) ) +static void unit_proxy_class_init (UnitProxyClass* klass) { + G_DBUS_PROXY_CLASS (klass)->g_signal = unit_proxy_g_signal; +} + + +static void unit_proxy_g_signal (GDBusProxy* proxy, const gchar* sender_name, const gchar* signal_name, GVariant* parameters) { +} + + +static void unit_proxy_init (UnitProxy* self) { +} + + +static char* unit_proxy_start (Unit* self, const gchar* mode, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp99_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Unit", "Start"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (mode)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp99_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp99_, NULL); + g_variant_unref (_tmp99_); + g_object_unref (_reply_message); + return _result; +} + + +static char* unit_proxy_stop (Unit* self, const gchar* mode, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp100_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Unit", "Stop"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (mode)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp100_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp100_, NULL); + g_variant_unref (_tmp100_); + g_object_unref (_reply_message); + return _result; +} + + +static char* unit_proxy_reload (Unit* self, const gchar* mode, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp101_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Unit", "Reload"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (mode)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp101_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp101_, NULL); + g_variant_unref (_tmp101_); + g_object_unref (_reply_message); + return _result; +} + + +static char* unit_proxy_restart (Unit* self, const gchar* mode, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp102_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Unit", "Restart"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (mode)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp102_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp102_, NULL); + g_variant_unref (_tmp102_); + g_object_unref (_reply_message); + return _result; +} + + +static char* unit_proxy_try_restart (Unit* self, const gchar* mode, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp103_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Unit", "TryRestart"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (mode)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp103_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp103_, NULL); + g_variant_unref (_tmp103_); + g_object_unref (_reply_message); + return _result; +} + + +static char* unit_proxy_reload_or_restart (Unit* self, const gchar* mode, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp104_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Unit", "ReloadOrRestart"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (mode)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp104_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp104_, NULL); + g_variant_unref (_tmp104_); + g_object_unref (_reply_message); + return _result; +} + + +static char* unit_proxy_reload_or_try_restart (Unit* self, const gchar* mode, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + char* _result; + GVariant* _tmp105_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Unit", "ReloadOrTryRestart"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (mode)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp105_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_dup_string (_tmp105_, NULL); + g_variant_unref (_tmp105_); + g_object_unref (_reply_message); + return _result; +} + + +static void unit_proxy_reset_failed (Unit* self, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Unit", "ResetFailed"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static gchar* unit_dbus_proxy_get_id (Unit* self) { + GVariant *_inner_reply; + gchar* _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "Id"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("Id")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_dup_string (_inner_reply, NULL); + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_names (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp106_; + int _tmp106__length; + int _tmp106__size; + int _tmp106__length1; + GVariantIter _tmp107_; + GVariant* _tmp108_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "Names"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("Names")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp106_ = g_new (gchar*, 5); + _tmp106__length = 0; + _tmp106__size = 4; + _tmp106__length1 = 0; + g_variant_iter_init (&_tmp107_, _inner_reply); + for (; (_tmp108_ = g_variant_iter_next_value (&_tmp107_)) != NULL; _tmp106__length1++) { + if (_tmp106__size == _tmp106__length) { + _tmp106__size = 2 * _tmp106__size; + _tmp106_ = g_renew (gchar*, _tmp106_, _tmp106__size + 1); + } + _tmp106_[_tmp106__length++] = g_variant_dup_string (_tmp108_, NULL); + g_variant_unref (_tmp108_); + } + _result_length1 = _tmp106__length1; + _tmp106_[_tmp106__length] = NULL; + _result = _tmp106_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar* unit_dbus_proxy_get_following (Unit* self) { + GVariant *_inner_reply; + gchar* _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "Following"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("Following")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_dup_string (_inner_reply, NULL); + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_requires (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp109_; + int _tmp109__length; + int _tmp109__size; + int _tmp109__length1; + GVariantIter _tmp110_; + GVariant* _tmp111_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "Requires"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("Requires")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp109_ = g_new (gchar*, 5); + _tmp109__length = 0; + _tmp109__size = 4; + _tmp109__length1 = 0; + g_variant_iter_init (&_tmp110_, _inner_reply); + for (; (_tmp111_ = g_variant_iter_next_value (&_tmp110_)) != NULL; _tmp109__length1++) { + if (_tmp109__size == _tmp109__length) { + _tmp109__size = 2 * _tmp109__size; + _tmp109_ = g_renew (gchar*, _tmp109_, _tmp109__size + 1); + } + _tmp109_[_tmp109__length++] = g_variant_dup_string (_tmp111_, NULL); + g_variant_unref (_tmp111_); + } + _result_length1 = _tmp109__length1; + _tmp109_[_tmp109__length] = NULL; + _result = _tmp109_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_requires_overridable (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp112_; + int _tmp112__length; + int _tmp112__size; + int _tmp112__length1; + GVariantIter _tmp113_; + GVariant* _tmp114_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "RequiresOverridable"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("RequiresOverridable")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp112_ = g_new (gchar*, 5); + _tmp112__length = 0; + _tmp112__size = 4; + _tmp112__length1 = 0; + g_variant_iter_init (&_tmp113_, _inner_reply); + for (; (_tmp114_ = g_variant_iter_next_value (&_tmp113_)) != NULL; _tmp112__length1++) { + if (_tmp112__size == _tmp112__length) { + _tmp112__size = 2 * _tmp112__size; + _tmp112_ = g_renew (gchar*, _tmp112_, _tmp112__size + 1); + } + _tmp112_[_tmp112__length++] = g_variant_dup_string (_tmp114_, NULL); + g_variant_unref (_tmp114_); + } + _result_length1 = _tmp112__length1; + _tmp112_[_tmp112__length] = NULL; + _result = _tmp112_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_requisite (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp115_; + int _tmp115__length; + int _tmp115__size; + int _tmp115__length1; + GVariantIter _tmp116_; + GVariant* _tmp117_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "Requisite"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("Requisite")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp115_ = g_new (gchar*, 5); + _tmp115__length = 0; + _tmp115__size = 4; + _tmp115__length1 = 0; + g_variant_iter_init (&_tmp116_, _inner_reply); + for (; (_tmp117_ = g_variant_iter_next_value (&_tmp116_)) != NULL; _tmp115__length1++) { + if (_tmp115__size == _tmp115__length) { + _tmp115__size = 2 * _tmp115__size; + _tmp115_ = g_renew (gchar*, _tmp115_, _tmp115__size + 1); + } + _tmp115_[_tmp115__length++] = g_variant_dup_string (_tmp117_, NULL); + g_variant_unref (_tmp117_); + } + _result_length1 = _tmp115__length1; + _tmp115_[_tmp115__length] = NULL; + _result = _tmp115_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_requisite_overridable (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp118_; + int _tmp118__length; + int _tmp118__size; + int _tmp118__length1; + GVariantIter _tmp119_; + GVariant* _tmp120_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "RequisiteOverridable"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("RequisiteOverridable")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp118_ = g_new (gchar*, 5); + _tmp118__length = 0; + _tmp118__size = 4; + _tmp118__length1 = 0; + g_variant_iter_init (&_tmp119_, _inner_reply); + for (; (_tmp120_ = g_variant_iter_next_value (&_tmp119_)) != NULL; _tmp118__length1++) { + if (_tmp118__size == _tmp118__length) { + _tmp118__size = 2 * _tmp118__size; + _tmp118_ = g_renew (gchar*, _tmp118_, _tmp118__size + 1); + } + _tmp118_[_tmp118__length++] = g_variant_dup_string (_tmp120_, NULL); + g_variant_unref (_tmp120_); + } + _result_length1 = _tmp118__length1; + _tmp118_[_tmp118__length] = NULL; + _result = _tmp118_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_wants (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp121_; + int _tmp121__length; + int _tmp121__size; + int _tmp121__length1; + GVariantIter _tmp122_; + GVariant* _tmp123_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "Wants"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("Wants")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp121_ = g_new (gchar*, 5); + _tmp121__length = 0; + _tmp121__size = 4; + _tmp121__length1 = 0; + g_variant_iter_init (&_tmp122_, _inner_reply); + for (; (_tmp123_ = g_variant_iter_next_value (&_tmp122_)) != NULL; _tmp121__length1++) { + if (_tmp121__size == _tmp121__length) { + _tmp121__size = 2 * _tmp121__size; + _tmp121_ = g_renew (gchar*, _tmp121_, _tmp121__size + 1); + } + _tmp121_[_tmp121__length++] = g_variant_dup_string (_tmp123_, NULL); + g_variant_unref (_tmp123_); + } + _result_length1 = _tmp121__length1; + _tmp121_[_tmp121__length] = NULL; + _result = _tmp121_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_required_by (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp124_; + int _tmp124__length; + int _tmp124__size; + int _tmp124__length1; + GVariantIter _tmp125_; + GVariant* _tmp126_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "RequiredBy"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("RequiredBy")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp124_ = g_new (gchar*, 5); + _tmp124__length = 0; + _tmp124__size = 4; + _tmp124__length1 = 0; + g_variant_iter_init (&_tmp125_, _inner_reply); + for (; (_tmp126_ = g_variant_iter_next_value (&_tmp125_)) != NULL; _tmp124__length1++) { + if (_tmp124__size == _tmp124__length) { + _tmp124__size = 2 * _tmp124__size; + _tmp124_ = g_renew (gchar*, _tmp124_, _tmp124__size + 1); + } + _tmp124_[_tmp124__length++] = g_variant_dup_string (_tmp126_, NULL); + g_variant_unref (_tmp126_); + } + _result_length1 = _tmp124__length1; + _tmp124_[_tmp124__length] = NULL; + _result = _tmp124_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_required_by_overridable (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp127_; + int _tmp127__length; + int _tmp127__size; + int _tmp127__length1; + GVariantIter _tmp128_; + GVariant* _tmp129_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "RequiredByOverridable"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("RequiredByOverridable")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp127_ = g_new (gchar*, 5); + _tmp127__length = 0; + _tmp127__size = 4; + _tmp127__length1 = 0; + g_variant_iter_init (&_tmp128_, _inner_reply); + for (; (_tmp129_ = g_variant_iter_next_value (&_tmp128_)) != NULL; _tmp127__length1++) { + if (_tmp127__size == _tmp127__length) { + _tmp127__size = 2 * _tmp127__size; + _tmp127_ = g_renew (gchar*, _tmp127_, _tmp127__size + 1); + } + _tmp127_[_tmp127__length++] = g_variant_dup_string (_tmp129_, NULL); + g_variant_unref (_tmp129_); + } + _result_length1 = _tmp127__length1; + _tmp127_[_tmp127__length] = NULL; + _result = _tmp127_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_wanted_by (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp130_; + int _tmp130__length; + int _tmp130__size; + int _tmp130__length1; + GVariantIter _tmp131_; + GVariant* _tmp132_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "WantedBy"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("WantedBy")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp130_ = g_new (gchar*, 5); + _tmp130__length = 0; + _tmp130__size = 4; + _tmp130__length1 = 0; + g_variant_iter_init (&_tmp131_, _inner_reply); + for (; (_tmp132_ = g_variant_iter_next_value (&_tmp131_)) != NULL; _tmp130__length1++) { + if (_tmp130__size == _tmp130__length) { + _tmp130__size = 2 * _tmp130__size; + _tmp130_ = g_renew (gchar*, _tmp130_, _tmp130__size + 1); + } + _tmp130_[_tmp130__length++] = g_variant_dup_string (_tmp132_, NULL); + g_variant_unref (_tmp132_); + } + _result_length1 = _tmp130__length1; + _tmp130_[_tmp130__length] = NULL; + _result = _tmp130_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_conflicts (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp133_; + int _tmp133__length; + int _tmp133__size; + int _tmp133__length1; + GVariantIter _tmp134_; + GVariant* _tmp135_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "Conflicts"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("Conflicts")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp133_ = g_new (gchar*, 5); + _tmp133__length = 0; + _tmp133__size = 4; + _tmp133__length1 = 0; + g_variant_iter_init (&_tmp134_, _inner_reply); + for (; (_tmp135_ = g_variant_iter_next_value (&_tmp134_)) != NULL; _tmp133__length1++) { + if (_tmp133__size == _tmp133__length) { + _tmp133__size = 2 * _tmp133__size; + _tmp133_ = g_renew (gchar*, _tmp133_, _tmp133__size + 1); + } + _tmp133_[_tmp133__length++] = g_variant_dup_string (_tmp135_, NULL); + g_variant_unref (_tmp135_); + } + _result_length1 = _tmp133__length1; + _tmp133_[_tmp133__length] = NULL; + _result = _tmp133_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_conflicted_by (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp136_; + int _tmp136__length; + int _tmp136__size; + int _tmp136__length1; + GVariantIter _tmp137_; + GVariant* _tmp138_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "ConflictedBy"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("ConflictedBy")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp136_ = g_new (gchar*, 5); + _tmp136__length = 0; + _tmp136__size = 4; + _tmp136__length1 = 0; + g_variant_iter_init (&_tmp137_, _inner_reply); + for (; (_tmp138_ = g_variant_iter_next_value (&_tmp137_)) != NULL; _tmp136__length1++) { + if (_tmp136__size == _tmp136__length) { + _tmp136__size = 2 * _tmp136__size; + _tmp136_ = g_renew (gchar*, _tmp136_, _tmp136__size + 1); + } + _tmp136_[_tmp136__length++] = g_variant_dup_string (_tmp138_, NULL); + g_variant_unref (_tmp138_); + } + _result_length1 = _tmp136__length1; + _tmp136_[_tmp136__length] = NULL; + _result = _tmp136_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_before (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp139_; + int _tmp139__length; + int _tmp139__size; + int _tmp139__length1; + GVariantIter _tmp140_; + GVariant* _tmp141_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "Before"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("Before")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp139_ = g_new (gchar*, 5); + _tmp139__length = 0; + _tmp139__size = 4; + _tmp139__length1 = 0; + g_variant_iter_init (&_tmp140_, _inner_reply); + for (; (_tmp141_ = g_variant_iter_next_value (&_tmp140_)) != NULL; _tmp139__length1++) { + if (_tmp139__size == _tmp139__length) { + _tmp139__size = 2 * _tmp139__size; + _tmp139_ = g_renew (gchar*, _tmp139_, _tmp139__size + 1); + } + _tmp139_[_tmp139__length++] = g_variant_dup_string (_tmp141_, NULL); + g_variant_unref (_tmp141_); + } + _result_length1 = _tmp139__length1; + _tmp139_[_tmp139__length] = NULL; + _result = _tmp139_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_after (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp142_; + int _tmp142__length; + int _tmp142__size; + int _tmp142__length1; + GVariantIter _tmp143_; + GVariant* _tmp144_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "After"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("After")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp142_ = g_new (gchar*, 5); + _tmp142__length = 0; + _tmp142__size = 4; + _tmp142__length1 = 0; + g_variant_iter_init (&_tmp143_, _inner_reply); + for (; (_tmp144_ = g_variant_iter_next_value (&_tmp143_)) != NULL; _tmp142__length1++) { + if (_tmp142__size == _tmp142__length) { + _tmp142__size = 2 * _tmp142__size; + _tmp142_ = g_renew (gchar*, _tmp142_, _tmp142__size + 1); + } + _tmp142_[_tmp142__length++] = g_variant_dup_string (_tmp144_, NULL); + g_variant_unref (_tmp144_); + } + _result_length1 = _tmp142__length1; + _tmp142_[_tmp142__length] = NULL; + _result = _tmp142_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_on_failure (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp145_; + int _tmp145__length; + int _tmp145__size; + int _tmp145__length1; + GVariantIter _tmp146_; + GVariant* _tmp147_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "OnFailure"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("OnFailure")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp145_ = g_new (gchar*, 5); + _tmp145__length = 0; + _tmp145__size = 4; + _tmp145__length1 = 0; + g_variant_iter_init (&_tmp146_, _inner_reply); + for (; (_tmp147_ = g_variant_iter_next_value (&_tmp146_)) != NULL; _tmp145__length1++) { + if (_tmp145__size == _tmp145__length) { + _tmp145__size = 2 * _tmp145__size; + _tmp145_ = g_renew (gchar*, _tmp145_, _tmp145__size + 1); + } + _tmp145_[_tmp145__length++] = g_variant_dup_string (_tmp147_, NULL); + g_variant_unref (_tmp147_); + } + _result_length1 = _tmp145__length1; + _tmp145_[_tmp145__length] = NULL; + _result = _tmp145_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar* unit_dbus_proxy_get_description (Unit* self) { + GVariant *_inner_reply; + gchar* _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "Description"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("Description")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_dup_string (_inner_reply, NULL); + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar* unit_dbus_proxy_get_load_state (Unit* self) { + GVariant *_inner_reply; + gchar* _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "LoadState"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("LoadState")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_dup_string (_inner_reply, NULL); + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar* unit_dbus_proxy_get_active_state (Unit* self) { + GVariant *_inner_reply; + gchar* _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "ActiveState"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("ActiveState")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_dup_string (_inner_reply, NULL); + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar* unit_dbus_proxy_get_sub_state (Unit* self) { + GVariant *_inner_reply; + gchar* _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "SubState"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("SubState")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_dup_string (_inner_reply, NULL); + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar* unit_dbus_proxy_get_fragment_path (Unit* self) { + GVariant *_inner_reply; + gchar* _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "FragmentPath"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("FragmentPath")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_dup_string (_inner_reply, NULL); + g_variant_unref (_inner_reply); + return _result; +} + + +static guint64 unit_dbus_proxy_get_inactive_exit_timestamp (Unit* self) { + GVariant *_inner_reply; + guint64 _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "InactiveExitTimestamp"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("InactiveExitTimestamp")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return 0ULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_uint64 (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static guint64 unit_dbus_proxy_get_active_enter_timestamp (Unit* self) { + GVariant *_inner_reply; + guint64 _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "ActiveEnterTimestamp"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("ActiveEnterTimestamp")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return 0ULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_uint64 (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static guint64 unit_dbus_proxy_get_active_exit_timestamp (Unit* self) { + GVariant *_inner_reply; + guint64 _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "ActiveExitTimestamp"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("ActiveExitTimestamp")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return 0ULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_uint64 (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static guint64 unit_dbus_proxy_get_inactive_enter_timestamp (Unit* self) { + GVariant *_inner_reply; + guint64 _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "InactiveEnterTimestamp"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("InactiveEnterTimestamp")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return 0ULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_uint64 (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static gboolean unit_dbus_proxy_get_can_start (Unit* self) { + GVariant *_inner_reply; + gboolean _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "CanStart"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("CanStart")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return FALSE; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_boolean (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static gboolean unit_dbus_proxy_get_can_stop (Unit* self) { + GVariant *_inner_reply; + gboolean _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "CanStop"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("CanStop")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return FALSE; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_boolean (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static gboolean unit_dbus_proxy_get_can_reload (Unit* self) { + GVariant *_inner_reply; + gboolean _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "CanReload"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("CanReload")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return FALSE; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_boolean (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static void unit_dbus_proxy_get_job (Unit* self, UnitJobLink* result) { + GVariant *_inner_reply; + UnitJobLink _tmp148_; + GVariantIter _tmp149_; + GVariant* _tmp150_; + GVariant* _tmp151_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "Job"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("Job")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + g_variant_iter_init (&_tmp149_, _inner_reply); + _tmp150_ = g_variant_iter_next_value (&_tmp149_); + _tmp148_.id = g_variant_get_uint32 (_tmp150_); + g_variant_unref (_tmp150_); + _tmp151_ = g_variant_iter_next_value (&_tmp149_); + _tmp148_.path = g_variant_dup_string (_tmp151_, NULL); + g_variant_unref (_tmp151_); + *result = _tmp148_; + g_variant_unref (_inner_reply); + return; +} + + +static gboolean unit_dbus_proxy_get_recursive_stop (Unit* self) { + GVariant *_inner_reply; + gboolean _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "RecursiveStop"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("RecursiveStop")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return FALSE; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_boolean (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static gboolean unit_dbus_proxy_get_stop_when_unneeded (Unit* self) { + GVariant *_inner_reply; + gboolean _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "StopWhenUnneeded"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("StopWhenUnneeded")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return FALSE; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_boolean (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static gboolean unit_dbus_proxy_get_refuse_manual_start (Unit* self) { + GVariant *_inner_reply; + gboolean _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "RefuseManualStart"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("RefuseManualStart")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return FALSE; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_boolean (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static gboolean unit_dbus_proxy_get_refuse_manual_stop (Unit* self) { + GVariant *_inner_reply; + gboolean _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "RefuseManualStop"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("RefuseManualStop")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return FALSE; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_boolean (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static gboolean unit_dbus_proxy_get_default_dependencies (Unit* self) { + GVariant *_inner_reply; + gboolean _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "DefaultDependencies"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("DefaultDependencies")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return FALSE; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_boolean (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar* unit_dbus_proxy_get_default_control_group (Unit* self) { + GVariant *_inner_reply; + gchar* _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "DefaultControlGroup"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("DefaultControlGroup")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_dup_string (_inner_reply, NULL); + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar** unit_dbus_proxy_get_control_groups (Unit* self, int* result_length1) { + GVariant *_inner_reply; + gchar** _result; + int _result_length1; + gchar** _tmp152_; + int _tmp152__length; + int _tmp152__size; + int _tmp152__length1; + GVariantIter _tmp153_; + GVariant* _tmp154_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "ControlGroups"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("ControlGroups")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result_length1 = 0; + _tmp152_ = g_new (gchar*, 5); + _tmp152__length = 0; + _tmp152__size = 4; + _tmp152__length1 = 0; + g_variant_iter_init (&_tmp153_, _inner_reply); + for (; (_tmp154_ = g_variant_iter_next_value (&_tmp153_)) != NULL; _tmp152__length1++) { + if (_tmp152__size == _tmp152__length) { + _tmp152__size = 2 * _tmp152__size; + _tmp152_ = g_renew (gchar*, _tmp152_, _tmp152__size + 1); + } + _tmp152_[_tmp152__length++] = g_variant_dup_string (_tmp154_, NULL); + g_variant_unref (_tmp154_); + } + _result_length1 = _tmp152__length1; + _tmp152_[_tmp152__length] = NULL; + _result = _tmp152_; + *result_length1 = _result_length1; + g_variant_unref (_inner_reply); + return _result; +} + + +static gboolean unit_dbus_proxy_get_need_daemon_reload (Unit* self) { + GVariant *_inner_reply; + gboolean _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "NeedDaemonReload"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("NeedDaemonReload")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return FALSE; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_boolean (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static guint64 unit_dbus_proxy_get_job_timeout_usec (Unit* self) { + GVariant *_inner_reply; + guint64 _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "JobTimeoutUsec"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Unit")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("JobTimeoutUsec")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return 0ULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_uint64 (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static void unit_proxy_unit_interface_init (UnitIface* iface) { + iface->start = unit_proxy_start; + iface->stop = unit_proxy_stop; + iface->reload = unit_proxy_reload; + iface->restart = unit_proxy_restart; + iface->try_restart = unit_proxy_try_restart; + iface->reload_or_restart = unit_proxy_reload_or_restart; + iface->reload_or_try_restart = unit_proxy_reload_or_try_restart; + iface->reset_failed = unit_proxy_reset_failed; + iface->get_id = unit_dbus_proxy_get_id; + iface->get_names = unit_dbus_proxy_get_names; + iface->get_following = unit_dbus_proxy_get_following; + iface->get_requires = unit_dbus_proxy_get_requires; + iface->get_requires_overridable = unit_dbus_proxy_get_requires_overridable; + iface->get_requisite = unit_dbus_proxy_get_requisite; + iface->get_requisite_overridable = unit_dbus_proxy_get_requisite_overridable; + iface->get_wants = unit_dbus_proxy_get_wants; + iface->get_required_by = unit_dbus_proxy_get_required_by; + iface->get_required_by_overridable = unit_dbus_proxy_get_required_by_overridable; + iface->get_wanted_by = unit_dbus_proxy_get_wanted_by; + iface->get_conflicts = unit_dbus_proxy_get_conflicts; + iface->get_conflicted_by = unit_dbus_proxy_get_conflicted_by; + iface->get_before = unit_dbus_proxy_get_before; + iface->get_after = unit_dbus_proxy_get_after; + iface->get_on_failure = unit_dbus_proxy_get_on_failure; + iface->get_description = unit_dbus_proxy_get_description; + iface->get_load_state = unit_dbus_proxy_get_load_state; + iface->get_active_state = unit_dbus_proxy_get_active_state; + iface->get_sub_state = unit_dbus_proxy_get_sub_state; + iface->get_fragment_path = unit_dbus_proxy_get_fragment_path; + iface->get_inactive_exit_timestamp = unit_dbus_proxy_get_inactive_exit_timestamp; + iface->get_active_enter_timestamp = unit_dbus_proxy_get_active_enter_timestamp; + iface->get_active_exit_timestamp = unit_dbus_proxy_get_active_exit_timestamp; + iface->get_inactive_enter_timestamp = unit_dbus_proxy_get_inactive_enter_timestamp; + iface->get_can_start = unit_dbus_proxy_get_can_start; + iface->get_can_stop = unit_dbus_proxy_get_can_stop; + iface->get_can_reload = unit_dbus_proxy_get_can_reload; + iface->get_job = unit_dbus_proxy_get_job; + iface->get_recursive_stop = unit_dbus_proxy_get_recursive_stop; + iface->get_stop_when_unneeded = unit_dbus_proxy_get_stop_when_unneeded; + iface->get_refuse_manual_start = unit_dbus_proxy_get_refuse_manual_start; + iface->get_refuse_manual_stop = unit_dbus_proxy_get_refuse_manual_stop; + iface->get_default_dependencies = unit_dbus_proxy_get_default_dependencies; + iface->get_default_control_group = unit_dbus_proxy_get_default_control_group; + iface->get_control_groups = unit_dbus_proxy_get_control_groups; + iface->get_need_daemon_reload = unit_dbus_proxy_get_need_daemon_reload; + iface->get_job_timeout_usec = unit_dbus_proxy_get_job_timeout_usec; +} + + +static void _dbus_unit_start (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* mode = NULL; + GVariant* _tmp155_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp155_ = g_variant_iter_next_value (&_arguments_iter); + mode = g_variant_dup_string (_tmp155_, NULL); + g_variant_unref (_tmp155_); + result = unit_start (self, mode, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (mode); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_unit_stop (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* mode = NULL; + GVariant* _tmp156_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp156_ = g_variant_iter_next_value (&_arguments_iter); + mode = g_variant_dup_string (_tmp156_, NULL); + g_variant_unref (_tmp156_); + result = unit_stop (self, mode, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (mode); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_unit_reload (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* mode = NULL; + GVariant* _tmp157_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp157_ = g_variant_iter_next_value (&_arguments_iter); + mode = g_variant_dup_string (_tmp157_, NULL); + g_variant_unref (_tmp157_); + result = unit_reload (self, mode, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (mode); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_unit_restart (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* mode = NULL; + GVariant* _tmp158_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp158_ = g_variant_iter_next_value (&_arguments_iter); + mode = g_variant_dup_string (_tmp158_, NULL); + g_variant_unref (_tmp158_); + result = unit_restart (self, mode, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (mode); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_unit_try_restart (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* mode = NULL; + GVariant* _tmp159_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp159_ = g_variant_iter_next_value (&_arguments_iter); + mode = g_variant_dup_string (_tmp159_, NULL); + g_variant_unref (_tmp159_); + result = unit_try_restart (self, mode, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (mode); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_unit_reload_or_restart (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* mode = NULL; + GVariant* _tmp160_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp160_ = g_variant_iter_next_value (&_arguments_iter); + mode = g_variant_dup_string (_tmp160_, NULL); + g_variant_unref (_tmp160_); + result = unit_reload_or_restart (self, mode, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (mode); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_unit_reload_or_try_restart (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* mode = NULL; + GVariant* _tmp161_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + char* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp161_ = g_variant_iter_next_value (&_arguments_iter); + mode = g_variant_dup_string (_tmp161_, NULL); + g_variant_unref (_tmp161_); + result = unit_reload_or_try_restart (self, mode, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_object_path (result)); + _g_free0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (mode); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void _dbus_unit_reset_failed (Unit* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + unit_reset_failed (self, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void unit_dbus_interface_method_call (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data) { + gpointer* data; + gpointer object; + data = user_data; + object = data[0]; + if (strcmp (method_name, "Start") == 0) { + _dbus_unit_start (object, parameters, invocation); + } else if (strcmp (method_name, "Stop") == 0) { + _dbus_unit_stop (object, parameters, invocation); + } else if (strcmp (method_name, "Reload") == 0) { + _dbus_unit_reload (object, parameters, invocation); + } else if (strcmp (method_name, "Restart") == 0) { + _dbus_unit_restart (object, parameters, invocation); + } else if (strcmp (method_name, "TryRestart") == 0) { + _dbus_unit_try_restart (object, parameters, invocation); + } else if (strcmp (method_name, "ReloadOrRestart") == 0) { + _dbus_unit_reload_or_restart (object, parameters, invocation); + } else if (strcmp (method_name, "ReloadOrTryRestart") == 0) { + _dbus_unit_reload_or_try_restart (object, parameters, invocation); + } else if (strcmp (method_name, "ResetFailed") == 0) { + _dbus_unit_reset_failed (object, parameters, invocation); + } else { + g_object_unref (invocation); + } +} + + +static GVariant* _dbus_unit_get_id (Unit* self) { + gchar* result; + GVariant* _reply; + result = unit_get_id (self); + _reply = g_variant_new_string (result); + _g_free0 (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_names (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp162_; + GVariantBuilder _tmp163_; + int _tmp164_; + GVariant* _reply; + result = unit_get_names (self, &result_length1); + _tmp162_ = result; + g_variant_builder_init (&_tmp163_, G_VARIANT_TYPE ("as")); + for (_tmp164_ = 0; _tmp164_ < result_length1; _tmp164_++) { + g_variant_builder_add_value (&_tmp163_, g_variant_new_string (*_tmp162_)); + _tmp162_++; + } + _reply = g_variant_builder_end (&_tmp163_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_following (Unit* self) { + gchar* result; + GVariant* _reply; + result = unit_get_following (self); + _reply = g_variant_new_string (result); + _g_free0 (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_requires (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp165_; + GVariantBuilder _tmp166_; + int _tmp167_; + GVariant* _reply; + result = unit_get_requires (self, &result_length1); + _tmp165_ = result; + g_variant_builder_init (&_tmp166_, G_VARIANT_TYPE ("as")); + for (_tmp167_ = 0; _tmp167_ < result_length1; _tmp167_++) { + g_variant_builder_add_value (&_tmp166_, g_variant_new_string (*_tmp165_)); + _tmp165_++; + } + _reply = g_variant_builder_end (&_tmp166_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_requires_overridable (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp168_; + GVariantBuilder _tmp169_; + int _tmp170_; + GVariant* _reply; + result = unit_get_requires_overridable (self, &result_length1); + _tmp168_ = result; + g_variant_builder_init (&_tmp169_, G_VARIANT_TYPE ("as")); + for (_tmp170_ = 0; _tmp170_ < result_length1; _tmp170_++) { + g_variant_builder_add_value (&_tmp169_, g_variant_new_string (*_tmp168_)); + _tmp168_++; + } + _reply = g_variant_builder_end (&_tmp169_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_requisite (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp171_; + GVariantBuilder _tmp172_; + int _tmp173_; + GVariant* _reply; + result = unit_get_requisite (self, &result_length1); + _tmp171_ = result; + g_variant_builder_init (&_tmp172_, G_VARIANT_TYPE ("as")); + for (_tmp173_ = 0; _tmp173_ < result_length1; _tmp173_++) { + g_variant_builder_add_value (&_tmp172_, g_variant_new_string (*_tmp171_)); + _tmp171_++; + } + _reply = g_variant_builder_end (&_tmp172_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_requisite_overridable (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp174_; + GVariantBuilder _tmp175_; + int _tmp176_; + GVariant* _reply; + result = unit_get_requisite_overridable (self, &result_length1); + _tmp174_ = result; + g_variant_builder_init (&_tmp175_, G_VARIANT_TYPE ("as")); + for (_tmp176_ = 0; _tmp176_ < result_length1; _tmp176_++) { + g_variant_builder_add_value (&_tmp175_, g_variant_new_string (*_tmp174_)); + _tmp174_++; + } + _reply = g_variant_builder_end (&_tmp175_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_wants (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp177_; + GVariantBuilder _tmp178_; + int _tmp179_; + GVariant* _reply; + result = unit_get_wants (self, &result_length1); + _tmp177_ = result; + g_variant_builder_init (&_tmp178_, G_VARIANT_TYPE ("as")); + for (_tmp179_ = 0; _tmp179_ < result_length1; _tmp179_++) { + g_variant_builder_add_value (&_tmp178_, g_variant_new_string (*_tmp177_)); + _tmp177_++; + } + _reply = g_variant_builder_end (&_tmp178_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_required_by (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp180_; + GVariantBuilder _tmp181_; + int _tmp182_; + GVariant* _reply; + result = unit_get_required_by (self, &result_length1); + _tmp180_ = result; + g_variant_builder_init (&_tmp181_, G_VARIANT_TYPE ("as")); + for (_tmp182_ = 0; _tmp182_ < result_length1; _tmp182_++) { + g_variant_builder_add_value (&_tmp181_, g_variant_new_string (*_tmp180_)); + _tmp180_++; + } + _reply = g_variant_builder_end (&_tmp181_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_required_by_overridable (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp183_; + GVariantBuilder _tmp184_; + int _tmp185_; + GVariant* _reply; + result = unit_get_required_by_overridable (self, &result_length1); + _tmp183_ = result; + g_variant_builder_init (&_tmp184_, G_VARIANT_TYPE ("as")); + for (_tmp185_ = 0; _tmp185_ < result_length1; _tmp185_++) { + g_variant_builder_add_value (&_tmp184_, g_variant_new_string (*_tmp183_)); + _tmp183_++; + } + _reply = g_variant_builder_end (&_tmp184_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_wanted_by (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp186_; + GVariantBuilder _tmp187_; + int _tmp188_; + GVariant* _reply; + result = unit_get_wanted_by (self, &result_length1); + _tmp186_ = result; + g_variant_builder_init (&_tmp187_, G_VARIANT_TYPE ("as")); + for (_tmp188_ = 0; _tmp188_ < result_length1; _tmp188_++) { + g_variant_builder_add_value (&_tmp187_, g_variant_new_string (*_tmp186_)); + _tmp186_++; + } + _reply = g_variant_builder_end (&_tmp187_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_conflicts (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp189_; + GVariantBuilder _tmp190_; + int _tmp191_; + GVariant* _reply; + result = unit_get_conflicts (self, &result_length1); + _tmp189_ = result; + g_variant_builder_init (&_tmp190_, G_VARIANT_TYPE ("as")); + for (_tmp191_ = 0; _tmp191_ < result_length1; _tmp191_++) { + g_variant_builder_add_value (&_tmp190_, g_variant_new_string (*_tmp189_)); + _tmp189_++; + } + _reply = g_variant_builder_end (&_tmp190_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_conflicted_by (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp192_; + GVariantBuilder _tmp193_; + int _tmp194_; + GVariant* _reply; + result = unit_get_conflicted_by (self, &result_length1); + _tmp192_ = result; + g_variant_builder_init (&_tmp193_, G_VARIANT_TYPE ("as")); + for (_tmp194_ = 0; _tmp194_ < result_length1; _tmp194_++) { + g_variant_builder_add_value (&_tmp193_, g_variant_new_string (*_tmp192_)); + _tmp192_++; + } + _reply = g_variant_builder_end (&_tmp193_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_before (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp195_; + GVariantBuilder _tmp196_; + int _tmp197_; + GVariant* _reply; + result = unit_get_before (self, &result_length1); + _tmp195_ = result; + g_variant_builder_init (&_tmp196_, G_VARIANT_TYPE ("as")); + for (_tmp197_ = 0; _tmp197_ < result_length1; _tmp197_++) { + g_variant_builder_add_value (&_tmp196_, g_variant_new_string (*_tmp195_)); + _tmp195_++; + } + _reply = g_variant_builder_end (&_tmp196_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_after (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp198_; + GVariantBuilder _tmp199_; + int _tmp200_; + GVariant* _reply; + result = unit_get_after (self, &result_length1); + _tmp198_ = result; + g_variant_builder_init (&_tmp199_, G_VARIANT_TYPE ("as")); + for (_tmp200_ = 0; _tmp200_ < result_length1; _tmp200_++) { + g_variant_builder_add_value (&_tmp199_, g_variant_new_string (*_tmp198_)); + _tmp198_++; + } + _reply = g_variant_builder_end (&_tmp199_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_on_failure (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp201_; + GVariantBuilder _tmp202_; + int _tmp203_; + GVariant* _reply; + result = unit_get_on_failure (self, &result_length1); + _tmp201_ = result; + g_variant_builder_init (&_tmp202_, G_VARIANT_TYPE ("as")); + for (_tmp203_ = 0; _tmp203_ < result_length1; _tmp203_++) { + g_variant_builder_add_value (&_tmp202_, g_variant_new_string (*_tmp201_)); + _tmp201_++; + } + _reply = g_variant_builder_end (&_tmp202_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_description (Unit* self) { + gchar* result; + GVariant* _reply; + result = unit_get_description (self); + _reply = g_variant_new_string (result); + _g_free0 (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_load_state (Unit* self) { + gchar* result; + GVariant* _reply; + result = unit_get_load_state (self); + _reply = g_variant_new_string (result); + _g_free0 (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_active_state (Unit* self) { + gchar* result; + GVariant* _reply; + result = unit_get_active_state (self); + _reply = g_variant_new_string (result); + _g_free0 (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_sub_state (Unit* self) { + gchar* result; + GVariant* _reply; + result = unit_get_sub_state (self); + _reply = g_variant_new_string (result); + _g_free0 (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_fragment_path (Unit* self) { + gchar* result; + GVariant* _reply; + result = unit_get_fragment_path (self); + _reply = g_variant_new_string (result); + _g_free0 (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_inactive_exit_timestamp (Unit* self) { + guint64 result; + GVariant* _reply; + result = unit_get_inactive_exit_timestamp (self); + _reply = g_variant_new_uint64 (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_active_enter_timestamp (Unit* self) { + guint64 result; + GVariant* _reply; + result = unit_get_active_enter_timestamp (self); + _reply = g_variant_new_uint64 (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_active_exit_timestamp (Unit* self) { + guint64 result; + GVariant* _reply; + result = unit_get_active_exit_timestamp (self); + _reply = g_variant_new_uint64 (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_inactive_enter_timestamp (Unit* self) { + guint64 result; + GVariant* _reply; + result = unit_get_inactive_enter_timestamp (self); + _reply = g_variant_new_uint64 (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_can_start (Unit* self) { + gboolean result; + GVariant* _reply; + result = unit_get_can_start (self); + _reply = g_variant_new_boolean (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_can_stop (Unit* self) { + gboolean result; + GVariant* _reply; + result = unit_get_can_stop (self); + _reply = g_variant_new_boolean (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_can_reload (Unit* self) { + gboolean result; + GVariant* _reply; + result = unit_get_can_reload (self); + _reply = g_variant_new_boolean (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_job (Unit* self) { + UnitJobLink result = {0}; + GVariantBuilder _tmp204_; + GVariant* _reply; + unit_get_job (self, &result); + g_variant_builder_init (&_tmp204_, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_tmp204_, g_variant_new_uint32 (result.id)); + g_variant_builder_add_value (&_tmp204_, g_variant_new_object_path (result.path)); + _reply = g_variant_builder_end (&_tmp204_); + unit_job_link_destroy (&result); + return _reply; +} + + +static GVariant* _dbus_unit_get_recursive_stop (Unit* self) { + gboolean result; + GVariant* _reply; + result = unit_get_recursive_stop (self); + _reply = g_variant_new_boolean (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_stop_when_unneeded (Unit* self) { + gboolean result; + GVariant* _reply; + result = unit_get_stop_when_unneeded (self); + _reply = g_variant_new_boolean (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_refuse_manual_start (Unit* self) { + gboolean result; + GVariant* _reply; + result = unit_get_refuse_manual_start (self); + _reply = g_variant_new_boolean (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_refuse_manual_stop (Unit* self) { + gboolean result; + GVariant* _reply; + result = unit_get_refuse_manual_stop (self); + _reply = g_variant_new_boolean (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_default_dependencies (Unit* self) { + gboolean result; + GVariant* _reply; + result = unit_get_default_dependencies (self); + _reply = g_variant_new_boolean (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_default_control_group (Unit* self) { + gchar* result; + GVariant* _reply; + result = unit_get_default_control_group (self); + _reply = g_variant_new_string (result); + _g_free0 (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_control_groups (Unit* self) { + gchar** result; + int result_length1; + gchar** _tmp205_; + GVariantBuilder _tmp206_; + int _tmp207_; + GVariant* _reply; + result = unit_get_control_groups (self, &result_length1); + _tmp205_ = result; + g_variant_builder_init (&_tmp206_, G_VARIANT_TYPE ("as")); + for (_tmp207_ = 0; _tmp207_ < result_length1; _tmp207_++) { + g_variant_builder_add_value (&_tmp206_, g_variant_new_string (*_tmp205_)); + _tmp205_++; + } + _reply = g_variant_builder_end (&_tmp206_); + result = (_vala_array_free (result, result_length1, (GDestroyNotify) g_free), NULL); + return _reply; +} + + +static GVariant* _dbus_unit_get_need_daemon_reload (Unit* self) { + gboolean result; + GVariant* _reply; + result = unit_get_need_daemon_reload (self); + _reply = g_variant_new_boolean (result); + return _reply; +} + + +static GVariant* _dbus_unit_get_job_timeout_usec (Unit* self) { + guint64 result; + GVariant* _reply; + result = unit_get_job_timeout_usec (self); + _reply = g_variant_new_uint64 (result); + return _reply; +} + + +static GVariant* unit_dbus_interface_get_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GError** error, gpointer user_data) { + gpointer* data; + gpointer object; + data = user_data; + object = data[0]; + if (strcmp (property_name, "Id") == 0) { + return _dbus_unit_get_id (object); + } else if (strcmp (property_name, "Names") == 0) { + return _dbus_unit_get_names (object); + } else if (strcmp (property_name, "Following") == 0) { + return _dbus_unit_get_following (object); + } else if (strcmp (property_name, "Requires") == 0) { + return _dbus_unit_get_requires (object); + } else if (strcmp (property_name, "RequiresOverridable") == 0) { + return _dbus_unit_get_requires_overridable (object); + } else if (strcmp (property_name, "Requisite") == 0) { + return _dbus_unit_get_requisite (object); + } else if (strcmp (property_name, "RequisiteOverridable") == 0) { + return _dbus_unit_get_requisite_overridable (object); + } else if (strcmp (property_name, "Wants") == 0) { + return _dbus_unit_get_wants (object); + } else if (strcmp (property_name, "RequiredBy") == 0) { + return _dbus_unit_get_required_by (object); + } else if (strcmp (property_name, "RequiredByOverridable") == 0) { + return _dbus_unit_get_required_by_overridable (object); + } else if (strcmp (property_name, "WantedBy") == 0) { + return _dbus_unit_get_wanted_by (object); + } else if (strcmp (property_name, "Conflicts") == 0) { + return _dbus_unit_get_conflicts (object); + } else if (strcmp (property_name, "ConflictedBy") == 0) { + return _dbus_unit_get_conflicted_by (object); + } else if (strcmp (property_name, "Before") == 0) { + return _dbus_unit_get_before (object); + } else if (strcmp (property_name, "After") == 0) { + return _dbus_unit_get_after (object); + } else if (strcmp (property_name, "OnFailure") == 0) { + return _dbus_unit_get_on_failure (object); + } else if (strcmp (property_name, "Description") == 0) { + return _dbus_unit_get_description (object); + } else if (strcmp (property_name, "LoadState") == 0) { + return _dbus_unit_get_load_state (object); + } else if (strcmp (property_name, "ActiveState") == 0) { + return _dbus_unit_get_active_state (object); + } else if (strcmp (property_name, "SubState") == 0) { + return _dbus_unit_get_sub_state (object); + } else if (strcmp (property_name, "FragmentPath") == 0) { + return _dbus_unit_get_fragment_path (object); + } else if (strcmp (property_name, "InactiveExitTimestamp") == 0) { + return _dbus_unit_get_inactive_exit_timestamp (object); + } else if (strcmp (property_name, "ActiveEnterTimestamp") == 0) { + return _dbus_unit_get_active_enter_timestamp (object); + } else if (strcmp (property_name, "ActiveExitTimestamp") == 0) { + return _dbus_unit_get_active_exit_timestamp (object); + } else if (strcmp (property_name, "InactiveEnterTimestamp") == 0) { + return _dbus_unit_get_inactive_enter_timestamp (object); + } else if (strcmp (property_name, "CanStart") == 0) { + return _dbus_unit_get_can_start (object); + } else if (strcmp (property_name, "CanStop") == 0) { + return _dbus_unit_get_can_stop (object); + } else if (strcmp (property_name, "CanReload") == 0) { + return _dbus_unit_get_can_reload (object); + } else if (strcmp (property_name, "Job") == 0) { + return _dbus_unit_get_job (object); + } else if (strcmp (property_name, "RecursiveStop") == 0) { + return _dbus_unit_get_recursive_stop (object); + } else if (strcmp (property_name, "StopWhenUnneeded") == 0) { + return _dbus_unit_get_stop_when_unneeded (object); + } else if (strcmp (property_name, "RefuseManualStart") == 0) { + return _dbus_unit_get_refuse_manual_start (object); + } else if (strcmp (property_name, "RefuseManualStop") == 0) { + return _dbus_unit_get_refuse_manual_stop (object); + } else if (strcmp (property_name, "DefaultDependencies") == 0) { + return _dbus_unit_get_default_dependencies (object); + } else if (strcmp (property_name, "DefaultControlGroup") == 0) { + return _dbus_unit_get_default_control_group (object); + } else if (strcmp (property_name, "ControlGroups") == 0) { + return _dbus_unit_get_control_groups (object); + } else if (strcmp (property_name, "NeedDaemonReload") == 0) { + return _dbus_unit_get_need_daemon_reload (object); + } else if (strcmp (property_name, "JobTimeoutUsec") == 0) { + return _dbus_unit_get_job_timeout_usec (object); + } + return NULL; +} + + +static gboolean unit_dbus_interface_set_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GVariant* value, GError** error, gpointer user_data) { + gpointer* data; + gpointer object; + data = user_data; + object = data[0]; + return FALSE; +} + + +guint unit_register_object (gpointer object, GDBusConnection* connection, const gchar* path, GError** error) { + guint result; + gpointer *data; + data = g_new (gpointer, 3); + data[0] = g_object_ref (object); + data[1] = g_object_ref (connection); + data[2] = g_strdup (path); + result = g_dbus_connection_register_object (connection, path, (GDBusInterfaceInfo *) (&_unit_dbus_interface_info), &_unit_dbus_interface_vtable, data, _unit_unregister_object, error); + if (!result) { + return 0; + } + return result; +} + + +static void _unit_unregister_object (gpointer user_data) { + gpointer* data; + data = user_data; + g_object_unref (data[0]); + g_object_unref (data[1]); + g_free (data[2]); + g_free (data); +} + + +void job_cancel (Job* self, GError** error) { +#line 160 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 160 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + JOB_GET_INTERFACE (self)->cancel (self, error); +#line 6747 "systemd-interfaces.c" +} + + +guint32 job_get_id (Job* self) { +#line 155 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, 0U); +#line 155 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return JOB_GET_INTERFACE (self)->get_id (self); +#line 6756 "systemd-interfaces.c" +} + + +gchar* job_get_state (Job* self) { +#line 156 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 156 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return JOB_GET_INTERFACE (self)->get_state (self); +#line 6765 "systemd-interfaces.c" +} + + +gchar* job_get_job_type (Job* self) { +#line 157 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 157 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return JOB_GET_INTERFACE (self)->get_job_type (self); +#line 6774 "systemd-interfaces.c" +} + + +void job_get_unit (Job* self, JobUnitLink* result) { +#line 158 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (self != NULL); +#line 158 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + JOB_GET_INTERFACE (self)->get_unit (self, result); +#line 6783 "systemd-interfaces.c" +} + + +void job_unit_link_copy (const JobUnitLink* self, JobUnitLink* dest) { + const gchar* _tmp0_; + gchar* _tmp1_; + const char* _tmp2_; + char* _tmp3_; +#line 150 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp0_ = (*self).id; +#line 150 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp1_ = g_strdup (_tmp0_); +#line 150 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).id); +#line 150 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).id = _tmp1_; +#line 150 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp2_ = (*self).path; +#line 150 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _tmp3_ = g_strdup (_tmp2_); +#line 150 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*dest).path); +#line 150 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + (*dest).path = _tmp3_; +#line 6808 "systemd-interfaces.c" +} + + +void job_unit_link_destroy (JobUnitLink* self) { +#line 151 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).id); +#line 152 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + _g_free0 ((*self).path); +#line 6817 "systemd-interfaces.c" +} + + +JobUnitLink* job_unit_link_dup (const JobUnitLink* self) { + JobUnitLink* dup; +#line 150 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + dup = g_new0 (JobUnitLink, 1); +#line 150 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + job_unit_link_copy (self, dup); +#line 150 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return dup; +#line 6829 "systemd-interfaces.c" +} + + +void job_unit_link_free (JobUnitLink* self) { +#line 150 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + job_unit_link_destroy (self); +#line 150 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_free (self); +#line 6838 "systemd-interfaces.c" +} + + +GType job_unit_link_get_type (void) { + static volatile gsize job_unit_link_type_id__volatile = 0; + if (g_once_init_enter (&job_unit_link_type_id__volatile)) { + GType job_unit_link_type_id; + job_unit_link_type_id = g_boxed_type_register_static ("JobUnitLink", (GBoxedCopyFunc) job_unit_link_dup, (GBoxedFreeFunc) job_unit_link_free); + g_once_init_leave (&job_unit_link_type_id__volatile, job_unit_link_type_id); + } + return job_unit_link_type_id__volatile; +} + + +static void job_base_init (JobIface * iface) { +#line 149 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + static gboolean initialized = FALSE; +#line 149 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + if (!initialized) { +#line 149 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + initialized = TRUE; +#line 6860 "systemd-interfaces.c" + } +} + + +GType job_get_type (void) { + static volatile gsize job_type_id__volatile = 0; + if (g_once_init_enter (&job_type_id__volatile)) { + static const GTypeInfo g_define_type_info = { sizeof (JobIface), (GBaseInitFunc) job_base_init, (GBaseFinalizeFunc) NULL, (GClassInitFunc) NULL, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL }; + GType job_type_id; + job_type_id = g_type_register_static (G_TYPE_INTERFACE, "Job", &g_define_type_info, 0); + g_type_interface_add_prerequisite (job_type_id, G_TYPE_DBUS_PROXY); + g_type_set_qdata (job_type_id, g_quark_from_static_string ("vala-dbus-proxy-type"), (void*) job_proxy_get_type); + g_type_set_qdata (job_type_id, g_quark_from_static_string ("vala-dbus-interface-name"), "org.freedesktop.systemd1.Job"); + g_type_set_qdata (job_type_id, g_quark_from_static_string ("vala-dbus-register-object"), (void*) job_register_object); + g_once_init_leave (&job_type_id__volatile, job_type_id); + } + return job_type_id__volatile; +} + + +G_DEFINE_TYPE_EXTENDED (JobProxy, job_proxy, G_TYPE_DBUS_PROXY, 0, G_IMPLEMENT_INTERFACE (TYPE_JOB, job_proxy_job_interface_init) ) +static void job_proxy_class_init (JobProxyClass* klass) { + G_DBUS_PROXY_CLASS (klass)->g_signal = job_proxy_g_signal; +} + + +static void job_proxy_g_signal (GDBusProxy* proxy, const gchar* sender_name, const gchar* signal_name, GVariant* parameters) { +} + + +static void job_proxy_init (JobProxy* self) { +} + + +static void job_proxy_cancel (Job* self, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.systemd1.Job", "Cancel"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return; + } + g_object_unref (_reply_message); +} + + +static guint32 job_dbus_proxy_get_id (Job* self) { + GVariant *_inner_reply; + guint32 _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "Id"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Job")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("Id")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return 0U; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_get_uint32 (_inner_reply); + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar* job_dbus_proxy_get_state (Job* self) { + GVariant *_inner_reply; + gchar* _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "State"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Job")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("State")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_dup_string (_inner_reply, NULL); + g_variant_unref (_inner_reply); + return _result; +} + + +static gchar* job_dbus_proxy_get_job_type (Job* self) { + GVariant *_inner_reply; + gchar* _result; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "JobType"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Job")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("JobType")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return NULL; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + _result = g_variant_dup_string (_inner_reply, NULL); + g_variant_unref (_inner_reply); + return _result; +} + + +static void job_dbus_proxy_get_unit (Job* self, JobUnitLink* result) { + GVariant *_inner_reply; + JobUnitLink _tmp208_; + GVariantIter _tmp209_; + GVariant* _tmp210_; + GVariant* _tmp211_; + _inner_reply = g_dbus_proxy_get_cached_property ((GDBusProxy *) self, "Unit"); + if (!_inner_reply) { + GVariant *_arguments; + GVariant *_reply; + GVariantBuilder _arguments_builder; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("org.freedesktop.systemd1.Job")); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string ("Unit")); + _arguments = g_variant_builder_end (&_arguments_builder); + _reply = g_dbus_proxy_call_sync ((GDBusProxy *) self, "org.freedesktop.DBus.Properties.Get", _arguments, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL); + if (!_reply) { + return; + } + g_variant_get (_reply, "(v)", &_inner_reply); + g_variant_unref (_reply); + } + g_variant_iter_init (&_tmp209_, _inner_reply); + _tmp210_ = g_variant_iter_next_value (&_tmp209_); + _tmp208_.id = g_variant_dup_string (_tmp210_, NULL); + g_variant_unref (_tmp210_); + _tmp211_ = g_variant_iter_next_value (&_tmp209_); + _tmp208_.path = g_variant_dup_string (_tmp211_, NULL); + g_variant_unref (_tmp211_); + *result = _tmp208_; + g_variant_unref (_inner_reply); + return; +} + + +static void job_proxy_job_interface_init (JobIface* iface) { + iface->cancel = job_proxy_cancel; + iface->get_id = job_dbus_proxy_get_id; + iface->get_state = job_dbus_proxy_get_state; + iface->get_job_type = job_dbus_proxy_get_job_type; + iface->get_unit = job_dbus_proxy_get_unit; +} + + +static void _dbus_job_cancel (Job* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + g_variant_iter_init (&_arguments_iter, parameters); + job_cancel (self, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void job_dbus_interface_method_call (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data) { + gpointer* data; + gpointer object; + data = user_data; + object = data[0]; + if (strcmp (method_name, "Cancel") == 0) { + _dbus_job_cancel (object, parameters, invocation); + } else { + g_object_unref (invocation); + } +} + + +static GVariant* _dbus_job_get_id (Job* self) { + guint32 result; + GVariant* _reply; + result = job_get_id (self); + _reply = g_variant_new_uint32 (result); + return _reply; +} + + +static GVariant* _dbus_job_get_state (Job* self) { + gchar* result; + GVariant* _reply; + result = job_get_state (self); + _reply = g_variant_new_string (result); + _g_free0 (result); + return _reply; +} + + +static GVariant* _dbus_job_get_job_type (Job* self) { + gchar* result; + GVariant* _reply; + result = job_get_job_type (self); + _reply = g_variant_new_string (result); + _g_free0 (result); + return _reply; +} + + +static GVariant* _dbus_job_get_unit (Job* self) { + JobUnitLink result = {0}; + GVariantBuilder _tmp212_; + GVariant* _reply; + job_get_unit (self, &result); + g_variant_builder_init (&_tmp212_, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_tmp212_, g_variant_new_string (result.id)); + g_variant_builder_add_value (&_tmp212_, g_variant_new_object_path (result.path)); + _reply = g_variant_builder_end (&_tmp212_); + job_unit_link_destroy (&result); + return _reply; +} + + +static GVariant* job_dbus_interface_get_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GError** error, gpointer user_data) { + gpointer* data; + gpointer object; + data = user_data; + object = data[0]; + if (strcmp (property_name, "Id") == 0) { + return _dbus_job_get_id (object); + } else if (strcmp (property_name, "State") == 0) { + return _dbus_job_get_state (object); + } else if (strcmp (property_name, "JobType") == 0) { + return _dbus_job_get_job_type (object); + } else if (strcmp (property_name, "Unit") == 0) { + return _dbus_job_get_unit (object); + } + return NULL; +} + + +static gboolean job_dbus_interface_set_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GVariant* value, GError** error, gpointer user_data) { + gpointer* data; + gpointer object; + data = user_data; + object = data[0]; + return FALSE; +} + + +guint job_register_object (gpointer object, GDBusConnection* connection, const gchar* path, GError** error) { + guint result; + gpointer *data; + data = g_new (gpointer, 3); + data[0] = g_object_ref (object); + data[1] = g_object_ref (connection); + data[2] = g_strdup (path); + result = g_dbus_connection_register_object (connection, path, (GDBusInterfaceInfo *) (&_job_dbus_interface_info), &_job_dbus_interface_vtable, data, _job_unregister_object, error); + if (!result) { + return 0; + } + return result; +} + + +static void _job_unregister_object (gpointer user_data) { + gpointer* data; + data = user_data; + g_object_unref (data[0]); + g_object_unref (data[1]); + g_free (data[2]); + g_free (data); +} + + +GVariant* properties_get (Properties* self, const gchar* iface, const gchar* property, GError** error) { +#line 165 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_val_if_fail (self != NULL, NULL); +#line 165 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + return PROPERTIES_GET_INTERFACE (self)->get (self, iface, property, error); +#line 7172 "systemd-interfaces.c" +} + + +static void g_cclosure_user_marshal_VOID__STRING_BOXED_BOXED_INT (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) { + typedef void (*GMarshalFunc_VOID__STRING_BOXED_BOXED_INT) (gpointer data1, const char* arg_1, gpointer arg_2, gpointer arg_3, gint arg_4, gpointer data2); + register GMarshalFunc_VOID__STRING_BOXED_BOXED_INT callback; + register GCClosure * cc; + register gpointer data1; + register gpointer data2; + cc = (GCClosure *) closure; +#line 164 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_return_if_fail (n_param_values == 5); +#line 164 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + if (G_CCLOSURE_SWAP_DATA (closure)) { +#line 164 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data1 = closure->data; +#line 164 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data2 = param_values->data[0].v_pointer; +#line 7191 "systemd-interfaces.c" + } else { +#line 164 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data1 = param_values->data[0].v_pointer; +#line 164 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + data2 = closure->data; +#line 7197 "systemd-interfaces.c" + } +#line 164 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + callback = (GMarshalFunc_VOID__STRING_BOXED_BOXED_INT) (marshal_data ? marshal_data : cc->callback); +#line 164 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + callback (data1, g_value_get_string (param_values + 1), g_value_get_boxed (param_values + 2), g_value_get_boxed (param_values + 3), g_value_get_int (param_values + 4), data2); +#line 7203 "systemd-interfaces.c" +} + + +static void properties_base_init (PropertiesIface * iface) { +#line 164 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + static gboolean initialized = FALSE; +#line 164 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + if (!initialized) { +#line 164 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + initialized = TRUE; +#line 164 "/home/lennart/projects/systemd/src/systemd-interfaces.vala" + g_signal_new ("properties_changed", TYPE_PROPERTIES, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__STRING_BOXED_BOXED_INT, G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_HASH_TABLE, G_TYPE_STRV, G_TYPE_INT); +#line 7216 "systemd-interfaces.c" + } +} + + +GType properties_get_type (void) { + static volatile gsize properties_type_id__volatile = 0; + if (g_once_init_enter (&properties_type_id__volatile)) { + static const GTypeInfo g_define_type_info = { sizeof (PropertiesIface), (GBaseInitFunc) properties_base_init, (GBaseFinalizeFunc) NULL, (GClassInitFunc) NULL, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL }; + GType properties_type_id; + properties_type_id = g_type_register_static (G_TYPE_INTERFACE, "Properties", &g_define_type_info, 0); + g_type_interface_add_prerequisite (properties_type_id, G_TYPE_DBUS_PROXY); + g_type_set_qdata (properties_type_id, g_quark_from_static_string ("vala-dbus-proxy-type"), (void*) properties_proxy_get_type); + g_type_set_qdata (properties_type_id, g_quark_from_static_string ("vala-dbus-interface-name"), "org.freedesktop.Properties"); + g_type_set_qdata (properties_type_id, g_quark_from_static_string ("vala-dbus-register-object"), (void*) properties_register_object); + g_once_init_leave (&properties_type_id__volatile, properties_type_id); + } + return properties_type_id__volatile; +} + + +G_DEFINE_TYPE_EXTENDED (PropertiesProxy, properties_proxy, G_TYPE_DBUS_PROXY, 0, G_IMPLEMENT_INTERFACE (TYPE_PROPERTIES, properties_proxy_properties_interface_init) ) +static void properties_proxy_class_init (PropertiesProxyClass* klass) { + G_DBUS_PROXY_CLASS (klass)->g_signal = properties_proxy_g_signal; +} + + +static void _dbus_handle_properties_properties_changed (Properties* self, GVariant* parameters) { + GVariantIter _arguments_iter; + gchar* iface = NULL; + GVariant* _tmp213_; + GHashTable* changed_properties = NULL; + GVariant* _tmp214_; + GHashTable* _tmp215_; + GVariantIter _tmp216_; + GVariant* _tmp217_; + GVariant* _tmp218_; + gchar** invalidated_properties = NULL; + int invalidated_properties_length1; + GVariant* _tmp219_; + gchar** _tmp220_; + int _tmp220__length; + int _tmp220__size; + int _tmp220__length1; + GVariantIter _tmp221_; + GVariant* _tmp222_; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp213_ = g_variant_iter_next_value (&_arguments_iter); + iface = g_variant_dup_string (_tmp213_, NULL); + g_variant_unref (_tmp213_); + _tmp214_ = g_variant_iter_next_value (&_arguments_iter); + _tmp215_ = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_variant_iter_init (&_tmp216_, _tmp214_); + while (g_variant_iter_loop (&_tmp216_, "{?*}", &_tmp217_, &_tmp218_)) { + g_hash_table_insert (_tmp215_, g_variant_dup_string (_tmp217_, NULL), g_variant_get_variant (_tmp218_)); + } + changed_properties = _tmp215_; + g_variant_unref (_tmp214_); + invalidated_properties_length1 = 0; + _tmp219_ = g_variant_iter_next_value (&_arguments_iter); + _tmp220_ = g_new (gchar*, 5); + _tmp220__length = 0; + _tmp220__size = 4; + _tmp220__length1 = 0; + g_variant_iter_init (&_tmp221_, _tmp219_); + for (; (_tmp222_ = g_variant_iter_next_value (&_tmp221_)) != NULL; _tmp220__length1++) { + if (_tmp220__size == _tmp220__length) { + _tmp220__size = 2 * _tmp220__size; + _tmp220_ = g_renew (gchar*, _tmp220_, _tmp220__size + 1); + } + _tmp220_[_tmp220__length++] = g_variant_dup_string (_tmp222_, NULL); + g_variant_unref (_tmp222_); + } + invalidated_properties_length1 = _tmp220__length1; + _tmp220_[_tmp220__length] = NULL; + invalidated_properties = _tmp220_; + g_variant_unref (_tmp219_); + g_signal_emit_by_name (self, "properties-changed", iface, changed_properties, invalidated_properties, invalidated_properties_length1); + _g_free0 (iface); + _g_hash_table_unref0 (changed_properties); + invalidated_properties = (_vala_array_free (invalidated_properties, invalidated_properties_length1, (GDestroyNotify) g_free), NULL); +} + + +static void properties_proxy_g_signal (GDBusProxy* proxy, const gchar* sender_name, const gchar* signal_name, GVariant* parameters) { + if (strcmp (signal_name, "PropertiesChanged") == 0) { + _dbus_handle_properties_properties_changed ((Properties*) proxy, parameters); + } +} + + +static void properties_proxy_init (PropertiesProxy* self) { +} + + +static GVariant* properties_proxy_get (Properties* self, const gchar* iface, const gchar* property, GError** error) { + GDBusMessage *_message; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GDBusMessage *_reply_message; + GVariant *_reply; + GVariantIter _reply_iter; + GVariant* _result; + GVariant* _tmp223_; + G_IO_ERROR; + _message = g_dbus_message_new_method_call (g_dbus_proxy_get_name ((GDBusProxy *) self), g_dbus_proxy_get_object_path ((GDBusProxy *) self), "org.freedesktop.Properties", "Get"); + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (iface)); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (property)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_message_set_body (_message, _arguments); + _reply_message = g_dbus_connection_send_message_with_reply_sync (g_dbus_proxy_get_connection ((GDBusProxy *) self), _message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, g_dbus_proxy_get_default_timeout ((GDBusProxy *) self), NULL, NULL, error); + g_object_unref (_message); + if (!_reply_message) { + return NULL; + } + if (g_dbus_message_to_gerror (_reply_message, error)) { + g_object_unref (_reply_message); + return NULL; + } + _reply = g_dbus_message_get_body (_reply_message); + g_variant_iter_init (&_reply_iter, _reply); + _tmp223_ = g_variant_iter_next_value (&_reply_iter); + _result = g_variant_get_variant (_tmp223_); + g_variant_unref (_tmp223_); + g_object_unref (_reply_message); + return _result; +} + + +static void properties_proxy_properties_interface_init (PropertiesIface* iface) { + iface->get = properties_proxy_get; +} + + +static void _dbus_properties_get (Properties* self, GVariant* parameters, GDBusMethodInvocation* invocation) { + GError* error = NULL; + GVariantIter _arguments_iter; + gchar* iface = NULL; + GVariant* _tmp224_; + gchar* property = NULL; + GVariant* _tmp225_; + GDBusMessage* _reply_message; + GVariant* _reply; + GVariantBuilder _reply_builder; + GVariant* result; + g_variant_iter_init (&_arguments_iter, parameters); + _tmp224_ = g_variant_iter_next_value (&_arguments_iter); + iface = g_variant_dup_string (_tmp224_, NULL); + g_variant_unref (_tmp224_); + _tmp225_ = g_variant_iter_next_value (&_arguments_iter); + property = g_variant_dup_string (_tmp225_, NULL); + g_variant_unref (_tmp225_); + result = properties_get (self, iface, property, &error); + if (error) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + _reply_message = g_dbus_message_new_method_reply (g_dbus_method_invocation_get_message (invocation)); + g_variant_builder_init (&_reply_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_reply_builder, g_variant_new_variant (result)); + _g_variant_unref0 (result); + _reply = g_variant_builder_end (&_reply_builder); + g_dbus_message_set_body (_reply_message, _reply); + _g_free0 (iface); + _g_free0 (property); + g_dbus_connection_send_message (g_dbus_method_invocation_get_connection (invocation), _reply_message, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, NULL); + g_object_unref (invocation); + g_object_unref (_reply_message); +} + + +static void properties_dbus_interface_method_call (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* method_name, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer user_data) { + gpointer* data; + gpointer object; + data = user_data; + object = data[0]; + if (strcmp (method_name, "Get") == 0) { + _dbus_properties_get (object, parameters, invocation); + } else { + g_object_unref (invocation); + } +} + + +static GVariant* properties_dbus_interface_get_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GError** error, gpointer user_data) { + gpointer* data; + gpointer object; + data = user_data; + object = data[0]; + return NULL; +} + + +static gboolean properties_dbus_interface_set_property (GDBusConnection* connection, const gchar* sender, const gchar* object_path, const gchar* interface_name, const gchar* property_name, GVariant* value, GError** error, gpointer user_data) { + gpointer* data; + gpointer object; + data = user_data; + object = data[0]; + return FALSE; +} + + +static void _dbus_properties_properties_changed (GObject* _sender, const gchar* iface, GHashTable* changed_properties, gchar** invalidated_properties, int invalidated_properties_length1, gpointer* _data) { + GDBusConnection * _connection; + const gchar * _path; + GVariant *_arguments; + GVariantBuilder _arguments_builder; + GVariantBuilder _tmp226_; + GHashTableIter _tmp227_; + gpointer _tmp228_; + gpointer _tmp229_; + gchar** _tmp230_; + GVariantBuilder _tmp231_; + int _tmp232_; + _connection = _data[1]; + _path = _data[2]; + g_variant_builder_init (&_arguments_builder, G_VARIANT_TYPE_TUPLE); + g_variant_builder_add_value (&_arguments_builder, g_variant_new_string (iface)); + g_hash_table_iter_init (&_tmp227_, changed_properties); + g_variant_builder_init (&_tmp226_, G_VARIANT_TYPE ("a{sv}")); + while (g_hash_table_iter_next (&_tmp227_, &_tmp228_, &_tmp229_)) { + gchar* _key; + GVariant* _value; + _key = (gchar*) _tmp228_; + _value = (GVariant*) _tmp229_; + g_variant_builder_add (&_tmp226_, "{?*}", g_variant_new_string (_key), g_variant_new_variant (_value)); + } + g_variant_builder_add_value (&_arguments_builder, g_variant_builder_end (&_tmp226_)); + _tmp230_ = invalidated_properties; + g_variant_builder_init (&_tmp231_, G_VARIANT_TYPE ("as")); + for (_tmp232_ = 0; _tmp232_ < invalidated_properties_length1; _tmp232_++) { + g_variant_builder_add_value (&_tmp231_, g_variant_new_string (*_tmp230_)); + _tmp230_++; + } + g_variant_builder_add_value (&_arguments_builder, g_variant_builder_end (&_tmp231_)); + _arguments = g_variant_builder_end (&_arguments_builder); + g_dbus_connection_emit_signal (_connection, NULL, _path, "org.freedesktop.Properties", "PropertiesChanged", _arguments, NULL); +} + + +guint properties_register_object (gpointer object, GDBusConnection* connection, const gchar* path, GError** error) { + guint result; + gpointer *data; + data = g_new (gpointer, 3); + data[0] = g_object_ref (object); + data[1] = g_object_ref (connection); + data[2] = g_strdup (path); + result = g_dbus_connection_register_object (connection, path, (GDBusInterfaceInfo *) (&_properties_dbus_interface_info), &_properties_dbus_interface_vtable, data, _properties_unregister_object, error); + if (!result) { + return 0; + } + g_signal_connect (object, "properties-changed", (GCallback) _dbus_properties_properties_changed, data); + return result; +} + + +static void _properties_unregister_object (gpointer user_data) { + gpointer* data; + data = user_data; + g_signal_handlers_disconnect_by_func (data[0], _dbus_properties_properties_changed, data); + g_object_unref (data[0]); + g_object_unref (data[1]); + g_free (data[2]); + g_free (data); +} + + +static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) { + if ((array != NULL) && (destroy_func != NULL)) { + int i; + for (i = 0; i < array_length; i = i + 1) { + if (((gpointer*) array)[i] != NULL) { + destroy_func (((gpointer*) array)[i]); + } + } + } +} + + +static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) { + _vala_array_destroy (array, array_length, destroy_func); + g_free (array); +} + + + diff --git a/src/systemd-interfaces.vala b/src/systemd-interfaces.vala new file mode 100644 index 0000000..a380f79 --- /dev/null +++ b/src/systemd-interfaces.vala @@ -0,0 +1,167 @@ +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +[DBus (name = "org.freedesktop.systemd1.Manager")] +public interface Manager : DBusProxy { + + public struct UnitInfo { + string id; + string description; + string load_state; + string active_state; + string sub_state; + string following; + ObjectPath unit_path; + uint32 job_id; + string job_type; + ObjectPath job_path; + } + + public struct JobInfo { + uint32 id; + string name; + string type; + string state; + ObjectPath job_path; + ObjectPath unit_path; + } + + public abstract string[] environment { owned get; } + + public abstract UnitInfo[] list_units() throws IOError; + public abstract JobInfo[] list_jobs() throws IOError; + + public abstract ObjectPath get_unit(string name) throws IOError; + public abstract ObjectPath get_unit_by_pid(uint32 pid) throws IOError; + public abstract ObjectPath load_unit(string name) throws IOError; + public abstract ObjectPath get_job(uint32 id) throws IOError; + + public abstract ObjectPath start_unit(string name, string mode = "replace") throws IOError; + public abstract ObjectPath stop_unit(string name, string mode = "replace") throws IOError; + public abstract ObjectPath reload_unit(string name, string mode = "replace") throws IOError; + public abstract ObjectPath restart_unit(string name, string mode = "replace") throws IOError; + public abstract ObjectPath try_restart_unit(string name, string mode = "replace") throws IOError; + public abstract ObjectPath reload_or_restart_unit(string name, string mode = "replace") throws IOError; + public abstract ObjectPath reload_or_try_restart_unit(string name, string mode = "replace") throws IOError; + + public abstract void reset_failed_unit(string name = "") throws IOError; + + public abstract void clear_jobs() throws IOError; + + public abstract void subscribe() throws IOError; + public abstract void unsubscribe() throws IOError; + + public abstract string dump() throws IOError; + + public abstract void reload() throws IOError; + public abstract void reexecute() throws IOError; + public abstract void exit() throws IOError; + public abstract void halt() throws IOError; + public abstract void power_off() throws IOError; + public abstract void reboot() throws IOError; + public abstract void kexec() throws IOError; + + public abstract ObjectPath create_snapshot(string name = "", bool cleanup = false) throws IOError; + + public abstract void set_environment(string[] names) throws IOError; + public abstract void unset_environment(string[] names) throws IOError; + + public abstract signal void unit_new(string id, ObjectPath path); + public abstract signal void unit_removed(string id, ObjectPath path); + public abstract signal void job_new(uint32 id, ObjectPath path); + public abstract signal void job_removed(uint32 id, ObjectPath path, string res); +} + +[DBus (name = "org.freedesktop.systemd1.Unit")] +public interface Unit : DBusProxy { + public struct JobLink { + uint32 id; + ObjectPath path; + } + + public abstract string id { owned get; } + public abstract string[] names { owned get; } + public abstract string following { owned get; } + public abstract string[] requires { owned get; } + public abstract string[] requires_overridable { owned get; } + public abstract string[] requisite { owned get; } + public abstract string[] requisite_overridable { owned get; } + public abstract string[] wants { owned get; } + public abstract string[] required_by { owned get; } + public abstract string[] required_by_overridable { owned get; } + public abstract string[] wanted_by { owned get; } + public abstract string[] conflicts { owned get; } + public abstract string[] conflicted_by { owned get; } + public abstract string[] before { owned get; } + public abstract string[] after { owned get; } + public abstract string[] on_failure { owned get; } + public abstract string description { owned get; } + public abstract string load_state { owned get; } + public abstract string active_state { owned get; } + public abstract string sub_state { owned get; } + public abstract string fragment_path { owned get; } + public abstract uint64 inactive_exit_timestamp { owned get; } + public abstract uint64 active_enter_timestamp { owned get; } + public abstract uint64 active_exit_timestamp { owned get; } + public abstract uint64 inactive_enter_timestamp { owned get; } + public abstract bool can_start { owned get; } + public abstract bool can_stop { owned get; } + public abstract bool can_reload { owned get; } + public abstract JobLink job { owned get; } + public abstract bool recursive_stop { owned get; } + public abstract bool stop_when_unneeded { owned get; } + public abstract bool refuse_manual_start { owned get; } + public abstract bool refuse_manual_stop { owned get; } + public abstract bool default_dependencies { owned get; } + public abstract string default_control_group { owned get; } + public abstract string[] control_groups { owned get; } + public abstract bool need_daemon_reload { owned get; } + public abstract uint64 job_timeout_usec { owned get; } + + public abstract ObjectPath start(string mode = "replace") throws IOError; + public abstract ObjectPath stop(string mode = "replace") throws IOError; + public abstract ObjectPath reload(string mode = "replace") throws IOError; + public abstract ObjectPath restart(string mode = "replace") throws IOError; + public abstract ObjectPath try_restart(string mode = "replace") throws IOError; + public abstract ObjectPath reload_or_restart(string mode = "replace") throws IOError; + public abstract ObjectPath reload_or_try_restart(string mode = "replace") throws IOError; + + public abstract void reset_failed() throws IOError; +} + +[DBus (name = "org.freedesktop.systemd1.Job")] +public interface Job : DBusProxy { + public struct UnitLink { + string id; + ObjectPath path; + } + + public abstract uint32 id { owned get; } + public abstract string state { owned get; } + public abstract string job_type { owned get; } + public abstract UnitLink unit { owned get; } + + public abstract void cancel() throws IOError; +} + +[DBus (name = "org.freedesktop.Properties")] +public interface Properties : DBusProxy { + public abstract Variant? get(string iface, string property) throws IOError; + public abstract signal void properties_changed(string iface, HashTable changed_properties, string[] invalidated_properties); +} diff --git a/src/systemd.pc.in b/src/systemd.pc.in new file mode 100644 index 0000000..4f2abb0 --- /dev/null +++ b/src/systemd.pc.in @@ -0,0 +1,21 @@ +# This file is part of systemd. +# +# systemd 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. + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +systemdutildir=@rootlibexecdir@ +systemdsystemunitdir=@systemunitdir@ +systemduserunitdir=@userunitdir@ +systemdsystemconfdir=@pkgsysconfdir@/system +systemduserconfdir=@pkgsysconfdir@/user +systemdsystemunitpath=/run/systemd/system:${systemdsystemconfdir}:/etc/systemd/system:/usr/local/share/systemd/system:/usr/local/lib/systemd/system:/usr/share/systemd/system:/usr/lib/systemd/system:/lib/systemd/system:${systemdsystemunitdir} +systemduserunitpath=${systemduserconfdir}:/etc/systemd/user:/usr/local/share/systemd/user:/usr/local/lib/systemd/user:/usr/share/systemd/user:/usr/lib/systemd/user:${systemduserunitdir} + +Name: systemd +Description: systemd System and Service Manager +URL: @PACKAGE_URL@ +Version: @PACKAGE_VERSION@ diff --git a/src/systemd/sd-daemon.h b/src/systemd/sd-daemon.h new file mode 100644 index 0000000..fe51159 --- /dev/null +++ b/src/systemd/sd-daemon.h @@ -0,0 +1,282 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosddaemonhfoo +#define foosddaemonhfoo + +/*** + Copyright 2010 Lennart Poettering + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + Reference implementation of a few systemd related interfaces for + writing daemons. These interfaces are trivial to implement. To + simplify porting we provide this reference implementation. + Applications are welcome to reimplement the algorithms described + here if they do not want to include these two source files. + + The following functionality is provided: + + - Support for logging with log levels on stderr + - File descriptor passing for socket-based activation + - Daemon startup and status notification + - Detection of systemd boots + + You may compile this with -DDISABLE_SYSTEMD to disable systemd + support. This makes all those calls NOPs that are directly related to + systemd (i.e. only sd_is_xxx() will stay useful). + + Since this is drop-in code we don't want any of our symbols to be + exported in any case. Hence we declare hidden visibility for all of + them. + + You may find an up-to-date version of these source files online: + + http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-daemon.h + http://cgit.freedesktop.org/systemd/systemd/plain/src/sd-daemon.c + + This should compile on non-Linux systems, too, but with the + exception of the sd_is_xxx() calls all functions will become NOPs. + + See sd-daemon(7) for more information. +*/ + +#ifndef _sd_printf_attr_ +#if __GNUC__ >= 4 +#define _sd_printf_attr_(a,b) __attribute__ ((format (printf, a, b))) +#else +#define _sd_printf_attr_(a,b) +#endif +#endif + +/* + Log levels for usage on stderr: + + fprintf(stderr, SD_NOTICE "Hello World!\n"); + + This is similar to printk() usage in the kernel. +*/ +#define SD_EMERG "<0>" /* system is unusable */ +#define SD_ALERT "<1>" /* action must be taken immediately */ +#define SD_CRIT "<2>" /* critical conditions */ +#define SD_ERR "<3>" /* error conditions */ +#define SD_WARNING "<4>" /* warning conditions */ +#define SD_NOTICE "<5>" /* normal but significant condition */ +#define SD_INFO "<6>" /* informational */ +#define SD_DEBUG "<7>" /* debug-level messages */ + +/* The first passed file descriptor is fd 3 */ +#define SD_LISTEN_FDS_START 3 + +/* + Returns how many file descriptors have been passed, or a negative + errno code on failure. Optionally, removes the $LISTEN_FDS and + $LISTEN_PID file descriptors from the environment (recommended, but + problematic in threaded environments). If r is the return value of + this function you'll find the file descriptors passed as fds + SD_LISTEN_FDS_START to SD_LISTEN_FDS_START+r-1. Returns a negative + errno style error code on failure. This function call ensures that + the FD_CLOEXEC flag is set for the passed file descriptors, to make + sure they are not passed on to child processes. If FD_CLOEXEC shall + not be set, the caller needs to unset it after this call for all file + descriptors that are used. + + See sd_listen_fds(3) for more information. +*/ +int sd_listen_fds(int unset_environment); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is a FIFO in the file system stored under the + specified path, 0 otherwise. If path is NULL a path name check will + not be done and the call only verifies if the file descriptor + refers to a FIFO. Returns a negative errno style error code on + failure. + + See sd_is_fifo(3) for more information. +*/ +int sd_is_fifo(int fd, const char *path); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is a special character device on the file + system stored under the specified path, 0 otherwise. + If path is NULL a path name check will not be done and the call + only verifies if the file descriptor refers to a special character. + Returns a negative errno style error code on failure. + + See sd_is_special(3) for more information. +*/ +int sd_is_special(int fd, const char *path); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is a socket of the specified family (AF_INET, + ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If + family is 0 a socket family check will not be done. If type is 0 a + socket type check will not be done and the call only verifies if + the file descriptor refers to a socket. If listening is > 0 it is + verified that the socket is in listening mode. (i.e. listen() has + been called) If listening is == 0 it is verified that the socket is + not in listening mode. If listening is < 0 no listening mode check + is done. Returns a negative errno style error code on failure. + + See sd_is_socket(3) for more information. +*/ +int sd_is_socket(int fd, int family, int type, int listening); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is an Internet socket, of the specified family + (either AF_INET or AF_INET6) and the specified type (SOCK_DGRAM, + SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version + check is not done. If type is 0 a socket type check will not be + done. If port is 0 a socket port check will not be done. The + listening flag is used the same way as in sd_is_socket(). Returns a + negative errno style error code on failure. + + See sd_is_socket_inet(3) for more information. +*/ +int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is an AF_UNIX socket of the specified type + (SOCK_DGRAM, SOCK_STREAM, ...) and path, 0 otherwise. If type is 0 + a socket type check will not be done. If path is NULL a socket path + check will not be done. For normal AF_UNIX sockets set length to + 0. For abstract namespace sockets set length to the length of the + socket name (including the initial 0 byte), and pass the full + socket path in path (including the initial 0 byte). The listening + flag is used the same way as in sd_is_socket(). Returns a negative + errno style error code on failure. + + See sd_is_socket_unix(3) for more information. +*/ +int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is a POSIX Message Queue of the specified name, + 0 otherwise. If path is NULL a message queue name check is not + done. Returns a negative errno style error code on failure. +*/ +int sd_is_mq(int fd, const char *path); + +/* + Informs systemd about changed daemon state. This takes a number of + newline separated environment-style variable assignments in a + string. The following variables are known: + + READY=1 Tells systemd that daemon startup is finished (only + relevant for services of Type=notify). The passed + argument is a boolean "1" or "0". Since there is + little value in signaling non-readiness the only + value daemons should send is "READY=1". + + STATUS=... Passes a single-line status string back to systemd + that describes the daemon state. This is free-from + and can be used for various purposes: general state + feedback, fsck-like programs could pass completion + percentages and failing programs could pass a human + readable error message. Example: "STATUS=Completed + 66% of file system check..." + + ERRNO=... If a daemon fails, the errno-style error code, + formatted as string. Example: "ERRNO=2" for ENOENT. + + BUSERROR=... If a daemon fails, the D-Bus error-style error + code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut" + + MAINPID=... The main pid of a daemon, in case systemd did not + fork off the process itself. Example: "MAINPID=4711" + + WATCHDOG=1 Tells systemd to update the watchdog timestamp. + Services using this feature should do this in + regular intervals. A watchdog framework can use the + timestamps to detect failed services. + + Daemons can choose to send additional variables. However, it is + recommended to prefix variable names not listed above with X_. + + Returns a negative errno-style error code on failure. Returns > 0 + if systemd could be notified, 0 if it couldn't possibly because + systemd is not running. + + Example: When a daemon finished starting up, it could issue this + call to notify systemd about it: + + sd_notify(0, "READY=1"); + + See sd_notifyf() for more complete examples. + + See sd_notify(3) for more information. +*/ +int sd_notify(int unset_environment, const char *state); + +/* + Similar to sd_notify() but takes a format string. + + Example 1: A daemon could send the following after initialization: + + sd_notifyf(0, "READY=1\n" + "STATUS=Processing requests...\n" + "MAINPID=%lu", + (unsigned long) getpid()); + + Example 2: A daemon could send the following shortly before + exiting, on failure: + + sd_notifyf(0, "STATUS=Failed to start up: %s\n" + "ERRNO=%i", + strerror(errno), + errno); + + See sd_notifyf(3) for more information. +*/ +int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2,3); + +/* + Returns > 0 if the system was booted with systemd. Returns < 0 on + error. Returns 0 if the system was not booted with systemd. Note + that all of the functions above handle non-systemd boots just + fine. You should NOT protect them with a call to this function. Also + note that this function checks whether the system, not the user + session is controlled by systemd. However the functions above work + for both user and system services. + + See sd_booted(3) for more information. +*/ +int sd_booted(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/systemd/sd-id128.h b/src/systemd/sd-id128.h new file mode 100644 index 0000000..af2841e --- /dev/null +++ b/src/systemd/sd-id128.h @@ -0,0 +1,69 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooid128hfoo +#define fooid128hfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef union sd_id128 sd_id128_t; + +union sd_id128 { + uint8_t bytes[16]; + uint64_t qwords[2]; +}; + +char *sd_id128_to_string(sd_id128_t id, char s[33]); + +int sd_id128_from_string(const char s[33], sd_id128_t *ret); + +int sd_id128_randomize(sd_id128_t *ret); + +int sd_id128_get_machine(sd_id128_t *ret); + +int sd_id128_get_boot(sd_id128_t *ret); + +#define SD_ID128_MAKE(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \ + ((sd_id128_t) { .bytes = { 0x##v0, 0x##v1, 0x##v2, 0x##v3, 0x##v4, 0x##v5, 0x##v6, 0x##v7, \ + 0x##v8, 0x##v9, 0x##v10, 0x##v11, 0x##v12, 0x##v13, 0x##v14, 0x##v15 }}) + +/* Note that SD_ID128_FORMAT_VAL will evaluate the passed argument 16 + * times. It is hence not a good idea to call this macro with an + * expensive function as paramater or an expression with side + * effects */ +#define SD_ID128_FORMAT_STR "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" +#define SD_ID128_FORMAT_VAL(x) (x).bytes[0], (x).bytes[1], (x).bytes[2], (x).bytes[3], (x).bytes[4], (x).bytes[5], (x).bytes[6], (x).bytes[7], (x).bytes[8], (x).bytes[9], (x).bytes[10], (x).bytes[11], (x).bytes[12], (x).bytes[13], (x).bytes[14], (x).bytes[15] + +static inline bool sd_id128_equal(sd_id128_t a, sd_id128_t b) { + return memcmp(&a, &b, 16) == 0; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/systemd/sd-journal.h b/src/systemd/sd-journal.h new file mode 100644 index 0000000..5a2dab1 --- /dev/null +++ b/src/systemd/sd-journal.h @@ -0,0 +1,114 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foojournalhfoo +#define foojournalhfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Write to daemon */ + +int sd_journal_print(int piority, const char *format, ...) __attribute__ ((format (printf, 2, 3))); +int sd_journal_printv(int priority, const char *format, va_list ap); + +int sd_journal_send(const char *format, ...) __attribute__((sentinel)); +int sd_journal_sendv(const struct iovec *iov, int n); + +int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix); + +/* Browse journal stream */ + +typedef struct sd_journal sd_journal; + +enum { + SD_JOURNAL_LOCAL_ONLY = 1, + SD_JOURNAL_RUNTIME_ONLY = 2, + SD_JOURNAL_SYSTEM_ONLY = 4 +}; + +int sd_journal_open(sd_journal **ret, int flags); +void sd_journal_close(sd_journal *j); + +int sd_journal_previous(sd_journal *j); +int sd_journal_next(sd_journal *j); + +int sd_journal_previous_skip(sd_journal *j, uint64_t skip); +int sd_journal_next_skip(sd_journal *j, uint64_t skip); + +int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret); +int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id128_t *ret_boot_id); +int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *l); +int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *l); +void sd_journal_restart_data(sd_journal *j); + +int sd_journal_add_match(sd_journal *j, const void *data, size_t size); +void sd_journal_flush_matches(sd_journal *j); + +int sd_journal_seek_head(sd_journal *j); +int sd_journal_seek_tail(sd_journal *j); +int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec); +int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec); +int sd_journal_seek_cursor(sd_journal *j, const char *cursor); + +int sd_journal_get_cursor(sd_journal *j, char **cursor); + +/* int sd_journal_query_unique(sd_journal *j, const char *field); /\* missing *\/ */ +/* int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l); /\* missing *\/ */ +/* void sd_journal_restart_unique(sd_journal *j); /\* missing *\/ */ + +enum { + SD_JOURNAL_NOP, + SD_JOURNAL_APPEND, + SD_JOURNAL_INVALIDATE_ADD, + SD_JOURNAL_INVALIDATE_REMOVE +}; + +int sd_journal_get_fd(sd_journal *j); +int sd_journal_process(sd_journal *j); + +#define SD_JOURNAL_FOREACH(j) \ + if (sd_journal_seek_head(j) >= 0) \ + while (sd_journal_next(j) > 0) + +#define SD_JOURNAL_FOREACH_BACKWARDS(j) \ + if (sd_journal_seek_tail(j) >= 0) \ + while (sd_journal_previous(j) > 0) + +#define SD_JOURNAL_FOREACH_DATA(j, data, l) \ + for (sd_journal_restart_data(j); sd_journal_enumerate_data((j), &(data), &(l)) > 0; ) + +#define SD_JOURNAL_FOREACH_UNIQUE(j, data, l) \ + for (sd_journal_restart_unique(j); sd_journal_enumerate_data((j), &(data), &(l)) > 0; ) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h new file mode 100644 index 0000000..2f3c90c --- /dev/null +++ b/src/systemd/sd-login.h @@ -0,0 +1,145 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosdloginhfoo +#define foosdloginhfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * A few points: + * + * Instead of returning an empty string array or empty uid array, we + * may return NULL. + * + * Free the data we return with libc free(). + * + * We return error codes as negative errno, kernel-style. 0 or + * positive on success. + * + * These functions access data in /proc, /sys/fs/cgroup and /run. All + * of these are virtual file systems, hence the accesses are + * relatively cheap. + */ + +/* Get session from PID. Note that 'shared' processes of a user are + * not attached to a session, but only attached to a user. This will + * return an error for system processes and 'shared' processes of a + * user. */ +int sd_pid_get_session(pid_t pid, char **session); + +/* Get UID of the owner of the session of the PID (or in case the + * process is a 'shared' user process the UID of that user is + * returned). This will not return the UID of the process, but rather + * the UID of the owner of the cgroup the process is in. This will + * return an error for system processes. */ +int sd_pid_get_owner_uid(pid_t pid, uid_t *uid); + +/* Get systemd unit (i.e. service) name from PID. This will return an + * error for non-service processes. */ +int sd_pid_get_unit(pid_t, char **unit); + +/* Get state from uid. Possible states: offline, lingering, online, active */ +int sd_uid_get_state(uid_t uid, char**state); + +/* Return 1 if uid has session on seat. If require_active is true will + * look for active sessions only. */ +int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat); + +/* Return sessions of user. If require_active is true will look for + * active sessions only. Returns number of sessions as return + * value. If sessions is NULL will just return number of sessions. */ +int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions); + +/* Return seats of user is on. If require_active is true will look for + * active seats only. Returns number of seats. If seats is NULL will + * just return number of seats.*/ +int sd_uid_get_seats(uid_t uid, int require_active, char ***seats); + +/* Return 1 if the session is a active */ +int sd_session_is_active(const char *session); + +/* Determine user id of session */ +int sd_session_get_uid(const char *session, uid_t *uid); + +/* Determine seat of session */ +int sd_session_get_seat(const char *session, char **seat); + +/* Determine the (PAM) service name this session was registered by. */ +int sd_session_get_service(const char *session, char **service); + +/* Determine the type of this session, i.e. one of "tty", "x11" or "unspecified". */ +int sd_session_get_type(const char *session, char **type); + +/* Determine the class of this session, i.e. one of "user", "greeter" or "lock-screen". */ +int sd_session_get_class(const char *session, char **class); + +/* Determine the X11 display of this session. */ +int sd_session_get_display(const char *session, char **display); + +/* Return active session and user of seat */ +int sd_seat_get_active(const char *seat, char **session, uid_t *uid); + +/* Return sessions and users on seat. Returns number of sessions as + * return value. If sessions is NULL returns only the number of + * sessions. */ +int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uid, unsigned *n_uids); + +/* Return whether the seat is multi-session capable */ +int sd_seat_can_multi_session(const char *seat); + +/* Get all seats, store in *seats. Returns the number of seats. If + * seats is NULL only returns number of seats. */ +int sd_get_seats(char ***seats); + +/* Get all sessions, store in *sessions. Returns the number of + * sessions. If sessions is NULL only returns number of sessions. */ +int sd_get_sessions(char ***sessions); + +/* Get all logged in users, store in *users. Returns the number of + * users. If users is NULL only returns the number of users. */ +int sd_get_uids(uid_t **users); + +/* Monitor object */ +typedef struct sd_login_monitor sd_login_monitor; + +/* Create a new monitor. Category must be NULL, "seat", "session", + * "uid" to get monitor events for the specific category (or all). */ +int sd_login_monitor_new(const char *category, sd_login_monitor** ret); + +/* Destroys the passed monitor. Returns NULL. */ +sd_login_monitor* sd_login_monitor_unref(sd_login_monitor *m); + +/* Flushes the monitor */ +int sd_login_monitor_flush(sd_login_monitor *m); + +/* Get FD from monitor */ +int sd_login_monitor_get_fd(sd_login_monitor *m); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/systemd/sd-messages.h b/src/systemd/sd-messages.h new file mode 100644 index 0000000..c5ac3ab --- /dev/null +++ b/src/systemd/sd-messages.h @@ -0,0 +1,41 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosdmessageshfoo +#define foosdmessageshfoo + +/*** + This file is part of systemd. + + Copyright 2012 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SD_MESSAGE_JOURNAL_START SD_ID128_MAKE(f7,73,79,a8,49,0b,40,8b,be,5f,69,40,50,5a,77,7b) +#define SD_MESSAGE_JOURNAL_STOP SD_ID128_MAKE(d9,3f,b3,c9,c2,4d,45,1a,97,ce,a6,15,ce,59,c0,0b) +#define SD_MESSAGE_JOURNAL_DROPPED SD_ID128_MAKE(a5,96,d6,fe,7b,fa,49,94,82,8e,72,30,9e,95,d6,1e) + +#define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/systemd/sd-readahead.h b/src/systemd/sd-readahead.h new file mode 100644 index 0000000..1f8c5a0 --- /dev/null +++ b/src/systemd/sd-readahead.h @@ -0,0 +1,73 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foosdreadaheadhfoo +#define foosdreadaheadhfoo + +/*** + Copyright 2010 Lennart Poettering + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + Reference implementation of a few boot readahead related + interfaces. These interfaces are trivial to implement. To simplify + porting we provide this reference implementation. Applications are + welcome to reimplement the algorithms described here if they do not + want to include these two source files. + + You may compile this with -DDISABLE_SYSTEMD to disable systemd + support. This makes all calls NOPs. + + Since this is drop-in code we don't want any of our symbols to be + exported in any case. Hence we declare hidden visibility for all of + them. + + You may find an up-to-date version of these source files online: + + http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-readahead.h + http://cgit.freedesktop.org/systemd/systemd/plain/src/readahead/sd-readahead.c + + This should compile on non-Linux systems, too, but all functions + will become NOPs. + + See sd-readahead(7) for more information. +*/ + +/* + Controls ongoing disk read-ahead operations during boot-up. The argument + must be a string, and either "cancel", "done" or "noreplay". + + cancel = terminate read-ahead data collection, drop collected information + done = terminate read-ahead data collection, keep collected information + noreplay = terminate read-ahead replay +*/ +int sd_readahead(const char *action); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/target.c b/src/target.c new file mode 100644 index 0000000..6c1e0c3 --- /dev/null +++ b/src/target.c @@ -0,0 +1,224 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "unit.h" +#include "target.h" +#include "load-fragment.h" +#include "log.h" +#include "dbus-target.h" +#include "special.h" +#include "unit-name.h" + +static const UnitActiveState state_translation_table[_TARGET_STATE_MAX] = { + [TARGET_DEAD] = UNIT_INACTIVE, + [TARGET_ACTIVE] = UNIT_ACTIVE +}; + +static void target_set_state(Target *t, TargetState state) { + TargetState old_state; + assert(t); + + old_state = t->state; + t->state = state; + + if (state != old_state) + log_debug("%s changed %s -> %s", + UNIT(t)->id, + target_state_to_string(old_state), + target_state_to_string(state)); + + unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true); +} + +static int target_add_default_dependencies(Target *t) { + static const UnitDependency deps[] = { + UNIT_REQUIRES, + UNIT_REQUIRES_OVERRIDABLE, + UNIT_REQUISITE, + UNIT_REQUISITE_OVERRIDABLE, + UNIT_WANTS, + UNIT_BIND_TO + }; + + Iterator i; + Unit *other; + int r; + unsigned k; + + assert(t); + + /* Imply ordering for requirement dependencies on target + * units. Note that when the user created a contradicting + * ordering manually we won't add anything in here to make + * sure we don't create a loop. */ + + for (k = 0; k < ELEMENTSOF(deps); k++) + SET_FOREACH(other, UNIT(t)->dependencies[deps[k]], i) + if ((r = unit_add_default_target_dependency(other, UNIT(t))) < 0) + return r; + + /* Make sure targets are unloaded on shutdown */ + return unit_add_dependency_by_name(UNIT(t), UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); +} + +static int target_load(Unit *u) { + Target *t = TARGET(u); + int r; + + assert(t); + + if ((r = unit_load_fragment_and_dropin(u)) < 0) + return r; + + /* This is a new unit? Then let's add in some extras */ + if (u->load_state == UNIT_LOADED) { + if (u->default_dependencies) + if ((r = target_add_default_dependencies(t)) < 0) + return r; + } + + return 0; +} + +static int target_coldplug(Unit *u) { + Target *t = TARGET(u); + + assert(t); + assert(t->state == TARGET_DEAD); + + if (t->deserialized_state != t->state) + target_set_state(t, t->deserialized_state); + + return 0; +} + +static void target_dump(Unit *u, FILE *f, const char *prefix) { + Target *t = TARGET(u); + + assert(t); + assert(f); + + fprintf(f, + "%sTarget State: %s\n", + prefix, target_state_to_string(t->state)); +} + +static int target_start(Unit *u) { + Target *t = TARGET(u); + + assert(t); + assert(t->state == TARGET_DEAD); + + target_set_state(t, TARGET_ACTIVE); + return 0; +} + +static int target_stop(Unit *u) { + Target *t = TARGET(u); + + assert(t); + assert(t->state == TARGET_ACTIVE); + + target_set_state(t, TARGET_DEAD); + return 0; +} + +static int target_serialize(Unit *u, FILE *f, FDSet *fds) { + Target *s = TARGET(u); + + assert(s); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", target_state_to_string(s->state)); + return 0; +} + +static int target_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Target *s = TARGET(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + TargetState state; + + if ((state = target_state_from_string(value)) < 0) + log_debug("Failed to parse state value %s", value); + else + s->deserialized_state = state; + + } else + log_debug("Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState target_active_state(Unit *u) { + assert(u); + + return state_translation_table[TARGET(u)->state]; +} + +static const char *target_sub_state_to_string(Unit *u) { + assert(u); + + return target_state_to_string(TARGET(u)->state); +} + +static const char* const target_state_table[_TARGET_STATE_MAX] = { + [TARGET_DEAD] = "dead", + [TARGET_ACTIVE] = "active" +}; + +DEFINE_STRING_TABLE_LOOKUP(target_state, TargetState); + +const UnitVTable target_vtable = { + .suffix = ".target", + .object_size = sizeof(Target), + .sections = + "Unit\0" + "Target\0" + "Install\0", + + .load = target_load, + .coldplug = target_coldplug, + + .dump = target_dump, + + .start = target_start, + .stop = target_stop, + + .serialize = target_serialize, + .deserialize_item = target_deserialize_item, + + .active_state = target_active_state, + .sub_state_to_string = target_sub_state_to_string, + + .bus_interface = "org.freedesktop.systemd1.Target", + .bus_message_handler = bus_target_message_handler +}; diff --git a/src/target.h b/src/target.h new file mode 100644 index 0000000..5b97c86 --- /dev/null +++ b/src/target.h @@ -0,0 +1,47 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef footargethfoo +#define footargethfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct Target Target; + +#include "unit.h" + +typedef enum TargetState { + TARGET_DEAD, + TARGET_ACTIVE, + _TARGET_STATE_MAX, + _TARGET_STATE_INVALID = -1 +} TargetState; + +struct Target { + Unit meta; + + TargetState state, deserialized_state; +}; + +extern const UnitVTable target_vtable; + +const char* target_state_to_string(TargetState i); +TargetState target_state_from_string(const char *s); + +#endif diff --git a/src/tcpwrap.c b/src/tcpwrap.c new file mode 100644 index 0000000..0aab142 --- /dev/null +++ b/src/tcpwrap.c @@ -0,0 +1,68 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#ifdef HAVE_LIBWRAP +#include +#endif + +#include "tcpwrap.h" +#include "log.h" + +bool socket_tcpwrap(int fd, const char *name) { +#ifdef HAVE_LIBWRAP + struct request_info req; + union { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; + struct sockaddr_un un; + struct sockaddr_storage storage; + } sa_union; + socklen_t l = sizeof(sa_union); + + if (getsockname(fd, &sa_union.sa, &l) < 0) + return true; + + if (sa_union.sa.sa_family != AF_INET && + sa_union.sa.sa_family != AF_INET6) + return true; + + request_init(&req, + RQ_DAEMON, name, + RQ_FILE, fd, + NULL); + + fromhost(&req); + + if (!hosts_access(&req)) { + log_warning("Connection refused by tcpwrap."); + return false; + } + + log_debug("Connection accepted by tcpwrap."); +#endif + return true; +} diff --git a/src/tcpwrap.h b/src/tcpwrap.h new file mode 100644 index 0000000..4d4553e --- /dev/null +++ b/src/tcpwrap.h @@ -0,0 +1,29 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foolibwraphfoo +#define foolibwraphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +bool socket_tcpwrap(int fd, const char *name); + +#endif diff --git a/src/test-cgroup.c b/src/test-cgroup.c new file mode 100644 index 0000000..eb18937 --- /dev/null +++ b/src/test-cgroup.c @@ -0,0 +1,104 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "cgroup-util.h" +#include "util.h" +#include "log.h" + +int main(int argc, char*argv[]) { + char *path; + char *c, *p; + + assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-a") == 0); + assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-a") == 0); + assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-b") == 0); + assert_se(cg_create(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-c") == 0); + assert_se(cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0) == 0); + + assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0); + assert_se(streq(path, "/test-b")); + free(path); + + assert_se(cg_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0) == 0); + + assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0); + assert_se(path_equal(path, "/test-a")); + free(path); + + assert_se(cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-d", 0) == 0); + + assert_se(cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, getpid(), &path) == 0); + assert_se(path_equal(path, "/test-b/test-d")); + free(path); + + assert_se(cg_get_path(SYSTEMD_CGROUP_CONTROLLER, "/test-b/test-d", NULL, &path) == 0); + assert_se(path_equal(path, "/sys/fs/cgroup/systemd/test-b/test-d")); + free(path); + + assert_se(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, "/test-a", false) > 0); + assert_se(cg_is_empty(SYSTEMD_CGROUP_CONTROLLER, "/test-b", false) > 0); + assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", false) > 0); + assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", false) == 0); + + assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0, false, false, false, NULL) == 0); + assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0, false, false, false, NULL) > 0); + + assert_se(cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", "/test-a", false, false) > 0); + + assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", false) == 0); + assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", false) > 0); + + assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0, false, false, false, NULL) > 0); + assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0, false, false, false, NULL) == 0); + + cg_trim(SYSTEMD_CGROUP_CONTROLLER, "/", false); + + assert_se(cg_delete(SYSTEMD_CGROUP_CONTROLLER, "/test-b") < 0); + assert_se(cg_delete(SYSTEMD_CGROUP_CONTROLLER, "/test-a") >= 0); + + assert_se(cg_split_spec("foobar:/", &c, &p) == 0); + assert(streq(c, "foobar")); + assert(streq(p, "/")); + free(c); + free(p); + + assert_se(cg_split_spec("foobar:", &c, &p) < 0); + assert_se(cg_split_spec("foobar:asdfd", &c, &p) < 0); + assert_se(cg_split_spec(":///", &c, &p) < 0); + assert_se(cg_split_spec(":", &c, &p) < 0); + assert_se(cg_split_spec("", &c, &p) < 0); + assert_se(cg_split_spec("fo/obar:/", &c, &p) < 0); + + assert_se(cg_split_spec("/", &c, &p) >= 0); + assert(c == NULL); + assert(streq(p, "/")); + free(p); + + assert_se(cg_split_spec("foo", &c, &p) >= 0); + assert(streq(c, "foo")); + assert(p == NULL); + free(c); + + return 0; +} diff --git a/src/test-daemon.c b/src/test-daemon.c new file mode 100644 index 0000000..20c5d15 --- /dev/null +++ b/src/test-daemon.c @@ -0,0 +1,37 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include + +int main(int argc, char*argv[]) { + + sd_notify(0, "STATUS=Starting up"); + sleep(5); + sd_notify(0, + "STATUS=Running\n" + "READY=1"); + sleep(10); + sd_notify(0, "STATUS=Quitting"); + + return 0; +} diff --git a/src/test-engine.c b/src/test-engine.c new file mode 100644 index 0000000..46a2d2c --- /dev/null +++ b/src/test-engine.c @@ -0,0 +1,99 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "manager.h" + +int main(int argc, char *argv[]) { + Manager *m = NULL; + Unit *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *g = NULL, *h = NULL; + Job *j; + + assert_se(set_unit_path("test") >= 0); + + assert_se(manager_new(MANAGER_SYSTEM, &m) >= 0); + + printf("Load1:\n"); + assert_se(manager_load_unit(m, "a.service", NULL, NULL, &a) >= 0); + assert_se(manager_load_unit(m, "b.service", NULL, NULL, &b) >= 0); + assert_se(manager_load_unit(m, "c.service", NULL, NULL, &c) >= 0); + manager_dump_units(m, stdout, "\t"); + + printf("Test1: (Trivial)\n"); + assert_se(manager_add_job(m, JOB_START, c, JOB_REPLACE, false, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Load2:\n"); + manager_clear_jobs(m); + assert_se(manager_load_unit(m, "d.service", NULL, NULL, &d) >= 0); + assert_se(manager_load_unit(m, "e.service", NULL, NULL, &e) >= 0); + manager_dump_units(m, stdout, "\t"); + + printf("Test2: (Cyclic Order, Unfixable)\n"); + assert_se(manager_add_job(m, JOB_START, d, JOB_REPLACE, false, NULL, &j) == -ENOEXEC); + manager_dump_jobs(m, stdout, "\t"); + + printf("Test3: (Cyclic Order, Fixable, Garbage Collector)\n"); + assert_se(manager_add_job(m, JOB_START, e, JOB_REPLACE, false, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Test4: (Identical transaction)\n"); + assert_se(manager_add_job(m, JOB_START, e, JOB_FAIL, false, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Load3:\n"); + assert_se(manager_load_unit(m, "g.service", NULL, NULL, &g) >= 0); + manager_dump_units(m, stdout, "\t"); + + printf("Test5: (Colliding transaction, fail)\n"); + assert_se(manager_add_job(m, JOB_START, g, JOB_FAIL, false, NULL, &j) == -EEXIST); + + printf("Test6: (Colliding transaction, replace)\n"); + assert_se(manager_add_job(m, JOB_START, g, JOB_REPLACE, false, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Test7: (Unmergeable job type, fail)\n"); + assert_se(manager_add_job(m, JOB_STOP, g, JOB_FAIL, false, NULL, &j) == -EEXIST); + + printf("Test8: (Mergeable job type, fail)\n"); + assert_se(manager_add_job(m, JOB_RESTART, g, JOB_FAIL, false, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Test9: (Unmergeable job type, replace)\n"); + assert_se(manager_add_job(m, JOB_STOP, g, JOB_REPLACE, false, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + printf("Load4:\n"); + assert_se(manager_load_unit(m, "h.service", NULL, NULL, &h) >= 0); + manager_dump_units(m, stdout, "\t"); + + printf("Test10: (Unmergeable job type of auxiliary job, fail)\n"); + assert_se(manager_add_job(m, JOB_START, h, JOB_FAIL, false, NULL, &j) == 0); + manager_dump_jobs(m, stdout, "\t"); + + manager_free(m); + + return 0; +} diff --git a/src/test-env-replace.c b/src/test-env-replace.c new file mode 100644 index 0000000..05dbacd --- /dev/null +++ b/src/test-env-replace.c @@ -0,0 +1,127 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +#include "util.h" +#include "log.h" +#include "strv.h" + +int main(int argc, char *argv[]) { + + const char *env[] = { + "FOO=BAR BAR", + "BAR=waldo", + NULL + }; + + const char *line[] = { + "FOO$FOO", + "FOO$FOOFOO", + "FOO${FOO}$FOO", + "FOO${FOO}", + "${FOO}", + "$FOO", + "$FOO$FOO", + "${FOO}${BAR}", + "${FOO", + NULL + }; + + char **i, **r, *t, **a, **b; + const char nulstr[] = "fuck\0fuck2\0fuck3\0\0fuck5\0\0xxx"; + + a = strv_parse_nulstr(nulstr, sizeof(nulstr)-1); + + STRV_FOREACH(i, a) + printf("nulstr--%s\n", *i); + + strv_free(a); + + r = replace_env_argv((char**) line, (char**) env); + + STRV_FOREACH(i, r) + printf("%s\n", *i); + + strv_free(r); + + t = normalize_env_assignment("foo=bar"); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("=bar"); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("foo="); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("="); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment(""); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=\"waldo\""); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=\"waldo"); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=waldo\""); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=\'"); + printf("%s\n", t); + free(t); + + t = normalize_env_assignment("a=\'\'"); + printf("%s\n", t); + free(t); + + a = strv_new("FOO=BAR", "WALDO=WALDO", "WALDO=", "PIEP", "SCHLUMPF=SMURF", NULL); + b = strv_new("FOO=KKK", "FOO=", "PIEP=", "SCHLUMPF=SMURFF", "NANANANA=YES", NULL); + + r = strv_env_merge(2, a, b); + strv_free(a); + strv_free(b); + + STRV_FOREACH(i, r) + printf("%s\n", *i); + + printf("CLEANED UP:\n"); + + r = strv_env_clean(r); + + STRV_FOREACH(i, r) + printf("%s\n", *i); + + strv_free(r); + + return 0; +} diff --git a/src/test-hostname.c b/src/test-hostname.c new file mode 100644 index 0000000..0a08416 --- /dev/null +++ b/src/test-hostname.c @@ -0,0 +1,37 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "hostname-setup.h" +#include "util.h" + +int main(int argc, char* argv[]) { + int r; + + if ((r = hostname_setup()) < 0) + fprintf(stderr, "hostname: %s\n", strerror(-r)); + + return 0; +} diff --git a/src/test-id128.c b/src/test-id128.c new file mode 100644 index 0000000..617c955 --- /dev/null +++ b/src/test-id128.c @@ -0,0 +1,52 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include + +#include "util.h" +#include "macro.h" + +#define ID128_WALDI SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10) + +int main(int argc, char *argv[]) { + sd_id128_t id, id2; + char t[33]; + + assert_se(sd_id128_randomize(&id) == 0); + printf("random: %s\n", sd_id128_to_string(id, t)); + + assert_se(sd_id128_from_string(t, &id2) == 0); + assert_se(sd_id128_equal(id, id2)); + + assert_se(sd_id128_get_machine(&id) == 0); + printf("machine: %s\n", sd_id128_to_string(id, t)); + + assert_se(sd_id128_get_boot(&id) == 0); + printf("boot: %s\n", sd_id128_to_string(id, t)); + + printf("waldi: %s\n", sd_id128_to_string(ID128_WALDI, t)); + + printf("waldi2: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(ID128_WALDI)); + + return 0; +} diff --git a/src/test-install.c b/src/test-install.c new file mode 100644 index 0000000..f8e87e0 --- /dev/null +++ b/src/test-install.c @@ -0,0 +1,264 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "util.h" +#include "install.h" + +static void dump_changes(UnitFileChange *c, unsigned n) { + unsigned i; + + assert(n == 0 || c); + + for (i = 0; i < n; i++) { + if (c[i].type == UNIT_FILE_UNLINK) + printf("rm '%s'\n", c[i].path); + else if (c[i].type == UNIT_FILE_SYMLINK) + printf("ln -s '%s' '%s'\n", c[i].source, c[i].path); + } +} + +int main(int argc, char* argv[]) { + Hashmap *h; + UnitFileList *p; + Iterator i; + int r; + const char *const files[] = { "avahi-daemon.service", NULL }; + const char *const files2[] = { "/home/lennart/test.service", NULL }; + UnitFileChange *changes = NULL; + unsigned n_changes = 0; + + h = hashmap_new(string_hash_func, string_compare_func); + r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h); + assert_se(r == 0); + + HASHMAP_FOREACH(p, h, i) { + UnitFileState s; + + s = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(p->path)); + + assert_se(p->state == s); + + fprintf(stderr, "%s (%s)\n", + p->path, + unit_file_state_to_string(p->state)); + } + + unit_file_list_free(h); + + log_error("enable"); + + r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes); + assert_se(r >= 0); + + log_error("enable2"); + + r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_ENABLED); + + log_error("disable"); + + changes = NULL; + n_changes = 0; + + r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_DISABLED); + + log_error("mask"); + changes = NULL; + n_changes = 0; + + r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes); + assert_se(r >= 0); + log_error("mask2"); + r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_MASKED); + + log_error("unmask"); + changes = NULL; + n_changes = 0; + + r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes); + assert_se(r >= 0); + log_error("unmask2"); + r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_DISABLED); + + log_error("mask"); + changes = NULL; + n_changes = 0; + + r = unit_file_mask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_MASKED); + + log_error("disable"); + changes = NULL; + n_changes = 0; + + r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes); + assert_se(r >= 0); + log_error("disable2"); + r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_MASKED); + + log_error("umask"); + changes = NULL; + n_changes = 0; + + r = unit_file_unmask(UNIT_FILE_SYSTEM, false, NULL, (char**) files, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0]) == UNIT_FILE_DISABLED); + + log_error("enable files2"); + changes = NULL; + n_changes = 0; + + r = unit_file_enable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files2[0])) == UNIT_FILE_ENABLED); + + log_error("disable files2"); + changes = NULL; + n_changes = 0; + + r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files2[0])) == _UNIT_FILE_STATE_INVALID); + + log_error("link files2"); + changes = NULL; + n_changes = 0; + + r = unit_file_link(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files2[0])) == UNIT_FILE_LINKED); + + log_error("disable files2"); + changes = NULL; + n_changes = 0; + + r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files2[0])) == _UNIT_FILE_STATE_INVALID); + + log_error("link files2"); + changes = NULL; + n_changes = 0; + + r = unit_file_link(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files2[0])) == UNIT_FILE_LINKED); + + log_error("reenable files2"); + changes = NULL; + n_changes = 0; + + r = unit_file_reenable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files2[0])) == UNIT_FILE_ENABLED); + + log_error("disable files2"); + changes = NULL; + n_changes = 0; + + r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files2[0])) == _UNIT_FILE_STATE_INVALID); + log_error("preset files"); + changes = NULL; + n_changes = 0; + + r = unit_file_preset(UNIT_FILE_SYSTEM, false, NULL, (char**) files, false, &changes, &n_changes); + assert_se(r >= 0); + + dump_changes(changes, n_changes); + unit_file_changes_free(changes, n_changes); + + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, NULL, file_name_from_path(files[0])) == UNIT_FILE_ENABLED); + + return 0; +} diff --git a/src/test-job-type.c b/src/test-job-type.c new file mode 100644 index 0000000..9de21e1 --- /dev/null +++ b/src/test-job-type.c @@ -0,0 +1,84 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "job.h" + +int main(int argc, char*argv[]) { + JobType a, b, c, d, e, f, g; + + for (a = 0; a < _JOB_TYPE_MAX; a++) + for (b = 0; b < _JOB_TYPE_MAX; b++) { + + if (!job_type_is_mergeable(a, b)) + printf("Not mergeable: %s + %s\n", job_type_to_string(a), job_type_to_string(b)); + + for (c = 0; c < _JOB_TYPE_MAX; c++) { + + /* Verify transitivity of mergeability + * of job types */ + assert(!job_type_is_mergeable(a, b) || + !job_type_is_mergeable(b, c) || + job_type_is_mergeable(a, c)); + + d = a; + if (job_type_merge(&d, b) >= 0) { + + printf("%s + %s = %s\n", job_type_to_string(a), job_type_to_string(b), job_type_to_string(d)); + + /* Verify that merged entries can be + * merged with the same entries they + * can be merged with separately */ + assert(!job_type_is_mergeable(a, c) || job_type_is_mergeable(d, c)); + assert(!job_type_is_mergeable(b, c) || job_type_is_mergeable(d, c)); + + /* Verify that if a merged + * with b is not mergeable with + * c then either a or b is not + * mergeable with c either. */ + assert(job_type_is_mergeable(d, c) || !job_type_is_mergeable(a, c) || !job_type_is_mergeable(b, c)); + + e = b; + if (job_type_merge(&e, c) >= 0) { + + /* Verify associativity */ + + f = d; + assert(job_type_merge(&f, c) == 0); + + g = e; + assert(job_type_merge(&g, a) == 0); + + assert(f == g); + + printf("%s + %s + %s = %s\n", job_type_to_string(a), job_type_to_string(b), job_type_to_string(c), job_type_to_string(d)); + } + } + } + } + + + return 0; +} diff --git a/src/test-loopback.c b/src/test-loopback.c new file mode 100644 index 0000000..9784aaf --- /dev/null +++ b/src/test-loopback.c @@ -0,0 +1,37 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include + +#include "loopback-setup.h" +#include "util.h" + +int main(int argc, char* argv[]) { + int r; + + if ((r = loopback_setup()) < 0) + fprintf(stderr, "loopback: %s\n", strerror(-r)); + + return 0; +} diff --git a/src/test-ns.c b/src/test-ns.c new file mode 100644 index 0000000..e2bdfc5 --- /dev/null +++ b/src/test-ns.c @@ -0,0 +1,60 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include "namespace.h" +#include "log.h" + +int main(int argc, char *argv[]) { + const char * const writable[] = { + "/home", + NULL + }; + + const char * const readable[] = { + "/", + "/usr", + "/boot", + NULL + }; + + const char * const inaccessible[] = { + "/home/lennart/projects", + NULL + }; + + int r; + + if ((r = setup_namespace((char**) writable, (char**) readable, (char**) inaccessible, true, MS_SHARED)) < 0) { + log_error("Failed to setup namespace: %s", strerror(-r)); + return 1; + } + + execl("/bin/sh", "/bin/sh", NULL); + log_error("execl(): %m"); + + return 1; +} diff --git a/src/test-strv.c b/src/test-strv.c new file mode 100644 index 0000000..1d577df --- /dev/null +++ b/src/test-strv.c @@ -0,0 +1,66 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "util.h" +#include "specifier.h" + +int main(int argc, char *argv[]) { + const Specifier table[] = { + { 'a', specifier_string, (char*) "AAAA" }, + { 'b', specifier_string, (char*) "BBBB" }, + { 0, NULL, NULL } + }; + + char *w, *state; + size_t l; + const char test[] = "test a b c 'd' e '' '' hhh '' ''"; + + printf("<%s>\n", test); + + FOREACH_WORD_QUOTED(w, l, test, state) { + char *t; + + assert_se(t = strndup(w, l)); + printf("<%s>\n", t); + free(t); + } + + printf("%s\n", default_term_for_tty("/dev/tty23")); + printf("%s\n", default_term_for_tty("/dev/ttyS23")); + printf("%s\n", default_term_for_tty("/dev/tty0")); + printf("%s\n", default_term_for_tty("/dev/pty0")); + printf("%s\n", default_term_for_tty("/dev/pts/0")); + printf("%s\n", default_term_for_tty("/dev/console")); + printf("%s\n", default_term_for_tty("tty23")); + printf("%s\n", default_term_for_tty("ttyS23")); + printf("%s\n", default_term_for_tty("tty0")); + printf("%s\n", default_term_for_tty("pty0")); + printf("%s\n", default_term_for_tty("pts/0")); + printf("%s\n", default_term_for_tty("console")); + + w = specifier_printf("xxx a=%a b=%b yyy", table, NULL); + printf("<%s>\n", w); + free(w); + + return 0; +} diff --git a/src/timedate/org.freedesktop.timedate1.conf b/src/timedate/org.freedesktop.timedate1.conf new file mode 100644 index 0000000..c9c221b --- /dev/null +++ b/src/timedate/org.freedesktop.timedate1.conf @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/timedate/org.freedesktop.timedate1.policy.in b/src/timedate/org.freedesktop.timedate1.policy.in new file mode 100644 index 0000000..3d9c208 --- /dev/null +++ b/src/timedate/org.freedesktop.timedate1.policy.in @@ -0,0 +1,61 @@ + + + + + + + + The systemd Project + http://www.freedesktop.org/wiki/Software/systemd + + + <_description>Set system time + <_message>Authentication is required to set the system time. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Set system timezone + <_message>Authentication is required to set the system timezone. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Set RTC to local timezone or UTC + <_message>Authentication is required to control whether + the RTC stores the local or UTC time. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + <_description>Turn network time synchronization on or off + <_message>Authentication is required to control whether + network time synchronization shall be enabled. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + diff --git a/src/timedate/org.freedesktop.timedate1.service b/src/timedate/org.freedesktop.timedate1.service new file mode 100644 index 0000000..c3120b6 --- /dev/null +++ b/src/timedate/org.freedesktop.timedate1.service @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# systemd 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. + +[D-BUS Service] +Name=org.freedesktop.timedate1 +Exec=/bin/false +User=root +SystemdService=dbus-org.freedesktop.timedate1.service diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c new file mode 100644 index 0000000..6a7d980 --- /dev/null +++ b/src/timedate/timedated.c @@ -0,0 +1,930 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include +#include +#include + +#include "util.h" +#include "strv.h" +#include "dbus-common.h" +#include "polkit.h" +#include "def.h" + +#define NULL_ADJTIME_UTC "0.0 0 0\n0\nUTC\n" +#define NULL_ADJTIME_LOCAL "0.0 0 0\n0\nLOCAL\n" + +#define INTERFACE \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" + +#define INTROSPECTION \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + INTERFACE \ + BUS_PROPERTIES_INTERFACE \ + BUS_INTROSPECTABLE_INTERFACE \ + BUS_PEER_INTERFACE \ + "\n" + +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.timedate1\0" + +const char timedate_interface[] _introspect_("timedate1") = INTERFACE; + +typedef struct TZ { + char *zone; + bool local_rtc; + int use_ntp; +} TZ; + +static TZ tz = { + .use_ntp = -1, +}; + +static usec_t remain_until; + +static void free_data(void) { + free(tz.zone); + tz.zone = NULL; + + tz.local_rtc = false; +} + +static bool valid_timezone(const char *name) { + const char *p; + char *t; + bool slash = false; + int r; + struct stat st; + + assert(name); + + if (*name == '/' || *name == 0) + return false; + + for (p = name; *p; p++) { + if (!(*p >= '0' && *p <= '9') && + !(*p >= 'a' && *p <= 'z') && + !(*p >= 'A' && *p <= 'Z') && + !(*p == '-' || *p == '_' || *p == '+' || *p == '/')) + return false; + + if (*p == '/') { + + if (slash) + return false; + + slash = true; + } else + slash = false; + } + + if (slash) + return false; + + t = strappend("/usr/share/zoneinfo/", name); + if (!t) + return false; + + r = stat(t, &st); + free(t); + + if (r < 0) + return false; + + if (!S_ISREG(st.st_mode)) + return false; + + return true; +} + +static void verify_timezone(void) { + char *p, *a = NULL, *b = NULL; + size_t l, q; + int j, k; + + if (!tz.zone) + return; + + p = strappend("/usr/share/zoneinfo/", tz.zone); + if (!p) { + log_error("Out of memory"); + return; + } + + j = read_full_file("/etc/localtime", &a, &l); + k = read_full_file(p, &b, &q); + + free(p); + + if (j < 0 || k < 0 || l != q || memcmp(a, b, l)) { + log_warning("/etc/localtime and /etc/timezone out of sync."); + free(tz.zone); + tz.zone = NULL; + } + + free(a); + free(b); +} + +static int read_data(void) { + int r; + + free_data(); + + r = read_one_line_file("/etc/timezone", &tz.zone); + if (r < 0) { + if (r != -ENOENT) + log_warning("Failed to read /etc/timezone: %s", strerror(-r)); + +#ifdef TARGET_FEDORA + r = parse_env_file("/etc/sysconfig/clock", NEWLINE, + "ZONE", &tz.zone, + NULL); + + if (r < 0 && r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/clock: %s", strerror(-r)); +#endif + } + + if (isempty(tz.zone)) { + free(tz.zone); + tz.zone = NULL; + } + + verify_timezone(); + + tz.local_rtc = hwclock_is_localtime() > 0; + + return 0; +} + +static int write_data_timezone(void) { + int r = 0; + char *p; + + if (!tz.zone) { + if (unlink("/etc/timezone") < 0 && errno != ENOENT) + r = -errno; + + if (unlink("/etc/localtime") < 0 && errno != ENOENT) + r = -errno; + + return r; + } + + p = strappend("/usr/share/zoneinfo/", tz.zone); + if (!p) { + log_error("Out of memory"); + return -ENOMEM; + } + + r = symlink_or_copy_atomic(p, "/etc/localtime"); + free(p); + + if (r < 0) + return r; + + r = write_one_line_file_atomic("/etc/timezone", tz.zone); + if (r < 0) + return r; + + return 0; +} + +static int write_data_local_rtc(void) { + int r; + char *s, *w; + + r = read_full_file("/etc/adjtime", &s, NULL); + if (r < 0) { + if (r != -ENOENT) + return r; + + if (!tz.local_rtc) + return 0; + + w = strdup(NULL_ADJTIME_LOCAL); + if (!w) + return -ENOMEM; + } else { + char *p, *e; + size_t a, b; + + p = strchr(s, '\n'); + if (!p) { + free(s); + return -EIO; + } + + p = strchr(p+1, '\n'); + if (!p) { + free(s); + return -EIO; + } + + p++; + e = strchr(p, '\n'); + if (!e) { + free(s); + return -EIO; + } + + a = p - s; + b = strlen(e); + + w = new(char, a + (tz.local_rtc ? 5 : 3) + b + 1); + if (!w) { + free(s); + return -ENOMEM; + } + + *(char*) mempcpy(stpcpy(mempcpy(w, s, a), tz.local_rtc ? "LOCAL" : "UTC"), e, b) = 0; + + if (streq(w, NULL_ADJTIME_UTC)) { + free(w); + + if (unlink("/etc/adjtime") < 0) { + if (errno != ENOENT) + return -errno; + } + + return 0; + } + } + + r = write_one_line_file_atomic("/etc/adjtime", w); + free(w); + + return r; +} + +static int read_ntp(DBusConnection *bus) { + DBusMessage *m = NULL, *reply = NULL; + const char *name = "ntpd.service", *s; + DBusError error; + int r; + + assert(bus); + + dbus_error_init(&error); + + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnitFileState"); + + if (!m) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + + if (streq(error.name, "org.freedesktop.DBus.Error.FileNotFound")) { + /* NTP is not installed. */ + tz.use_ntp = false; + r = 0; + goto finish; + } + + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_STRING, &s, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + tz.use_ntp = + streq(s, "enabled") || + streq(s, "enabled-runtime"); + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int start_ntp(DBusConnection *bus, DBusError *error) { + DBusMessage *m = NULL, *reply = NULL; + const char *name = "ntpd.service", *mode = "replace"; + int r; + + assert(bus); + assert(error); + + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + tz.use_ntp ? "StartUnit" : "StopUnit"); + if (!m) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(error)); + r = -EIO; + goto finish; + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + return r; +} + +static int enable_ntp(DBusConnection *bus, DBusError *error) { + DBusMessage *m = NULL, *reply = NULL; + const char * const names[] = { "ntpd.service", NULL }; + int r; + DBusMessageIter iter; + dbus_bool_t f = FALSE, t = TRUE; + + assert(bus); + assert(error); + + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + tz.use_ntp ? "EnableUnitFiles" : "DisableUnitFiles"); + + if (!m) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + dbus_message_iter_init_append(m, &iter); + + r = bus_append_strv_iter(&iter, (char**) names); + if (r < 0) { + log_error("Failed to append unit files."); + goto finish; + } + /* send runtime bool */ + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &f)) { + log_error("Failed to append runtime boolean."); + r = -ENOMEM; + goto finish; + } + + if (tz.use_ntp) { + /* send force bool */ + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &t)) { + log_error("Failed to append force boolean."); + r = -ENOMEM; + goto finish; + } + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(m); + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "Reload"); + if (!m) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + dbus_message_unref(reply); + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(error)); + r = -EIO; + goto finish; + } + + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + return r; +} + +static int property_append_ntp(DBusMessageIter *i, const char *property, void *data) { + dbus_bool_t db; + + assert(i); + assert(property); + + db = tz.use_ntp > 0; + + if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &db)) + return -ENOMEM; + + return 0; +} + +static const BusProperty bus_timedate_properties[] = { + { "Timezone", bus_property_append_string, "s", offsetof(TZ, zone), true }, + { "LocalRTC", bus_property_append_bool, "b", offsetof(TZ, local_rtc) }, + { "NTP", property_append_ntp, "b", offsetof(TZ, use_ntp) }, + { NULL, } +}; + +static const BusBoundProperties bps[] = { + { "org.freedesktop.timedate1", bus_timedate_properties, &tz }, + { NULL, } +}; + +static DBusHandlerResult timedate_message_handler( + DBusConnection *connection, + DBusMessage *message, + void *userdata) { + + DBusMessage *reply = NULL, *changed = NULL; + DBusError error; + int r; + + assert(connection); + assert(message); + + dbus_error_init(&error); + + if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetTimezone")) { + const char *z; + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_STRING, &z, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (!valid_timezone(z)) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + if (!streq_ptr(z, tz.zone)) { + char *t; + + r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-timezone", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + t = strdup(z); + if (!t) + goto oom; + + free(tz.zone); + tz.zone = t; + + /* 1. Write new configuration file */ + r = write_data_timezone(); + if (r < 0) { + log_error("Failed to set timezone: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + if (tz.local_rtc) { + struct timespec ts; + struct tm *tm; + + /* 2. Teach kernel new timezone */ + hwclock_apply_localtime_delta(NULL); + + /* 3. Sync RTC from system clock, with the new delta */ + assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); + assert_se(tm = localtime(&ts.tv_sec)); + hwclock_set_time(tm); + } + + log_info("Changed timezone to '%s'.", tz.zone); + + changed = bus_properties_changed_new( + "/org/freedesktop/timedate1", + "org.freedesktop.timedate1", + "Timezone\0"); + if (!changed) + goto oom; + } + + } else if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetLocalRTC")) { + dbus_bool_t lrtc; + dbus_bool_t fix_system; + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_BOOLEAN, &lrtc, + DBUS_TYPE_BOOLEAN, &fix_system, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (lrtc != tz.local_rtc) { + struct timespec ts; + + r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-local-rtc", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + tz.local_rtc = lrtc; + + /* 1. Write new configuration file */ + r = write_data_local_rtc(); + if (r < 0) { + log_error("Failed to set RTC to local/UTC: %s", strerror(-r)); + return bus_send_error_reply(connection, message, NULL, r); + } + + /* 2. Teach kernel new timezone */ + if (tz.local_rtc) + hwclock_apply_localtime_delta(NULL); + else + hwclock_reset_localtime_delta(); + + /* 3. Synchronize clocks */ + assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); + + if (fix_system) { + struct tm tm; + + /* Sync system clock from RTC; first, + * initialize the timezone fields of + * struct tm. */ + if (tz.local_rtc) + tm = *localtime(&ts.tv_sec); + else + tm = *gmtime(&ts.tv_sec); + + /* Override the main fields of + * struct tm, but not the timezone + * fields */ + if (hwclock_get_time(&tm) >= 0) { + + /* And set the system clock + * with this */ + if (tz.local_rtc) + ts.tv_sec = mktime(&tm); + else + ts.tv_sec = timegm(&tm); + + clock_settime(CLOCK_REALTIME, &ts); + } + + } else { + struct tm *tm; + + /* Sync RTC from system clock */ + if (tz.local_rtc) + tm = localtime(&ts.tv_sec); + else + tm = gmtime(&ts.tv_sec); + + hwclock_set_time(tm); + } + + log_info("RTC configured to %s time.", tz.local_rtc ? "local" : "UTC"); + + changed = bus_properties_changed_new( + "/org/freedesktop/timedate1", + "org.freedesktop.timedate1", + "LocalRTC\0"); + if (!changed) + goto oom; + } + + } else if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetTime")) { + int64_t utc; + dbus_bool_t relative; + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_INT64, &utc, + DBUS_TYPE_BOOLEAN, &relative, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (!relative && utc <= 0) + return bus_send_error_reply(connection, message, NULL, -EINVAL); + + if (!relative || utc != 0) { + struct timespec ts; + struct tm* tm; + + r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-time", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + if (relative) + timespec_store(&ts, now(CLOCK_REALTIME) + utc); + else + timespec_store(&ts, utc); + + /* Set system clock */ + if (clock_settime(CLOCK_REALTIME, &ts) < 0) { + log_error("Failed to set local time: %m"); + return bus_send_error_reply(connection, message, NULL, -errno); + } + + /* Sync down to RTC */ + if (tz.local_rtc) + tm = localtime(&ts.tv_sec); + else + tm = gmtime(&ts.tv_sec); + + hwclock_set_time(tm); + + log_info("Changed local time to %s", ctime(&ts.tv_sec)); + } + } else if (dbus_message_is_method_call(message, "org.freedesktop.timedate1", "SetNTP")) { + dbus_bool_t ntp; + dbus_bool_t interactive; + + if (!dbus_message_get_args( + message, + &error, + DBUS_TYPE_BOOLEAN, &ntp, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID)) + return bus_send_error_reply(connection, message, &error, -EINVAL); + + if (ntp != !!tz.use_ntp) { + + r = verify_polkit(connection, message, "org.freedesktop.timedate1.set-ntp", interactive, NULL, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + tz.use_ntp = !!ntp; + + r = enable_ntp(connection, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + r = start_ntp(connection, &error); + if (r < 0) + return bus_send_error_reply(connection, message, &error, r); + + log_info("Set NTP to %s", tz.use_ntp ? "enabled" : "disabled"); + + changed = bus_properties_changed_new( + "/org/freedesktop/timedate1", + "org.freedesktop.timedate1", + "NTP\0"); + if (!changed) + goto oom; + } + + } else + return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps); + + if (!(reply = dbus_message_new_method_return(message))) + goto oom; + + if (!dbus_connection_send(connection, reply, NULL)) + goto oom; + + dbus_message_unref(reply); + reply = NULL; + + if (changed) { + + if (!dbus_connection_send(connection, changed, NULL)) + goto oom; + + dbus_message_unref(changed); + } + + return DBUS_HANDLER_RESULT_HANDLED; + +oom: + if (reply) + dbus_message_unref(reply); + + if (changed) + dbus_message_unref(changed); + + dbus_error_free(&error); + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static int connect_bus(DBusConnection **_bus) { + static const DBusObjectPathVTable timedate_vtable = { + .message_function = timedate_message_handler + }; + DBusError error; + DBusConnection *bus = NULL; + int r; + + assert(_bus); + + dbus_error_init(&error); + + bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + if (!bus) { + log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error)); + r = -ECONNREFUSED; + goto fail; + } + + dbus_connection_set_exit_on_disconnect(bus, FALSE); + + if (!dbus_connection_register_object_path(bus, "/org/freedesktop/timedate1", &timedate_vtable, NULL) || + !dbus_connection_add_filter(bus, bus_exit_idle_filter, &remain_until, NULL)) { + log_error("Not enough memory"); + r = -ENOMEM; + goto fail; + } + + r = dbus_bus_request_name(bus, "org.freedesktop.timedate1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error); + if (dbus_error_is_set(&error)) { + log_error("Failed to register name on bus: %s", bus_error_message(&error)); + r = -EEXIST; + goto fail; + } + + if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + log_error("Failed to acquire name."); + r = -EEXIST; + goto fail; + } + + if (_bus) + *_bus = bus; + + return 0; + +fail: + dbus_connection_close(bus); + dbus_connection_unref(bus); + + dbus_error_free(&error); + + return r; +} + +int main(int argc, char *argv[]) { + int r; + DBusConnection *bus = NULL; + bool exiting = false; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argc == 2 && streq(argv[1], "--introspect")) { + fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE + "\n", stdout); + fputs(timedate_interface, stdout); + fputs("\n", stdout); + return 0; + } + + if (argc != 1) { + log_error("This program takes no arguments."); + r = -EINVAL; + goto finish; + } + + r = read_data(); + if (r < 0) { + log_error("Failed to read timezone data: %s", strerror(-r)); + goto finish; + } + + r = connect_bus(&bus); + if (r < 0) + goto finish; + + r = read_ntp(bus); + if (r < 0) { + log_error("Failed to determine whether NTP is enabled: %s", strerror(-r)); + goto finish; + } + + remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC; + for (;;) { + + if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC))) + break; + + if (!exiting && remain_until < now(CLOCK_MONOTONIC)) { + exiting = true; + bus_async_unregister_and_exit(bus, "org.freedesktop.hostname1"); + } + } + + r = 0; + +finish: + free_data(); + + if (bus) { + dbus_connection_flush(bus); + dbus_connection_close(bus); + dbus_connection_unref(bus); + } + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/timer.c b/src/timer.c new file mode 100644 index 0000000..e318fee --- /dev/null +++ b/src/timer.c @@ -0,0 +1,520 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "unit.h" +#include "unit-name.h" +#include "timer.h" +#include "dbus-timer.h" +#include "special.h" +#include "bus-errors.h" + +static const UnitActiveState state_translation_table[_TIMER_STATE_MAX] = { + [TIMER_DEAD] = UNIT_INACTIVE, + [TIMER_WAITING] = UNIT_ACTIVE, + [TIMER_RUNNING] = UNIT_ACTIVE, + [TIMER_ELAPSED] = UNIT_ACTIVE, + [TIMER_FAILED] = UNIT_FAILED +}; + +static void timer_init(Unit *u) { + Timer *t = TIMER(u); + + assert(u); + assert(u->load_state == UNIT_STUB); + + t->next_elapse = (usec_t) -1; +} + +static void timer_done(Unit *u) { + Timer *t = TIMER(u); + TimerValue *v; + + assert(t); + + while ((v = t->values)) { + LIST_REMOVE(TimerValue, value, t->values, v); + free(v); + } + + unit_unwatch_timer(u, &t->timer_watch); + + unit_ref_unset(&t->unit); +} + +static int timer_verify(Timer *t) { + assert(t); + + if (UNIT(t)->load_state != UNIT_LOADED) + return 0; + + if (!t->values) { + log_error("%s lacks value setting. Refusing.", UNIT(t)->id); + return -EINVAL; + } + + return 0; +} + +static int timer_add_default_dependencies(Timer *t) { + int r; + + assert(t); + + if (UNIT(t)->manager->running_as == MANAGER_SYSTEM) { + if ((r = unit_add_dependency_by_name(UNIT(t), UNIT_BEFORE, SPECIAL_BASIC_TARGET, NULL, true)) < 0) + return r; + + if ((r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true)) < 0) + return r; + } + + return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true); +} + +static int timer_load(Unit *u) { + Timer *t = TIMER(u); + int r; + + assert(u); + assert(u->load_state == UNIT_STUB); + + if ((r = unit_load_fragment_and_dropin(u)) < 0) + return r; + + if (u->load_state == UNIT_LOADED) { + + if (!UNIT_DEREF(t->unit)) { + Unit *x; + + r = unit_load_related_unit(u, ".service", &x); + if (r < 0) + return r; + + unit_ref_set(&t->unit, x); + } + + r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(t->unit), true); + if (r < 0) + return r; + + if (UNIT(t)->default_dependencies) + if ((r = timer_add_default_dependencies(t)) < 0) + return r; + } + + return timer_verify(t); +} + +static void timer_dump(Unit *u, FILE *f, const char *prefix) { + Timer *t = TIMER(u); + TimerValue *v; + char + timespan1[FORMAT_TIMESPAN_MAX]; + + fprintf(f, + "%sTimer State: %s\n" + "%sResult: %s\n" + "%sUnit: %s\n", + prefix, timer_state_to_string(t->state), + prefix, timer_result_to_string(t->result), + prefix, UNIT_DEREF(t->unit)->id); + + LIST_FOREACH(value, v, t->values) + fprintf(f, + "%s%s: %s\n", + prefix, + timer_base_to_string(v->base), + strna(format_timespan(timespan1, sizeof(timespan1), v->value))); +} + +static void timer_set_state(Timer *t, TimerState state) { + TimerState old_state; + assert(t); + + old_state = t->state; + t->state = state; + + if (state != TIMER_WAITING) + unit_unwatch_timer(UNIT(t), &t->timer_watch); + + if (state != old_state) + log_debug("%s changed %s -> %s", + UNIT(t)->id, + timer_state_to_string(old_state), + timer_state_to_string(state)); + + unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true); +} + +static void timer_enter_waiting(Timer *t, bool initial); + +static int timer_coldplug(Unit *u) { + Timer *t = TIMER(u); + + assert(t); + assert(t->state == TIMER_DEAD); + + if (t->deserialized_state != t->state) { + + if (t->deserialized_state == TIMER_WAITING) + timer_enter_waiting(t, false); + else + timer_set_state(t, t->deserialized_state); + } + + return 0; +} + +static void timer_enter_dead(Timer *t, TimerResult f) { + assert(t); + + if (f != TIMER_SUCCESS) + t->result = f; + + timer_set_state(t, t->result != TIMER_SUCCESS ? TIMER_FAILED : TIMER_DEAD); +} + +static void timer_enter_waiting(Timer *t, bool initial) { + TimerValue *v; + usec_t base = 0, delay, n; + bool found = false; + int r; + + n = now(CLOCK_MONOTONIC); + + LIST_FOREACH(value, v, t->values) { + + if (v->disabled) + continue; + + switch (v->base) { + + case TIMER_ACTIVE: + if (state_translation_table[t->state] == UNIT_ACTIVE) + base = UNIT(t)->inactive_exit_timestamp.monotonic; + else + base = n; + break; + + case TIMER_BOOT: + /* CLOCK_MONOTONIC equals the uptime on Linux */ + base = 0; + break; + + case TIMER_STARTUP: + base = UNIT(t)->manager->startup_timestamp.monotonic; + break; + + case TIMER_UNIT_ACTIVE: + + if (UNIT_DEREF(t->unit)->inactive_exit_timestamp.monotonic <= 0) + continue; + + base = UNIT_DEREF(t->unit)->inactive_exit_timestamp.monotonic; + break; + + case TIMER_UNIT_INACTIVE: + + if (UNIT_DEREF(t->unit)->inactive_enter_timestamp.monotonic <= 0) + continue; + + base = UNIT_DEREF(t->unit)->inactive_enter_timestamp.monotonic; + break; + + default: + assert_not_reached("Unknown timer base"); + } + + v->next_elapse = base + v->value; + + if (!initial && v->next_elapse < n) { + v->disabled = true; + continue; + } + + if (!found) + t->next_elapse = v->next_elapse; + else + t->next_elapse = MIN(t->next_elapse, v->next_elapse); + + found = true; + } + + if (!found) { + timer_set_state(t, TIMER_ELAPSED); + return; + } + + delay = n < t->next_elapse ? t->next_elapse - n : 0; + + if ((r = unit_watch_timer(UNIT(t), delay, &t->timer_watch)) < 0) + goto fail; + + timer_set_state(t, TIMER_WAITING); + return; + +fail: + log_warning("%s failed to enter waiting state: %s", UNIT(t)->id, strerror(-r)); + timer_enter_dead(t, TIMER_FAILURE_RESOURCES); +} + +static void timer_enter_running(Timer *t) { + DBusError error; + int r; + + assert(t); + dbus_error_init(&error); + + /* Don't start job if we are supposed to go down */ + if (UNIT(t)->job && UNIT(t)->job->type == JOB_STOP) + return; + + if ((r = manager_add_job(UNIT(t)->manager, JOB_START, UNIT_DEREF(t->unit), JOB_REPLACE, true, &error, NULL)) < 0) + goto fail; + + timer_set_state(t, TIMER_RUNNING); + return; + +fail: + log_warning("%s failed to queue unit startup job: %s", UNIT(t)->id, bus_error(&error, r)); + timer_enter_dead(t, TIMER_FAILURE_RESOURCES); + + dbus_error_free(&error); +} + +static int timer_start(Unit *u) { + Timer *t = TIMER(u); + + assert(t); + assert(t->state == TIMER_DEAD || t->state == TIMER_FAILED); + + if (UNIT_DEREF(t->unit)->load_state != UNIT_LOADED) + return -ENOENT; + + t->result = TIMER_SUCCESS; + timer_enter_waiting(t, true); + return 0; +} + +static int timer_stop(Unit *u) { + Timer *t = TIMER(u); + + assert(t); + assert(t->state == TIMER_WAITING || t->state == TIMER_RUNNING || t->state == TIMER_ELAPSED); + + timer_enter_dead(t, TIMER_SUCCESS); + return 0; +} + +static int timer_serialize(Unit *u, FILE *f, FDSet *fds) { + Timer *t = TIMER(u); + + assert(u); + assert(f); + assert(fds); + + unit_serialize_item(u, f, "state", timer_state_to_string(t->state)); + unit_serialize_item(u, f, "result", timer_result_to_string(t->result)); + + return 0; +} + +static int timer_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) { + Timer *t = TIMER(u); + + assert(u); + assert(key); + assert(value); + assert(fds); + + if (streq(key, "state")) { + TimerState state; + + if ((state = timer_state_from_string(value)) < 0) + log_debug("Failed to parse state value %s", value); + else + t->deserialized_state = state; + } else if (streq(key, "result")) { + TimerResult f; + + f = timer_result_from_string(value); + if (f < 0) + log_debug("Failed to parse result value %s", value); + else if (f != TIMER_SUCCESS) + t->result = f; + + } else + log_debug("Unknown serialization key '%s'", key); + + return 0; +} + +static UnitActiveState timer_active_state(Unit *u) { + assert(u); + + return state_translation_table[TIMER(u)->state]; +} + +static const char *timer_sub_state_to_string(Unit *u) { + assert(u); + + return timer_state_to_string(TIMER(u)->state); +} + +static void timer_timer_event(Unit *u, uint64_t elapsed, Watch *w) { + Timer *t = TIMER(u); + + assert(t); + assert(elapsed == 1); + + if (t->state != TIMER_WAITING) + return; + + log_debug("Timer elapsed on %s", u->id); + timer_enter_running(t); +} + +void timer_unit_notify(Unit *u, UnitActiveState new_state) { + Iterator i; + Unit *k; + + if (u->type == UNIT_TIMER) + return; + + SET_FOREACH(k, u->dependencies[UNIT_TRIGGERED_BY], i) { + Timer *t; + TimerValue *v; + + if (k->type != UNIT_TIMER) + continue; + + if (k->load_state != UNIT_LOADED) + continue; + + t = TIMER(k); + + /* Reenable all timers that depend on unit state */ + LIST_FOREACH(value, v, t->values) + if (v->base == TIMER_UNIT_ACTIVE || + v->base == TIMER_UNIT_INACTIVE) + v->disabled = false; + + switch (t->state) { + + case TIMER_WAITING: + case TIMER_ELAPSED: + + /* Recalculate sleep time */ + timer_enter_waiting(t, false); + break; + + case TIMER_RUNNING: + + if (UNIT_IS_INACTIVE_OR_FAILED(new_state)) { + log_debug("%s got notified about unit deactivation.", UNIT(t)->id); + timer_enter_waiting(t, false); + } + + break; + + case TIMER_DEAD: + case TIMER_FAILED: + break; + + default: + assert_not_reached("Unknown timer state"); + } + } +} + +static void timer_reset_failed(Unit *u) { + Timer *t = TIMER(u); + + assert(t); + + if (t->state == TIMER_FAILED) + timer_set_state(t, TIMER_DEAD); + + t->result = TIMER_SUCCESS; +} + +static const char* const timer_state_table[_TIMER_STATE_MAX] = { + [TIMER_DEAD] = "dead", + [TIMER_WAITING] = "waiting", + [TIMER_RUNNING] = "running", + [TIMER_ELAPSED] = "elapsed", + [TIMER_FAILED] = "failed" +}; + +DEFINE_STRING_TABLE_LOOKUP(timer_state, TimerState); + +static const char* const timer_base_table[_TIMER_BASE_MAX] = { + [TIMER_ACTIVE] = "OnActiveSec", + [TIMER_BOOT] = "OnBootSec", + [TIMER_STARTUP] = "OnStartupSec", + [TIMER_UNIT_ACTIVE] = "OnUnitActiveSec", + [TIMER_UNIT_INACTIVE] = "OnUnitInactiveSec" +}; + +DEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase); + +static const char* const timer_result_table[_TIMER_RESULT_MAX] = { + [TIMER_SUCCESS] = "success", + [TIMER_FAILURE_RESOURCES] = "resources" +}; + +DEFINE_STRING_TABLE_LOOKUP(timer_result, TimerResult); + +const UnitVTable timer_vtable = { + .suffix = ".timer", + .object_size = sizeof(Timer), + .sections = + "Unit\0" + "Timer\0" + "Install\0", + + .init = timer_init, + .done = timer_done, + .load = timer_load, + + .coldplug = timer_coldplug, + + .dump = timer_dump, + + .start = timer_start, + .stop = timer_stop, + + .serialize = timer_serialize, + .deserialize_item = timer_deserialize_item, + + .active_state = timer_active_state, + .sub_state_to_string = timer_sub_state_to_string, + + .timer_event = timer_timer_event, + + .reset_failed = timer_reset_failed, + + .bus_interface = "org.freedesktop.systemd1.Timer", + .bus_message_handler = bus_timer_message_handler, + .bus_invalidating_properties = bus_timer_invalidating_properties +}; diff --git a/src/timer.h b/src/timer.h new file mode 100644 index 0000000..f5c5c64 --- /dev/null +++ b/src/timer.h @@ -0,0 +1,93 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef footimerhfoo +#define footimerhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +typedef struct Timer Timer; + +#include "unit.h" + +typedef enum TimerState { + TIMER_DEAD, + TIMER_WAITING, + TIMER_RUNNING, + TIMER_ELAPSED, + TIMER_FAILED, + _TIMER_STATE_MAX, + _TIMER_STATE_INVALID = -1 +} TimerState; + +typedef enum TimerBase { + TIMER_ACTIVE, + TIMER_BOOT, + TIMER_STARTUP, + TIMER_UNIT_ACTIVE, + TIMER_UNIT_INACTIVE, + _TIMER_BASE_MAX, + _TIMER_BASE_INVALID = -1 +} TimerBase; + +typedef struct TimerValue { + usec_t value; + usec_t next_elapse; + + LIST_FIELDS(struct TimerValue, value); + + TimerBase base; + bool disabled; +} TimerValue; + +typedef enum TimerResult { + TIMER_SUCCESS, + TIMER_FAILURE_RESOURCES, + _TIMER_RESULT_MAX, + _TIMER_RESULT_INVALID = -1 +} TimerResult; + +struct Timer { + Unit meta; + + LIST_HEAD(TimerValue, values); + usec_t next_elapse; + + TimerState state, deserialized_state; + UnitRef unit; + + Watch timer_watch; + + TimerResult result; +}; + +void timer_unit_notify(Unit *u, UnitActiveState new_state); + +extern const UnitVTable timer_vtable; + +const char *timer_state_to_string(TimerState i); +TimerState timer_state_from_string(const char *s); + +const char *timer_base_to_string(TimerBase i); +TimerBase timer_base_from_string(const char *s); + +const char* timer_result_to_string(TimerResult i); +TimerResult timer_result_from_string(const char *s); + +#endif diff --git a/src/timestamp.c b/src/timestamp.c new file mode 100644 index 0000000..ce51429 --- /dev/null +++ b/src/timestamp.c @@ -0,0 +1,39 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#include "util.h" + +int main(int argc, char *argv[]) { + struct dual_timestamp t; + + /* This is mostly useful for stuff like init ram disk scripts + * which want to take a proper timestamp to do minimal bootup + * profiling. */ + + dual_timestamp_get(&t); + printf("%llu %llu\n", + (unsigned long long) t.realtime, + (unsigned long long) t.monotonic); + + return 0; +} diff --git a/src/tmpfiles.c b/src/tmpfiles.c new file mode 100644 index 0000000..8cbce12 --- /dev/null +++ b/src/tmpfiles.c @@ -0,0 +1,1314 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering, Kay Sievers + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "util.h" +#include "strv.h" +#include "label.h" +#include "set.h" + +/* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates + * them in the file system. This is intended to be used to create + * properly owned directories beneath /tmp, /var/tmp, /run, which are + * volatile and hence need to be recreated on bootup. */ + +typedef enum ItemType { + /* These ones take file names */ + CREATE_FILE = 'f', + TRUNCATE_FILE = 'F', + WRITE_FILE = 'w', + CREATE_DIRECTORY = 'd', + TRUNCATE_DIRECTORY = 'D', + CREATE_FIFO = 'p', + CREATE_SYMLINK = 'L', + CREATE_CHAR_DEVICE = 'c', + CREATE_BLOCK_DEVICE = 'b', + + /* These ones take globs */ + IGNORE_PATH = 'x', + REMOVE_PATH = 'r', + RECURSIVE_REMOVE_PATH = 'R', + RELABEL_PATH = 'z', + RECURSIVE_RELABEL_PATH = 'Z' +} ItemType; + +typedef struct Item { + ItemType type; + + char *path; + char *argument; + uid_t uid; + gid_t gid; + mode_t mode; + usec_t age; + + dev_t major_minor; + + bool uid_set:1; + bool gid_set:1; + bool mode_set:1; + bool age_set:1; +} Item; + +static Hashmap *items = NULL, *globs = NULL; +static Set *unix_sockets = NULL; + +static bool arg_create = false; +static bool arg_clean = false; +static bool arg_remove = false; + +static const char *arg_prefix = NULL; + +#define MAX_DEPTH 256 + +static bool needs_glob(ItemType t) { + return t == IGNORE_PATH || t == REMOVE_PATH || t == RECURSIVE_REMOVE_PATH || t == RELABEL_PATH || t == RECURSIVE_RELABEL_PATH; +} + +static struct Item* find_glob(Hashmap *h, const char *match) { + Item *j; + Iterator i; + + HASHMAP_FOREACH(j, h, i) + if (fnmatch(j->path, match, FNM_PATHNAME|FNM_PERIOD) == 0) + return j; + + return NULL; +} + +static void load_unix_sockets(void) { + FILE *f = NULL; + char line[LINE_MAX]; + + if (unix_sockets) + return; + + /* We maintain a cache of the sockets we found in + * /proc/net/unix to speed things up a little. */ + + unix_sockets = set_new(string_hash_func, string_compare_func); + if (!unix_sockets) + return; + + f = fopen("/proc/net/unix", "re"); + if (!f) + return; + + /* Skip header */ + if (!fgets(line, sizeof(line), f)) + goto fail; + + for (;;) { + char *p, *s; + int k; + + if (!fgets(line, sizeof(line), f)) + break; + + truncate_nl(line); + + p = strchr(line, ':'); + if (!p) + continue; + + if (strlen(p) < 37) + continue; + + p += 37; + p += strspn(p, WHITESPACE); + p += strcspn(p, WHITESPACE); /* skip one more word */ + p += strspn(p, WHITESPACE); + + if (*p != '/') + continue; + + s = strdup(p); + if (!s) + goto fail; + + path_kill_slashes(s); + + k = set_put(unix_sockets, s); + if (k < 0) { + free(s); + + if (k != -EEXIST) + goto fail; + } + } + + fclose(f); + return; + +fail: + set_free_free(unix_sockets); + unix_sockets = NULL; + + if (f) + fclose(f); +} + +static bool unix_socket_alive(const char *fn) { + assert(fn); + + load_unix_sockets(); + + if (unix_sockets) + return !!set_get(unix_sockets, (char*) fn); + + /* We don't know, so assume yes */ + return true; +} + +static int dir_cleanup( + const char *p, + DIR *d, + const struct stat *ds, + usec_t cutoff, + dev_t rootdev, + bool mountpoint, + int maxdepth) +{ + struct dirent *dent; + struct timespec times[2]; + bool deleted = false; + char *sub_path = NULL; + int r = 0; + + while ((dent = readdir(d))) { + struct stat s; + usec_t age; + + if (streq(dent->d_name, ".") || + streq(dent->d_name, "..")) + continue; + + if (fstatat(dirfd(d), dent->d_name, &s, AT_SYMLINK_NOFOLLOW) < 0) { + + if (errno != ENOENT) { + log_error("stat(%s/%s) failed: %m", p, dent->d_name); + r = -errno; + } + + continue; + } + + /* Stay on the same filesystem */ + if (s.st_dev != rootdev) + continue; + + /* Do not delete read-only files owned by root */ + if (s.st_uid == 0 && !(s.st_mode & S_IWUSR)) + continue; + + free(sub_path); + sub_path = NULL; + + if (asprintf(&sub_path, "%s/%s", p, dent->d_name) < 0) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + /* Is there an item configured for this path? */ + if (hashmap_get(items, sub_path)) + continue; + + if (find_glob(globs, sub_path)) + continue; + + if (S_ISDIR(s.st_mode)) { + + if (mountpoint && + streq(dent->d_name, "lost+found") && + s.st_uid == 0) + continue; + + if (maxdepth <= 0) + log_warning("Reached max depth on %s.", sub_path); + else { + DIR *sub_dir; + int q; + + sub_dir = xopendirat(dirfd(d), dent->d_name, O_NOFOLLOW); + if (sub_dir == NULL) { + if (errno != ENOENT) { + log_error("opendir(%s/%s) failed: %m", p, dent->d_name); + r = -errno; + } + + continue; + } + + q = dir_cleanup(sub_path, sub_dir, &s, cutoff, rootdev, false, maxdepth-1); + closedir(sub_dir); + + if (q < 0) + r = q; + } + + /* Ignore ctime, we change it when deleting */ + age = MAX(timespec_load(&s.st_mtim), + timespec_load(&s.st_atim)); + if (age >= cutoff) + continue; + + log_debug("rmdir '%s'\n", sub_path); + + if (unlinkat(dirfd(d), dent->d_name, AT_REMOVEDIR) < 0) { + if (errno != ENOENT && errno != ENOTEMPTY) { + log_error("rmdir(%s): %m", sub_path); + r = -errno; + } + } + + } else { + /* Skip files for which the sticky bit is + * set. These are semantics we define, and are + * unknown elsewhere. See XDG_RUNTIME_DIR + * specification for details. */ + if (s.st_mode & S_ISVTX) + continue; + + if (mountpoint && S_ISREG(s.st_mode)) { + if (streq(dent->d_name, ".journal") && + s.st_uid == 0) + continue; + + if (streq(dent->d_name, "aquota.user") || + streq(dent->d_name, "aquota.group")) + continue; + } + + /* Ignore sockets that are listed in /proc/net/unix */ + if (S_ISSOCK(s.st_mode) && unix_socket_alive(sub_path)) + continue; + + /* Ignore device nodes */ + if (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode)) + continue; + + age = MAX3(timespec_load(&s.st_mtim), + timespec_load(&s.st_atim), + timespec_load(&s.st_ctim)); + + if (age >= cutoff) + continue; + + log_debug("unlink '%s'\n", sub_path); + + if (unlinkat(dirfd(d), dent->d_name, 0) < 0) { + if (errno != ENOENT) { + log_error("unlink(%s): %m", sub_path); + r = -errno; + } + } + + deleted = true; + } + } + +finish: + if (deleted) { + /* Restore original directory timestamps */ + times[0] = ds->st_atim; + times[1] = ds->st_mtim; + + if (futimens(dirfd(d), times) < 0) + log_error("utimensat(%s): %m", p); + } + + free(sub_path); + + return r; +} + +static int clean_item(Item *i) { + DIR *d; + struct stat s, ps; + bool mountpoint; + int r; + usec_t cutoff, n; + + assert(i); + + if (i->type != CREATE_DIRECTORY && + i->type != TRUNCATE_DIRECTORY && + i->type != IGNORE_PATH) + return 0; + + if (!i->age_set || i->age <= 0) + return 0; + + n = now(CLOCK_REALTIME); + if (n < i->age) + return 0; + + cutoff = n - i->age; + + d = opendir(i->path); + if (!d) { + if (errno == ENOENT) + return 0; + + log_error("Failed to open directory %s: %m", i->path); + return -errno; + } + + if (fstat(dirfd(d), &s) < 0) { + log_error("stat(%s) failed: %m", i->path); + r = -errno; + goto finish; + } + + if (!S_ISDIR(s.st_mode)) { + log_error("%s is not a directory.", i->path); + r = -ENOTDIR; + goto finish; + } + + if (fstatat(dirfd(d), "..", &ps, AT_SYMLINK_NOFOLLOW) != 0) { + log_error("stat(%s/..) failed: %m", i->path); + r = -errno; + goto finish; + } + + mountpoint = s.st_dev != ps.st_dev || + (s.st_dev == ps.st_dev && s.st_ino == ps.st_ino); + + r = dir_cleanup(i->path, d, &s, cutoff, s.st_dev, mountpoint, MAX_DEPTH); + +finish: + if (d) + closedir(d); + + return r; +} + +static int item_set_perms(Item *i, const char *path) { + /* not using i->path directly because it may be a glob */ + if (i->mode_set) + if (chmod(path, i->mode) < 0) { + log_error("chmod(%s) failed: %m", path); + return -errno; + } + + if (i->uid_set || i->gid_set) + if (chown(path, + i->uid_set ? i->uid : (uid_t) -1, + i->gid_set ? i->gid : (gid_t) -1) < 0) { + + log_error("chown(%s) failed: %m", path); + return -errno; + } + + return label_fix(path, false); +} + +static int recursive_relabel_children(Item *i, const char *path) { + DIR *d; + int ret = 0; + + /* This returns the first error we run into, but nevertheless + * tries to go on */ + + d = opendir(path); + if (!d) + return errno == ENOENT ? 0 : -errno; + + for (;;) { + struct dirent buf, *de; + bool is_dir; + int r; + char *entry_path; + + r = readdir_r(d, &buf, &de); + if (r != 0) { + if (ret == 0) + ret = -r; + break; + } + + if (!de) + break; + + if (streq(de->d_name, ".") || streq(de->d_name, "..")) + continue; + + if (asprintf(&entry_path, "%s/%s", path, de->d_name) < 0) { + if (ret == 0) + ret = -ENOMEM; + continue; + } + + if (de->d_type == DT_UNKNOWN) { + struct stat st; + + if (lstat(entry_path, &st) < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + free(entry_path); + continue; + } + + is_dir = S_ISDIR(st.st_mode); + + } else + is_dir = de->d_type == DT_DIR; + + r = item_set_perms(i, entry_path); + if (r < 0) { + if (ret == 0 && r != -ENOENT) + ret = r; + free(entry_path); + continue; + } + + if (is_dir) { + r = recursive_relabel_children(i, entry_path); + if (r < 0 && ret == 0) + ret = r; + } + + free(entry_path); + } + + closedir(d); + + return ret; +} + +static int recursive_relabel(Item *i, const char *path) { + int r; + struct stat st; + + r = item_set_perms(i, path); + if (r < 0) + return r; + + if (lstat(path, &st) < 0) + return -errno; + + if (S_ISDIR(st.st_mode)) + r = recursive_relabel_children(i, path); + + return r; +} + +static int glob_item(Item *i, int (*action)(Item *, const char *)) { + int r = 0, k; + glob_t g; + char **fn; + + zero(g); + + errno = 0; + if ((k = glob(i->path, GLOB_NOSORT|GLOB_BRACE, NULL, &g)) != 0) { + + if (k != GLOB_NOMATCH) { + if (errno != 0) + errno = EIO; + + log_error("glob(%s) failed: %m", i->path); + return -errno; + } + } + + STRV_FOREACH(fn, g.gl_pathv) + if ((k = action(i, *fn)) < 0) + r = k; + + globfree(&g); + return r; +} + +static int create_item(Item *i) { + int r; + mode_t u; + struct stat st; + + assert(i); + + switch (i->type) { + + case IGNORE_PATH: + case REMOVE_PATH: + case RECURSIVE_REMOVE_PATH: + return 0; + + case CREATE_FILE: + case TRUNCATE_FILE: + case WRITE_FILE: { + int fd, flags; + + flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND : + i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC : 0; + + u = umask(0); + fd = open(i->path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, i->mode); + umask(u); + + if (fd < 0) { + if (i->type == WRITE_FILE && errno == ENOENT) + break; + + log_error("Failed to create file %s: %m", i->path); + return -errno; + } + + if (i->argument) { + ssize_t n; + size_t l; + struct iovec iovec[2]; + static const char new_line = '\n'; + + l = strlen(i->argument); + + zero(iovec); + iovec[0].iov_base = i->argument; + iovec[0].iov_len = l; + + iovec[1].iov_base = (void*) &new_line; + iovec[1].iov_len = 1; + + n = writev(fd, iovec, 2); + if (n < 0 || (size_t) n != l+1) { + log_error("Failed to write file %s: %s", i->path, n < 0 ? strerror(-n) : "Short"); + close_nointr_nofail(fd); + return n < 0 ? n : -EIO; + } + } + + close_nointr_nofail(fd); + + if (stat(i->path, &st) < 0) { + log_error("stat(%s) failed: %m", i->path); + return -errno; + } + + if (!S_ISREG(st.st_mode)) { + log_error("%s is not a file.", i->path); + return -EEXIST; + } + + r = item_set_perms(i, i->path); + if (r < 0) + return r; + + break; + } + + case TRUNCATE_DIRECTORY: + case CREATE_DIRECTORY: + + u = umask(0); + mkdir_parents(i->path, 0755); + r = mkdir(i->path, i->mode); + umask(u); + + if (r < 0 && errno != EEXIST) { + log_error("Failed to create directory %s: %m", i->path); + return -errno; + } + + if (stat(i->path, &st) < 0) { + log_error("stat(%s) failed: %m", i->path); + return -errno; + } + + if (!S_ISDIR(st.st_mode)) { + log_error("%s is not a directory.", i->path); + return -EEXIST; + } + + r = item_set_perms(i, i->path); + if (r < 0) + return r; + + break; + + case CREATE_FIFO: + + u = umask(0); + r = mkfifo(i->path, i->mode); + umask(u); + + if (r < 0 && errno != EEXIST) { + log_error("Failed to create fifo %s: %m", i->path); + return -errno; + } + + if (stat(i->path, &st) < 0) { + log_error("stat(%s) failed: %m", i->path); + return -errno; + } + + if (!S_ISFIFO(st.st_mode)) { + log_error("%s is not a fifo.", i->path); + return -EEXIST; + } + + r = item_set_perms(i, i->path); + if (r < 0) + return r; + + break; + + case CREATE_SYMLINK: { + char *x; + + r = symlink(i->argument, i->path); + if (r < 0 && errno != EEXIST) { + log_error("symlink(%s, %s) failed: %m", i->argument, i->path); + return -errno; + } + + r = readlink_malloc(i->path, &x); + if (r < 0) { + log_error("readlink(%s) failed: %s", i->path, strerror(-r)); + return -errno; + } + + if (!streq(i->argument, x)) { + free(x); + log_error("%s is not the right symlinks.", i->path); + return -EEXIST; + } + + free(x); + break; + } + + case CREATE_BLOCK_DEVICE: + case CREATE_CHAR_DEVICE: { + + u = umask(0); + r = mknod(i->path, i->mode | (i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR), i->major_minor); + umask(u); + + if (r < 0 && errno != EEXIST) { + log_error("Failed to create device node %s: %m", i->path); + return -errno; + } + + if (stat(i->path, &st) < 0) { + log_error("stat(%s) failed: %m", i->path); + return -errno; + } + + if (i->type == CREATE_BLOCK_DEVICE ? !S_ISBLK(st.st_mode) : !S_ISCHR(st.st_mode)) { + log_error("%s is not a device node.", i->path); + return -EEXIST; + } + + r = item_set_perms(i, i->path); + if (r < 0) + return r; + + break; + } + + case RELABEL_PATH: + + r = glob_item(i, item_set_perms); + if (r < 0) + return 0; + break; + + case RECURSIVE_RELABEL_PATH: + + r = glob_item(i, recursive_relabel); + if (r < 0) + return r; + } + + log_debug("%s created successfully.", i->path); + + return 0; +} + +static int remove_item_instance(Item *i, const char *instance) { + int r; + + assert(i); + + switch (i->type) { + + case CREATE_FILE: + case TRUNCATE_FILE: + case CREATE_DIRECTORY: + case CREATE_FIFO: + case CREATE_SYMLINK: + case CREATE_BLOCK_DEVICE: + case CREATE_CHAR_DEVICE: + case IGNORE_PATH: + case RELABEL_PATH: + case RECURSIVE_RELABEL_PATH: + case WRITE_FILE: + break; + + case REMOVE_PATH: + if (remove(instance) < 0 && errno != ENOENT) { + log_error("remove(%s): %m", instance); + return -errno; + } + + break; + + case TRUNCATE_DIRECTORY: + case RECURSIVE_REMOVE_PATH: + r = rm_rf(instance, false, i->type == RECURSIVE_REMOVE_PATH, false); + if (r < 0 && r != -ENOENT) { + log_error("rm_rf(%s): %s", instance, strerror(-r)); + return r; + } + + break; + } + + return 0; +} + +static int remove_item(Item *i) { + int r = 0; + + assert(i); + + switch (i->type) { + + case CREATE_FILE: + case TRUNCATE_FILE: + case CREATE_DIRECTORY: + case CREATE_FIFO: + case CREATE_SYMLINK: + case CREATE_CHAR_DEVICE: + case CREATE_BLOCK_DEVICE: + case IGNORE_PATH: + case RELABEL_PATH: + case RECURSIVE_RELABEL_PATH: + case WRITE_FILE: + break; + + case REMOVE_PATH: + case TRUNCATE_DIRECTORY: + case RECURSIVE_REMOVE_PATH: + r = glob_item(i, remove_item_instance); + break; + } + + return r; +} + +static int process_item(Item *i) { + int r, q, p; + + assert(i); + + r = arg_create ? create_item(i) : 0; + q = arg_remove ? remove_item(i) : 0; + p = arg_clean ? clean_item(i) : 0; + + if (r < 0) + return r; + + if (q < 0) + return q; + + return p; +} + +static void item_free(Item *i) { + assert(i); + + free(i->path); + free(i->argument); + free(i); +} + +static bool item_equal(Item *a, Item *b) { + assert(a); + assert(b); + + if (!streq_ptr(a->path, b->path)) + return false; + + if (a->type != b->type) + return false; + + if (a->uid_set != b->uid_set || + (a->uid_set && a->uid != b->uid)) + return false; + + if (a->gid_set != b->gid_set || + (a->gid_set && a->gid != b->gid)) + return false; + + if (a->mode_set != b->mode_set || + (a->mode_set && a->mode != b->mode)) + return false; + + if (a->age_set != b->age_set || + (a->age_set && a->age != b->age)) + return false; + + if ((a->type == CREATE_FILE || + a->type == TRUNCATE_FILE || + a->type == WRITE_FILE || + a->type == CREATE_SYMLINK) && + !streq_ptr(a->argument, b->argument)) + return false; + + if ((a->type == CREATE_CHAR_DEVICE || + a->type == CREATE_BLOCK_DEVICE) && + a->major_minor != b->major_minor) + return false; + + return true; +} + +static int parse_line(const char *fname, unsigned line, const char *buffer) { + Item *i, *existing; + char *mode = NULL, *user = NULL, *group = NULL, *age = NULL; + char type; + Hashmap *h; + int r, n = -1; + + assert(fname); + assert(line >= 1); + assert(buffer); + + i = new0(Item, 1); + if (!i) { + log_error("Out of memory"); + return -ENOMEM; + } + + if (sscanf(buffer, + "%c " + "%ms " + "%ms " + "%ms " + "%ms " + "%ms " + "%n", + &type, + &i->path, + &mode, + &user, + &group, + &age, + &n) < 2) { + log_error("[%s:%u] Syntax error.", fname, line); + r = -EIO; + goto finish; + } + + if (n >= 0) { + n += strspn(buffer+n, WHITESPACE); + if (buffer[n] != 0 && (buffer[n] != '-' || buffer[n+1] != 0)) { + i->argument = unquote(buffer+n, "\""); + if (!i->argument) { + log_error("Out of memory"); + return -ENOMEM; + } + } + } + + switch(type) { + + case CREATE_FILE: + case TRUNCATE_FILE: + case CREATE_DIRECTORY: + case TRUNCATE_DIRECTORY: + case CREATE_FIFO: + case IGNORE_PATH: + case REMOVE_PATH: + case RECURSIVE_REMOVE_PATH: + case RELABEL_PATH: + case RECURSIVE_RELABEL_PATH: + break; + + case CREATE_SYMLINK: + if (!i->argument) { + log_error("[%s:%u] Symlink file requires argument.", fname, line); + r = -EBADMSG; + goto finish; + } + break; + + case WRITE_FILE: + if (!i->argument) { + log_error("[%s:%u] Write file requires argument.", fname, line); + r = -EBADMSG; + goto finish; + } + break; + + case CREATE_CHAR_DEVICE: + case CREATE_BLOCK_DEVICE: { + unsigned major, minor; + + if (!i->argument) { + log_error("[%s:%u] Device file requires argument.", fname, line); + r = -EBADMSG; + goto finish; + } + + if (sscanf(i->argument, "%u:%u", &major, &minor) != 2) { + log_error("[%s:%u] Can't parse device file major/minor '%s'.", fname, line, i->argument); + r = -EBADMSG; + goto finish; + } + + i->major_minor = makedev(major, minor); + break; + } + + default: + log_error("[%s:%u] Unknown file type '%c'.", fname, line, type); + r = -EBADMSG; + goto finish; + } + + i->type = type; + + if (!path_is_absolute(i->path)) { + log_error("[%s:%u] Path '%s' not absolute.", fname, line, i->path); + r = -EBADMSG; + goto finish; + } + + path_kill_slashes(i->path); + + if (arg_prefix && !path_startswith(i->path, arg_prefix)) { + r = 0; + goto finish; + } + + if (user && !streq(user, "-")) { + const char *u = user; + + r = get_user_creds(&u, &i->uid, NULL, NULL); + if (r < 0) { + log_error("[%s:%u] Unknown user '%s'.", fname, line, user); + goto finish; + } + + i->uid_set = true; + } + + if (group && !streq(group, "-")) { + const char *g = group; + + r = get_group_creds(&g, &i->gid); + if (r < 0) { + log_error("[%s:%u] Unknown group '%s'.", fname, line, group); + goto finish; + } + + i->gid_set = true; + } + + if (mode && !streq(mode, "-")) { + unsigned m; + + if (sscanf(mode, "%o", &m) != 1) { + log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode); + r = -ENOENT; + goto finish; + } + + i->mode = m; + i->mode_set = true; + } else + i->mode = + i->type == CREATE_DIRECTORY || + i->type == TRUNCATE_DIRECTORY ? 0755 : 0644; + + if (age && !streq(age, "-")) { + if (parse_usec(age, &i->age) < 0) { + log_error("[%s:%u] Invalid age '%s'.", fname, line, age); + r = -EBADMSG; + goto finish; + } + + i->age_set = true; + } + + h = needs_glob(i->type) ? globs : items; + + existing = hashmap_get(h, i->path); + if (existing) { + + /* Two identical items are fine */ + if (!item_equal(existing, i)) + log_warning("Two or more conflicting lines for %s configured, ignoring.", i->path); + + r = 0; + goto finish; + } + + r = hashmap_put(h, i->path, i); + if (r < 0) { + log_error("Failed to insert item %s: %s", i->path, strerror(-r)); + goto finish; + } + + i = NULL; + r = 0; + +finish: + free(user); + free(group); + free(mode); + free(age); + + if (i) + item_free(i); + + return r; +} + +static int help(void) { + + printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n" + "Creates, deletes and cleans up volatile and temporary files and directories.\n\n" + " -h --help Show this help\n" + " --create Create marked files/directories\n" + " --clean Clean up marked directories\n" + " --remove Remove marked files/directories\n" + " --prefix=PATH Only apply rules that apply to paths with the specified prefix\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_CREATE, + ARG_CLEAN, + ARG_REMOVE, + ARG_PREFIX + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "create", no_argument, NULL, ARG_CREATE }, + { "clean", no_argument, NULL, ARG_CLEAN }, + { "remove", no_argument, NULL, ARG_REMOVE }, + { "prefix", required_argument, NULL, ARG_PREFIX }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_CREATE: + arg_create = true; + break; + + case ARG_CLEAN: + arg_clean = true; + break; + + case ARG_REMOVE: + arg_remove = true; + break; + + case ARG_PREFIX: + arg_prefix = optarg; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (!arg_clean && !arg_create && !arg_remove) { + log_error("You need to specify at least one of --clean, --create or --remove."); + return -EINVAL; + } + + return 1; +} + +static int read_config_file(const char *fn, bool ignore_enoent) { + FILE *f; + unsigned v = 0; + int r = 0; + + assert(fn); + + f = fopen(fn, "re"); + if (!f) { + + if (ignore_enoent && errno == ENOENT) + return 0; + + log_error("Failed to open %s: %m", fn); + return -errno; + } + + log_debug("apply: %s\n", fn); + for (;;) { + char line[LINE_MAX], *l; + int k; + + if (!(fgets(line, sizeof(line), f))) + break; + + v++; + + l = strstrip(line); + if (*l == '#' || *l == 0) + continue; + + if ((k = parse_line(fn, v, l)) < 0) + if (r == 0) + r = k; + } + + if (ferror(f)) { + log_error("Failed to read from file %s: %m", fn); + if (r == 0) + r = -EIO; + } + + fclose(f); + + return r; +} + +int main(int argc, char *argv[]) { + int r; + Item *i; + Iterator iterator; + + r = parse_argv(argc, argv); + if (r <= 0) + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + label_init(); + + items = hashmap_new(string_hash_func, string_compare_func); + globs = hashmap_new(string_hash_func, string_compare_func); + + if (!items || !globs) { + log_error("Out of memory"); + r = EXIT_FAILURE; + goto finish; + } + + r = EXIT_SUCCESS; + + if (optind < argc) { + int j; + + for (j = optind; j < argc; j++) + if (read_config_file(argv[j], false) < 0) + r = EXIT_FAILURE; + + } else { + char **files, **f; + + r = conf_files_list(&files, ".conf", + "/run/tmpfiles.d", + "/etc/tmpfiles.d", + "/usr/local/lib/tmpfiles.d", + "/usr/lib/tmpfiles.d", + NULL); + if (r < 0) { + r = EXIT_FAILURE; + log_error("Failed to enumerate tmpfiles.d files: %s", strerror(-r)); + goto finish; + } + + STRV_FOREACH(f, files) { + if (read_config_file(*f, true) < 0) + r = EXIT_FAILURE; + } + + strv_free(files); + } + + HASHMAP_FOREACH(i, globs, iterator) + process_item(i); + + HASHMAP_FOREACH(i, items, iterator) + process_item(i); + +finish: + while ((i = hashmap_steal_first(items))) + item_free(i); + + while ((i = hashmap_steal_first(globs))) + item_free(i); + + hashmap_free(items); + hashmap_free(globs); + + set_free_free(unix_sockets); + + label_finish(); + + return r; +} diff --git a/src/tty-ask-password-agent.c b/src/tty-ask-password-agent.c new file mode 100644 index 0000000..13481b2 --- /dev/null +++ b/src/tty-ask-password-agent.c @@ -0,0 +1,753 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "conf-parser.h" +#include "utmp-wtmp.h" +#include "socket-util.h" +#include "ask-password-api.h" +#include "strv.h" + +static enum { + ACTION_LIST, + ACTION_QUERY, + ACTION_WATCH, + ACTION_WALL +} arg_action = ACTION_QUERY; + +static bool arg_plymouth = false; +static bool arg_console = false; + +static int ask_password_plymouth( + const char *message, + usec_t until, + const char *flag_file, + bool accept_cached, + char ***_passphrases) { + + int fd = -1, notify = -1; + union sockaddr_union sa; + char *packet = NULL; + ssize_t k; + int r, n; + struct pollfd pollfd[2]; + char buffer[LINE_MAX]; + size_t p = 0; + enum { + POLL_SOCKET, + POLL_INOTIFY + }; + + assert(_passphrases); + + if (flag_file) { + if ((notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) { + r = -errno; + goto finish; + } + + if (inotify_add_watch(notify, flag_file, IN_ATTRIB /* for the link count */) < 0) { + r = -errno; + goto finish; + } + } + + if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) { + r = -errno; + goto finish; + } + + zero(sa); + sa.sa.sa_family = AF_UNIX; + strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1); + if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) { + log_error("Failed to connect to Plymouth: %m"); + r = -errno; + goto finish; + } + + if (accept_cached) { + packet = strdup("c"); + n = 1; + } else + asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n); + + if (!packet) { + r = -ENOMEM; + goto finish; + } + + if ((k = loop_write(fd, packet, n+1, true)) != n+1) { + r = k < 0 ? (int) k : -EIO; + goto finish; + } + + zero(pollfd); + pollfd[POLL_SOCKET].fd = fd; + pollfd[POLL_SOCKET].events = POLLIN; + pollfd[POLL_INOTIFY].fd = notify; + pollfd[POLL_INOTIFY].events = POLLIN; + + for (;;) { + int sleep_for = -1, j; + + if (until > 0) { + usec_t y; + + y = now(CLOCK_MONOTONIC); + + if (y > until) { + r = -ETIME; + goto finish; + } + + sleep_for = (int) ((until - y) / USEC_PER_MSEC); + } + + if (flag_file) + if (access(flag_file, F_OK) < 0) { + r = -errno; + goto finish; + } + + if ((j = poll(pollfd, notify > 0 ? 2 : 1, sleep_for)) < 0) { + + if (errno == EINTR) + continue; + + r = -errno; + goto finish; + } else if (j == 0) { + r = -ETIME; + goto finish; + } + + if (notify > 0 && pollfd[POLL_INOTIFY].revents != 0) + flush_fd(notify); + + if (pollfd[POLL_SOCKET].revents == 0) + continue; + + if ((k = read(fd, buffer + p, sizeof(buffer) - p)) <= 0) { + r = k < 0 ? -errno : -EIO; + goto finish; + } + + p += k; + + if (p < 1) + continue; + + if (buffer[0] == 5) { + + if (accept_cached) { + /* Hmm, first try with cached + * passwords failed, so let's retry + * with a normal password request */ + free(packet); + packet = NULL; + + if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) { + r = -ENOMEM; + goto finish; + } + + if ((k = loop_write(fd, packet, n+1, true)) != n+1) { + r = k < 0 ? (int) k : -EIO; + goto finish; + } + + accept_cached = false; + p = 0; + continue; + } + + /* No password, because UI not shown */ + r = -ENOENT; + goto finish; + + } else if (buffer[0] == 2 || buffer[0] == 9) { + uint32_t size; + char **l; + + /* One ore more answers */ + if (p < 5) + continue; + + memcpy(&size, buffer+1, sizeof(size)); + size = le32toh(size); + if (size+5 > sizeof(buffer)) { + r = -EIO; + goto finish; + } + + if (p-5 < size) + continue; + + if (!(l = strv_parse_nulstr(buffer + 5, size))) { + r = -ENOMEM; + goto finish; + } + + *_passphrases = l; + break; + + } else { + /* Unknown packet */ + r = -EIO; + goto finish; + } + } + + r = 0; + +finish: + if (notify >= 0) + close_nointr_nofail(notify); + + if (fd >= 0) + close_nointr_nofail(fd); + + free(packet); + + return r; +} + +static int parse_password(const char *filename, char **wall) { + char *socket_name = NULL, *message = NULL, *packet = NULL; + uint64_t not_after = 0; + unsigned pid = 0; + int socket_fd = -1; + bool accept_cached = false; + + const ConfigTableItem items[] = { + { "Ask", "Socket", config_parse_string, 0, &socket_name }, + { "Ask", "NotAfter", config_parse_uint64, 0, ¬_after }, + { "Ask", "Message", config_parse_string, 0, &message }, + { "Ask", "PID", config_parse_unsigned, 0, &pid }, + { "Ask", "AcceptCached", config_parse_bool, 0, &accept_cached }, + { NULL, NULL, NULL, 0, NULL } + }; + + FILE *f; + int r; + + assert(filename); + + f = fopen(filename, "re"); + if (!f) { + if (errno == ENOENT) + return 0; + + log_error("open(%s): %m", filename); + return -errno; + } + + r = config_parse(filename, f, NULL, config_item_table_lookup, (void*) items, true, NULL); + if (r < 0) { + log_error("Failed to parse password file %s: %s", filename, strerror(-r)); + goto finish; + } + + if (!socket_name) { + log_error("Invalid password file %s", filename); + r = -EBADMSG; + goto finish; + } + + if (not_after > 0) { + if (now(CLOCK_MONOTONIC) > not_after) { + r = 0; + goto finish; + } + } + + if (pid > 0 && + kill(pid, 0) < 0 && + errno == ESRCH) { + r = 0; + goto finish; + } + + if (arg_action == ACTION_LIST) + printf("'%s' (PID %u)\n", message, pid); + else if (arg_action == ACTION_WALL) { + char *_wall; + + if (asprintf(&_wall, + "%s%sPassword entry required for \'%s\' (PID %u).\r\n" + "Please enter password with the systemd-tty-ask-password-agent tool!", + *wall ? *wall : "", + *wall ? "\r\n\r\n" : "", + message, + pid) < 0) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + free(*wall); + *wall = _wall; + } else { + union { + struct sockaddr sa; + struct sockaddr_un un; + } sa; + size_t packet_length = 0; + + assert(arg_action == ACTION_QUERY || + arg_action == ACTION_WATCH); + + if (access(socket_name, W_OK) < 0) { + + if (arg_action == ACTION_QUERY) + log_info("Not querying '%s' (PID %u), lacking privileges.", message, pid); + + r = 0; + goto finish; + } + + if (arg_plymouth) { + char **passwords = NULL; + + if ((r = ask_password_plymouth(message, not_after, filename, accept_cached, &passwords)) >= 0) { + char **p; + + packet_length = 1; + STRV_FOREACH(p, passwords) + packet_length += strlen(*p) + 1; + + if (!(packet = new(char, packet_length))) + r = -ENOMEM; + else { + char *d; + + packet[0] = '+'; + d = packet+1; + + STRV_FOREACH(p, passwords) + d = stpcpy(d, *p) + 1; + } + } + + } else { + int tty_fd = -1; + char *password; + + if (arg_console) + if ((tty_fd = acquire_terminal("/dev/console", false, false, false)) < 0) { + r = tty_fd; + goto finish; + } + + r = ask_password_tty(message, not_after, filename, &password); + + if (arg_console) { + close_nointr_nofail(tty_fd); + release_terminal(); + } + + if (r >= 0) { + packet_length = 1+strlen(password)+1; + if (!(packet = new(char, packet_length))) + r = -ENOMEM; + else { + packet[0] = '+'; + strcpy(packet+1, password); + } + + free(password); + } + } + + if (r == -ETIME || r == -ENOENT) { + /* If the query went away, that's OK */ + r = 0; + goto finish; + } + + if (r < 0) { + log_error("Failed to query password: %s", strerror(-r)); + goto finish; + } + + if ((socket_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) { + log_error("socket(): %m"); + r = -errno; + goto finish; + } + + zero(sa); + sa.un.sun_family = AF_UNIX; + strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path)); + + if (sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0) { + log_error("Failed to send: %m"); + r = -errno; + goto finish; + } + } + +finish: + fclose(f); + + if (socket_fd >= 0) + close_nointr_nofail(socket_fd); + + free(packet); + free(socket_name); + free(message); + + return r; +} + +static int wall_tty_block(void) { + char *p; + int fd, r; + dev_t devnr; + + r = get_ctty_devnr(0, &devnr); + if (r < 0) + return -r; + + if (asprintf(&p, "/run/systemd/ask-password-block/%u:%u", major(devnr), minor(devnr)) < 0) + return -ENOMEM; + + mkdir_parents(p, 0700); + mkfifo(p, 0600); + + fd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + free(p); + + if (fd < 0) + return -errno; + + return fd; +} + +static bool wall_tty_match(const char *path) { + int fd, k; + char *p; + struct stat st; + + if (path_is_absolute(path)) + k = lstat(path, &st); + else { + if (asprintf(&p, "/dev/%s", path) < 0) + return true; + + k = lstat(p, &st); + free(p); + } + + if (k < 0) + return true; + + if (!S_ISCHR(st.st_mode)) + return true; + + /* We use named pipes to ensure that wall messages suggesting + * password entry are not printed over password prompts + * already shown. We use the fact here that opening a pipe in + * non-blocking mode for write-only will succeed only if + * there's some writer behind it. Using pipes has the + * advantage that the block will automatically go away if the + * process dies. */ + + if (asprintf(&p, "/run/systemd/ask-password-block/%u:%u", major(st.st_rdev), minor(st.st_rdev)) < 0) + return true; + + fd = open(p, O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + free(p); + + if (fd < 0) + return true; + + /* What, we managed to open the pipe? Then this tty is filtered. */ + close_nointr_nofail(fd); + return false; +} + +static int show_passwords(void) { + DIR *d; + struct dirent *de; + int r = 0; + + if (!(d = opendir("/run/systemd/ask-password"))) { + if (errno == ENOENT) + return 0; + + log_error("opendir(): %m"); + return -errno; + } + + while ((de = readdir(d))) { + char *p; + int q; + char *wall; + + /* We only support /dev on tmpfs, hence we can rely on + * d_type to be reliable */ + + if (de->d_type != DT_REG) + continue; + + if (ignore_file(de->d_name)) + continue; + + if (!startswith(de->d_name, "ask.")) + continue; + + if (!(p = strappend("/run/systemd/ask-password/", de->d_name))) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + wall = NULL; + if ((q = parse_password(p, &wall)) < 0) + r = q; + + free(p); + + if (wall) { + utmp_wall(wall, wall_tty_match); + free(wall); + } + } + +finish: + if (d) + closedir(d); + + return r; +} + +static int watch_passwords(void) { + enum { + FD_INOTIFY, + FD_SIGNAL, + _FD_MAX + }; + + int notify = -1, signal_fd = -1, tty_block_fd = -1; + struct pollfd pollfd[_FD_MAX]; + sigset_t mask; + int r; + + tty_block_fd = wall_tty_block(); + + mkdir_p("/run/systemd/ask-password", 0755); + + if ((notify = inotify_init1(IN_CLOEXEC)) < 0) { + r = -errno; + goto finish; + } + + if (inotify_add_watch(notify, "/run/systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO) < 0) { + r = -errno; + goto finish; + } + + assert_se(sigemptyset(&mask) == 0); + sigset_add_many(&mask, SIGINT, SIGTERM, -1); + assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0); + + if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) { + log_error("signalfd(): %m"); + r = -errno; + goto finish; + } + + zero(pollfd); + pollfd[FD_INOTIFY].fd = notify; + pollfd[FD_INOTIFY].events = POLLIN; + pollfd[FD_SIGNAL].fd = signal_fd; + pollfd[FD_SIGNAL].events = POLLIN; + + for (;;) { + if ((r = show_passwords()) < 0) + log_error("Failed to show password: %s", strerror(-r)); + + if (poll(pollfd, _FD_MAX, -1) < 0) { + + if (errno == EINTR) + continue; + + r = -errno; + goto finish; + } + + if (pollfd[FD_INOTIFY].revents != 0) + flush_fd(notify); + + if (pollfd[FD_SIGNAL].revents != 0) + break; + } + + r = 0; + +finish: + if (notify >= 0) + close_nointr_nofail(notify); + + if (signal_fd >= 0) + close_nointr_nofail(signal_fd); + + if (tty_block_fd >= 0) + close_nointr_nofail(tty_block_fd); + + return r; +} + +static int help(void) { + + printf("%s [OPTIONS...]\n\n" + "Process system password requests.\n\n" + " -h --help Show this help\n" + " --list Show pending password requests\n" + " --query Process pending password requests\n" + " --watch Continuously process password requests\n" + " --wall Continuously forward password requests to wall\n" + " --plymouth Ask question with Plymouth instead of on TTY\n" + " --console Ask question on /dev/console instead of current TTY\n", + program_invocation_short_name); + + return 0; +} + +static int parse_argv(int argc, char *argv[]) { + + enum { + ARG_LIST = 0x100, + ARG_QUERY, + ARG_WATCH, + ARG_WALL, + ARG_PLYMOUTH, + ARG_CONSOLE + }; + + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "list", no_argument, NULL, ARG_LIST }, + { "query", no_argument, NULL, ARG_QUERY }, + { "watch", no_argument, NULL, ARG_WATCH }, + { "wall", no_argument, NULL, ARG_WALL }, + { "plymouth", no_argument, NULL, ARG_PLYMOUTH }, + { "console", no_argument, NULL, ARG_CONSOLE }, + { NULL, 0, NULL, 0 } + }; + + int c; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { + + switch (c) { + + case 'h': + help(); + return 0; + + case ARG_LIST: + arg_action = ACTION_LIST; + break; + + case ARG_QUERY: + arg_action = ACTION_QUERY; + break; + + case ARG_WATCH: + arg_action = ACTION_WATCH; + break; + + case ARG_WALL: + arg_action = ACTION_WALL; + break; + + case ARG_PLYMOUTH: + arg_plymouth = true; + break; + + case ARG_CONSOLE: + arg_console = true; + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + } + + if (optind != argc) { + help(); + return -EINVAL; + } + + return 1; +} + +int main(int argc, char *argv[]) { + int r; + + log_parse_environment(); + log_open(); + + umask(0022); + + if ((r = parse_argv(argc, argv)) <= 0) + goto finish; + + if (arg_console) { + setsid(); + release_terminal(); + } + + if (arg_action == ACTION_WATCH || + arg_action == ACTION_WALL) + r = watch_passwords(); + else + r = show_passwords(); + + if (r < 0) + log_error("Error: %s", strerror(-r)); + +finish: + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/umount.c b/src/umount.c new file mode 100644 index 0000000..4e036d8 --- /dev/null +++ b/src/umount.c @@ -0,0 +1,640 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 ProFUSION embedded systems + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "list.h" +#include "mount-setup.h" +#include "umount.h" +#include "util.h" + +typedef struct MountPoint { + char *path; + dev_t devnum; + bool skip_ro; + LIST_FIELDS (struct MountPoint, mount_point); +} MountPoint; + +static void mount_point_free(MountPoint **head, MountPoint *m) { + assert(head); + assert(m); + + LIST_REMOVE(MountPoint, mount_point, *head, m); + + free(m->path); + free(m); +} + +static void mount_points_list_free(MountPoint **head) { + assert(head); + + while (*head) + mount_point_free(head, *head); +} + +static int mount_points_list_get(MountPoint **head) { + FILE *proc_self_mountinfo; + char *path, *p; + unsigned int i; + int r; + + assert(head); + + if (!(proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"))) + return -errno; + + for (i = 1;; i++) { + int k; + MountPoint *m; + char *root; + bool skip_ro; + + path = p = NULL; + + if ((k = fscanf(proc_self_mountinfo, + "%*s " /* (1) mount id */ + "%*s " /* (2) parent id */ + "%*s " /* (3) major:minor */ + "%ms " /* (4) root */ + "%ms " /* (5) mount point */ + "%*s" /* (6) mount options */ + "%*[^-]" /* (7) optional fields */ + "- " /* (8) separator */ + "%*s " /* (9) file system type */ + "%*s" /* (10) mount source */ + "%*s" /* (11) mount options 2 */ + "%*[^\n]", /* some rubbish at the end */ + &root, + &path)) != 2) { + if (k == EOF) + break; + + log_warning("Failed to parse /proc/self/mountinfo:%u.", i); + + free(path); + continue; + } + + /* If we encounter a bind mount, don't try to remount + * the source dir too early */ + skip_ro = !streq(root, "/"); + free(root); + + p = cunescape(path); + free(path); + + if (!p) { + r = -ENOMEM; + goto finish; + } + + if (mount_point_is_api(p) || mount_point_ignore(p)) { + free(p); + continue; + } + + if (!(m = new0(MountPoint, 1))) { + free(p); + r = -ENOMEM; + goto finish; + } + + m->path = p; + m->skip_ro = skip_ro; + LIST_PREPEND(MountPoint, mount_point, *head, m); + } + + r = 0; + +finish: + fclose(proc_self_mountinfo); + + return r; +} + +static int swap_list_get(MountPoint **head) { + FILE *proc_swaps; + unsigned int i; + int r; + + assert(head); + + if (!(proc_swaps = fopen("/proc/swaps", "re"))) + return (errno == ENOENT) ? 0 : -errno; + + (void) fscanf(proc_swaps, "%*s %*s %*s %*s %*s\n"); + + for (i = 2;; i++) { + MountPoint *swap; + char *dev = NULL, *d; + int k; + + if ((k = fscanf(proc_swaps, + "%ms " /* device/file */ + "%*s " /* type of swap */ + "%*s " /* swap size */ + "%*s " /* used */ + "%*s\n", /* priority */ + &dev)) != 1) { + + if (k == EOF) + break; + + log_warning("Failed to parse /proc/swaps:%u.", i); + + free(dev); + continue; + } + + if (endswith(dev, "(deleted)")) { + free(dev); + continue; + } + + d = cunescape(dev); + free(dev); + + if (!d) { + r = -ENOMEM; + goto finish; + } + + if (!(swap = new0(MountPoint, 1))) { + free(d); + r = -ENOMEM; + goto finish; + } + + swap->path = d; + LIST_PREPEND(MountPoint, mount_point, *head, swap); + } + + r = 0; + +finish: + fclose(proc_swaps); + + return r; +} + +static int loopback_list_get(MountPoint **head) { + int r; + struct udev *udev; + struct udev_enumerate *e = NULL; + struct udev_list_entry *item = NULL, *first = NULL; + + assert(head); + + if (!(udev = udev_new())) { + r = -ENOMEM; + goto finish; + } + + if (!(e = udev_enumerate_new(udev))) { + r = -ENOMEM; + goto finish; + } + + if (udev_enumerate_add_match_subsystem(e, "block") < 0 || + udev_enumerate_add_match_sysname(e, "loop*") < 0) { + r = -EIO; + goto finish; + } + + if (udev_enumerate_scan_devices(e) < 0) { + r = -EIO; + goto finish; + } + + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + MountPoint *lb; + struct udev_device *d; + char *loop; + const char *dn; + + if (!(d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)))) { + r = -ENOMEM; + goto finish; + } + + if (!(dn = udev_device_get_devnode(d))) { + udev_device_unref(d); + continue; + } + + loop = strdup(dn); + udev_device_unref(d); + + if (!loop) { + r = -ENOMEM; + goto finish; + } + + if (!(lb = new0(MountPoint, 1))) { + free(loop); + r = -ENOMEM; + goto finish; + } + + lb->path = loop; + LIST_PREPEND(MountPoint, mount_point, *head, lb); + } + + r = 0; + +finish: + if (e) + udev_enumerate_unref(e); + + if (udev) + udev_unref(udev); + + return r; +} + +static int dm_list_get(MountPoint **head) { + int r; + struct udev *udev; + struct udev_enumerate *e = NULL; + struct udev_list_entry *item = NULL, *first = NULL; + + assert(head); + + if (!(udev = udev_new())) { + r = -ENOMEM; + goto finish; + } + + if (!(e = udev_enumerate_new(udev))) { + r = -ENOMEM; + goto finish; + } + + if (udev_enumerate_add_match_subsystem(e, "block") < 0 || + udev_enumerate_add_match_sysname(e, "dm-*") < 0) { + r = -EIO; + goto finish; + } + + if (udev_enumerate_scan_devices(e) < 0) { + r = -EIO; + goto finish; + } + + first = udev_enumerate_get_list_entry(e); + + udev_list_entry_foreach(item, first) { + MountPoint *m; + struct udev_device *d; + dev_t devnum; + char *node; + const char *dn; + + if (!(d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)))) { + r = -ENOMEM; + goto finish; + } + + devnum = udev_device_get_devnum(d); + dn = udev_device_get_devnode(d); + + if (major(devnum) == 0 || !dn) { + udev_device_unref(d); + continue; + } + + node = strdup(dn); + udev_device_unref(d); + + if (!node) { + r = -ENOMEM; + goto finish; + } + + if (!(m = new(MountPoint, 1))) { + free(node); + r = -ENOMEM; + goto finish; + } + + m->path = node; + m->devnum = devnum; + LIST_PREPEND(MountPoint, mount_point, *head, m); + } + + r = 0; + +finish: + if (e) + udev_enumerate_unref(e); + + if (udev) + udev_unref(udev); + + return r; +} + +static int delete_loopback(const char *device) { + int fd, r; + + if ((fd = open(device, O_RDONLY|O_CLOEXEC)) < 0) + return errno == ENOENT ? 0 : -errno; + + r = ioctl(fd, LOOP_CLR_FD, 0); + close_nointr_nofail(fd); + + if (r >= 0) + return 1; + + /* ENXIO: not bound, so no error */ + if (errno == ENXIO) + return 0; + + return -errno; +} + +static int delete_dm(dev_t devnum) { + int fd, r; + struct dm_ioctl dm; + + assert(major(devnum) != 0); + + if ((fd = open("/dev/mapper/control", O_RDWR|O_CLOEXEC)) < 0) + return -errno; + + zero(dm); + dm.version[0] = DM_VERSION_MAJOR; + dm.version[1] = DM_VERSION_MINOR; + dm.version[2] = DM_VERSION_PATCHLEVEL; + + dm.data_size = sizeof(dm); + dm.dev = devnum; + + r = ioctl(fd, DM_DEV_REMOVE, &dm); + close_nointr_nofail(fd); + + return r >= 0 ? 0 : -errno; +} + +static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_error) { + MountPoint *m, *n; + int n_failed = 0; + + assert(head); + + LIST_FOREACH_SAFE(mount_point, m, n, *head) { + if (streq(m->path, "/")) { + n_failed++; + continue; + } + + /* Trying to umount. Forcing to umount if busy (only for NFS mounts) */ + if (umount2(m->path, MNT_FORCE) == 0) { + log_info("Unmounted %s.", m->path); + if (changed) + *changed = true; + + mount_point_free(head, m); + } else if (log_error) { + log_warning("Could not unmount %s: %m", m->path); + n_failed++; + } + } + + return n_failed; +} + +static int mount_points_list_remount_read_only(MountPoint **head, bool *changed) { + MountPoint *m, *n; + int n_failed = 0; + + assert(head); + + LIST_FOREACH_SAFE(mount_point, m, n, *head) { + + if (m->skip_ro) { + n_failed++; + continue; + } + + /* Trying to remount read-only */ + if (mount(NULL, m->path, NULL, MS_MGC_VAL|MS_REMOUNT|MS_RDONLY, NULL) == 0) { + if (changed) + *changed = true; + + mount_point_free(head, m); + } else { + log_warning("Could not remount as read-only %s: %m", m->path); + n_failed++; + } + } + + return n_failed; +} + +static int swap_points_list_off(MountPoint **head, bool *changed) { + MountPoint *m, *n; + int n_failed = 0; + + assert(head); + + LIST_FOREACH_SAFE(mount_point, m, n, *head) { + if (swapoff(m->path) == 0) { + if (changed) + *changed = true; + + mount_point_free(head, m); + } else { + log_warning("Could not deactivate swap %s: %m", m->path); + n_failed++; + } + } + + return n_failed; +} + +static int loopback_points_list_detach(MountPoint **head, bool *changed) { + MountPoint *m, *n; + int n_failed = 0, k; + struct stat root_st; + + assert(head); + + k = lstat("/", &root_st); + + LIST_FOREACH_SAFE(mount_point, m, n, *head) { + int r; + struct stat loopback_st; + + if (k >= 0 && + major(root_st.st_dev) != 0 && + lstat(m->path, &loopback_st) >= 0 && + root_st.st_dev == loopback_st.st_rdev) { + n_failed ++; + continue; + } + + if ((r = delete_loopback(m->path)) >= 0) { + + if (r > 0 && changed) + *changed = true; + + mount_point_free(head, m); + } else { + log_warning("Could not delete loopback %s: %m", m->path); + n_failed++; + } + } + + return n_failed; +} + +static int dm_points_list_detach(MountPoint **head, bool *changed) { + MountPoint *m, *n; + int n_failed = 0, k; + struct stat root_st; + + assert(head); + + k = lstat("/", &root_st); + + LIST_FOREACH_SAFE(mount_point, m, n, *head) { + int r; + + if (k >= 0 && + major(root_st.st_dev) != 0 && + root_st.st_dev == m->devnum) { + n_failed ++; + continue; + } + + if ((r = delete_dm(m->devnum)) >= 0) { + + if (r > 0 && changed) + *changed = true; + + mount_point_free(head, m); + } else { + log_warning("Could not delete dm %s: %m", m->path); + n_failed++; + } + } + + return n_failed; +} + +int umount_all(bool *changed) { + int r; + bool umount_changed; + + LIST_HEAD(MountPoint, mp_list_head); + + LIST_HEAD_INIT(MountPoint, mp_list_head); + + r = mount_points_list_get(&mp_list_head); + if (r < 0) + goto end; + + /* retry umount, until nothing can be umounted anymore */ + do { + umount_changed = false; + + mount_points_list_umount(&mp_list_head, &umount_changed, false); + if (umount_changed) + *changed = true; + + } while (umount_changed); + + /* umount one more time with logging enabled */ + r = mount_points_list_umount(&mp_list_head, &umount_changed, true); + if (r <= 0) + goto end; + + r = mount_points_list_remount_read_only(&mp_list_head, changed); + + end: + mount_points_list_free(&mp_list_head); + + return r; +} + +int swapoff_all(bool *changed) { + int r; + LIST_HEAD(MountPoint, swap_list_head); + + LIST_HEAD_INIT(MountPoint, swap_list_head); + + r = swap_list_get(&swap_list_head); + if (r < 0) + goto end; + + r = swap_points_list_off(&swap_list_head, changed); + + end: + mount_points_list_free(&swap_list_head); + + return r; +} + +int loopback_detach_all(bool *changed) { + int r; + LIST_HEAD(MountPoint, loopback_list_head); + + LIST_HEAD_INIT(MountPoint, loopback_list_head); + + r = loopback_list_get(&loopback_list_head); + if (r < 0) + goto end; + + r = loopback_points_list_detach(&loopback_list_head, changed); + + end: + mount_points_list_free(&loopback_list_head); + + return r; +} + +int dm_detach_all(bool *changed) { + int r; + LIST_HEAD(MountPoint, dm_list_head); + + LIST_HEAD_INIT(MountPoint, dm_list_head); + + r = dm_list_get(&dm_list_head); + if (r < 0) + goto end; + + r = dm_points_list_detach(&dm_list_head, changed); + + end: + mount_points_list_free(&dm_list_head); + + return r; +} diff --git a/src/umount.h b/src/umount.h new file mode 100644 index 0000000..acdf09a --- /dev/null +++ b/src/umount.h @@ -0,0 +1,33 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooumounthfoo +#define fooumounthfoo + +/*** + This file is part of systemd. + + Copyright 2010 ProFUSION embedded systems + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +int umount_all(bool *changed); + +int swapoff_all(bool *changed); + +int loopback_detach_all(bool *changed); + +int dm_detach_all(bool *changed); + +#endif diff --git a/src/unit-name.c b/src/unit-name.c new file mode 100644 index 0000000..1cbb804 --- /dev/null +++ b/src/unit-name.c @@ -0,0 +1,448 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "util.h" +#include "unit-name.h" + +#define VALID_CHARS \ + "0123456789" \ + "abcdefghijklmnopqrstuvwxyz" \ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + ":-_.\\" + +bool unit_name_is_valid_no_type(const char *n, bool template_ok) { + const char *e, *i, *at; + + /* Valid formats: + * + * string@instance.suffix + * string.suffix + */ + + assert(n); + + if (strlen(n) >= UNIT_NAME_MAX) + return false; + + e = strrchr(n, '.'); + if (!e || e == n) + return false; + + for (i = n, at = NULL; i < e; i++) { + + if (*i == '@' && !at) + at = i; + + if (!strchr("@" VALID_CHARS, *i)) + return false; + } + + if (at) { + if (at == n) + return false; + + if (!template_ok && at+1 == e) + return false; + } + + return true; +} + +bool unit_instance_is_valid(const char *i) { + assert(i); + + /* The max length depends on the length of the string, so we + * don't really check this here. */ + + if (i[0] == 0) + return false; + + /* We allow additional @ in the instance string, we do not + * allow them in the prefix! */ + + for (; *i; i++) + if (!strchr("@" VALID_CHARS, *i)) + return false; + + return true; +} + +bool unit_prefix_is_valid(const char *p) { + + /* We don't allow additional @ in the instance string */ + + if (p[0] == 0) + return false; + + for (; *p; p++) + if (!strchr(VALID_CHARS, *p)) + return false; + + return true; +} + +int unit_name_to_instance(const char *n, char **instance) { + const char *p, *d; + char *i; + + assert(n); + assert(instance); + + /* Everything past the first @ and before the last . is the instance */ + if (!(p = strchr(n, '@'))) { + *instance = NULL; + return 0; + } + + assert_se(d = strrchr(n, '.')); + assert(p < d); + + if (!(i = strndup(p+1, d-p-1))) + return -ENOMEM; + + *instance = i; + return 0; +} + +char *unit_name_to_prefix_and_instance(const char *n) { + const char *d; + + assert(n); + + assert_se(d = strrchr(n, '.')); + + return strndup(n, d - n); +} + +char *unit_name_to_prefix(const char *n) { + const char *p; + + if ((p = strchr(n, '@'))) + return strndup(n, p - n); + + return unit_name_to_prefix_and_instance(n); +} + +char *unit_name_change_suffix(const char *n, const char *suffix) { + char *e, *r; + size_t a, b; + + assert(n); + assert(unit_name_is_valid_no_type(n, true)); + assert(suffix); + + assert_se(e = strrchr(n, '.')); + a = e - n; + b = strlen(suffix); + + if (!(r = new(char, a + b + 1))) + return NULL; + + memcpy(r, n, a); + memcpy(r+a, suffix, b+1); + + return r; +} + +char *unit_name_build(const char *prefix, const char *instance, const char *suffix) { + assert(prefix); + assert(unit_prefix_is_valid(prefix)); + assert(!instance || unit_instance_is_valid(instance)); + assert(suffix); + + if (!instance) + return strappend(prefix, suffix); + + return join(prefix, "@", instance, suffix, NULL); +} + +static char* do_escape(const char *f, char *t) { + assert(f); + assert(t); + + for (; *f; f++) { + if (*f == '/') + *(t++) = '-'; + else if (*f == '-' || *f == '\\' || !strchr(VALID_CHARS, *f)) { + *(t++) = '\\'; + *(t++) = 'x'; + *(t++) = hexchar(*f >> 4); + *(t++) = hexchar(*f); + } else + *(t++) = *f; + } + + return t; +} + +char *unit_name_build_escape(const char *prefix, const char *instance, const char *suffix) { + char *r, *t; + size_t a, b, c; + + assert(prefix); + assert(suffix); + + /* Takes a arbitrary string for prefix and instance plus a + * suffix and makes a nice string suitable as unit name of it, + * escaping all weird chars on the way. + * + * / becomes ., and all chars not allowed in a unit name get + * escaped as \xFF, including \ and ., of course. This + * escaping is hence reversible. + * + * This is primarily useful to make nice unit names from + * strings, but is actually useful for any kind of string. + */ + + a = strlen(prefix); + c = strlen(suffix); + + if (instance) { + b = strlen(instance); + + if (!(r = new(char, a*4 + 1 + b*4 + c + 1))) + return NULL; + + t = do_escape(prefix, r); + *(t++) = '@'; + t = do_escape(instance, t); + } else { + + if (!(r = new(char, a*4 + c + 1))) + return NULL; + + t = do_escape(prefix, r); + } + + strcpy(t, suffix); + return r; +} + +char *unit_name_escape(const char *f) { + char *r, *t; + + if (!(r = new(char, strlen(f)*4+1))) + return NULL; + + t = do_escape(f, r); + *t = 0; + + return r; + +} + +char *unit_name_unescape(const char *f) { + char *r, *t; + + assert(f); + + if (!(r = strdup(f))) + return NULL; + + for (t = r; *f; f++) { + if (*f == '-') + *(t++) = '/'; + else if (*f == '\\') { + int a, b; + + if (f[1] != 'x' || + (a = unhexchar(f[2])) < 0 || + (b = unhexchar(f[3])) < 0) { + /* Invalid escape code, let's take it literal then */ + *(t++) = '\\'; + } else { + *(t++) = (char) ((a << 4) | b); + f += 3; + } + } else + *(t++) = *f; + } + + *t = 0; + + return r; +} + +bool unit_name_is_template(const char *n) { + const char *p; + + assert(n); + + if (!(p = strchr(n, '@'))) + return false; + + return p[1] == '.'; +} + +char *unit_name_replace_instance(const char *f, const char *i) { + const char *p, *e; + char *r, *k; + size_t a; + + assert(f); + + p = strchr(f, '@'); + assert_se(e = strrchr(f, '.')); + + a = p - f; + + if (p) { + size_t b; + + b = strlen(i); + + if (!(r = new(char, a + 1 + b + strlen(e) + 1))) + return NULL; + + k = mempcpy(r, f, a + 1); + k = mempcpy(k, i, b); + } else { + + if (!(r = new(char, a + strlen(e) + 1))) + return NULL; + + k = mempcpy(r, f, a); + } + + strcpy(k, e); + return r; +} + +char *unit_name_template(const char *f) { + const char *p, *e; + char *r; + size_t a; + + if (!(p = strchr(f, '@'))) + return strdup(f); + + assert_se(e = strrchr(f, '.')); + a = p - f + 1; + + if (!(r = new(char, a + strlen(e) + 1))) + return NULL; + + strcpy(mempcpy(r, f, a), e); + return r; + +} + +char *unit_name_from_path(const char *path, const char *suffix) { + char *p, *r; + + assert(path); + assert(suffix); + + if (!(p = strdup(path))) + return NULL; + + path_kill_slashes(p); + + path = p[0] == '/' ? p + 1 : p; + + if (path[0] == 0) { + free(p); + return strappend("-", suffix); + } + + r = unit_name_build_escape(path, NULL, suffix); + free(p); + + return r; +} + +char *unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix) { + char *p, *r; + + assert(path); + assert(suffix); + + if (!(p = strdup(path))) + return NULL; + + path_kill_slashes(p); + + path = p[0] == '/' ? p + 1 : p; + + if (path[0] == 0) { + free(p); + return unit_name_build_escape(prefix, "-", suffix); + } + + r = unit_name_build_escape(prefix, path, suffix); + free(p); + + return r; +} + +char *unit_name_to_path(const char *name) { + char *w, *e; + + assert(name); + + if (!(w = unit_name_to_prefix(name))) + return NULL; + + e = unit_name_unescape(w); + free(w); + + if (!e) + return NULL; + + if (e[0] != '/') { + w = strappend("/", e); + free(e); + + if (!w) + return NULL; + + e = w; + } + + return e; +} + +char *unit_name_path_unescape(const char *f) { + char *e; + + assert(f); + + if (!(e = unit_name_unescape(f))) + return NULL; + + if (e[0] != '/') { + char *w; + + w = strappend("/", e); + free(e); + + if (!w) + return NULL; + + e = w; + } + + return e; +} diff --git a/src/unit-name.h b/src/unit-name.h new file mode 100644 index 0000000..e369910 --- /dev/null +++ b/src/unit-name.h @@ -0,0 +1,57 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foounitnamehfoo +#define foounitnamehfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include + +#define UNIT_NAME_MAX 256 + +int unit_name_to_instance(const char *n, char **instance); +char* unit_name_to_prefix(const char *n); +char* unit_name_to_prefix_and_instance(const char *n); + +bool unit_name_is_valid_no_type(const char *n, bool template_ok); +bool unit_prefix_is_valid(const char *p); +bool unit_instance_is_valid(const char *i); + +char *unit_name_change_suffix(const char *n, const char *suffix); + +char *unit_name_build(const char *prefix, const char *instance, const char *suffix); +char *unit_name_build_escape(const char *prefix, const char *instance, const char *suffix); + +char *unit_name_escape(const char *f); +char *unit_name_unescape(const char *f); + +char *unit_name_path_unescape(const char *f); + +bool unit_name_is_template(const char *n); + +char *unit_name_replace_instance(const char *f, const char *i); + +char *unit_name_template(const char *f); + +char *unit_name_from_path(const char *path, const char *suffix); +char *unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix); +char *unit_name_to_path(const char *name); + +#endif diff --git a/src/unit.c b/src/unit.c new file mode 100644 index 0000000..9e33701 --- /dev/null +++ b/src/unit.c @@ -0,0 +1,2676 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "set.h" +#include "unit.h" +#include "macro.h" +#include "strv.h" +#include "load-fragment.h" +#include "load-dropin.h" +#include "log.h" +#include "unit-name.h" +#include "specifier.h" +#include "dbus-unit.h" +#include "special.h" +#include "cgroup-util.h" +#include "missing.h" +#include "cgroup-attr.h" + +const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = { + [UNIT_SERVICE] = &service_vtable, + [UNIT_TIMER] = &timer_vtable, + [UNIT_SOCKET] = &socket_vtable, + [UNIT_TARGET] = &target_vtable, + [UNIT_DEVICE] = &device_vtable, + [UNIT_MOUNT] = &mount_vtable, + [UNIT_AUTOMOUNT] = &automount_vtable, + [UNIT_SNAPSHOT] = &snapshot_vtable, + [UNIT_SWAP] = &swap_vtable, + [UNIT_PATH] = &path_vtable +}; + +Unit *unit_new(Manager *m, size_t size) { + Unit *u; + + assert(m); + assert(size >= sizeof(Unit)); + + u = malloc0(size); + if (!u) + return NULL; + + u->names = set_new(string_hash_func, string_compare_func); + if (!u->names) { + free(u); + return NULL; + } + + u->manager = m; + u->type = _UNIT_TYPE_INVALID; + u->deserialized_job = _JOB_TYPE_INVALID; + u->default_dependencies = true; + u->unit_file_state = _UNIT_FILE_STATE_INVALID; + + return u; +} + +bool unit_has_name(Unit *u, const char *name) { + assert(u); + assert(name); + + return !!set_get(u->names, (char*) name); +} + +int unit_add_name(Unit *u, const char *text) { + UnitType t; + char *s, *i = NULL; + int r; + + assert(u); + assert(text); + + if (unit_name_is_template(text)) { + if (!u->instance) + return -EINVAL; + + s = unit_name_replace_instance(text, u->instance); + } else + s = strdup(text); + + if (!s) + return -ENOMEM; + + if (!unit_name_is_valid(s, false)) { + r = -EINVAL; + goto fail; + } + + assert_se((t = unit_name_to_type(s)) >= 0); + + if (u->type != _UNIT_TYPE_INVALID && t != u->type) { + r = -EINVAL; + goto fail; + } + + if ((r = unit_name_to_instance(s, &i)) < 0) + goto fail; + + if (i && unit_vtable[t]->no_instances) { + r = -EINVAL; + goto fail; + } + + /* Ensure that this unit is either instanced or not instanced, + * but not both. */ + if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i) { + r = -EINVAL; + goto fail; + } + + if (unit_vtable[t]->no_alias && + !set_isempty(u->names) && + !set_get(u->names, s)) { + r = -EEXIST; + goto fail; + } + + if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES) { + r = -E2BIG; + goto fail; + } + + if ((r = set_put(u->names, s)) < 0) { + if (r == -EEXIST) + r = 0; + goto fail; + } + + if ((r = hashmap_put(u->manager->units, s, u)) < 0) { + set_remove(u->names, s); + goto fail; + } + + if (u->type == _UNIT_TYPE_INVALID) { + + u->type = t; + u->id = s; + u->instance = i; + + LIST_PREPEND(Unit, units_by_type, u->manager->units_by_type[t], u); + + if (UNIT_VTABLE(u)->init) + UNIT_VTABLE(u)->init(u); + } else + free(i); + + unit_add_to_dbus_queue(u); + return 0; + +fail: + free(s); + free(i); + + return r; +} + +int unit_choose_id(Unit *u, const char *name) { + char *s, *t = NULL, *i; + int r; + + assert(u); + assert(name); + + if (unit_name_is_template(name)) { + + if (!u->instance) + return -EINVAL; + + if (!(t = unit_name_replace_instance(name, u->instance))) + return -ENOMEM; + + name = t; + } + + /* Selects one of the names of this unit as the id */ + s = set_get(u->names, (char*) name); + free(t); + + if (!s) + return -ENOENT; + + if ((r = unit_name_to_instance(s, &i)) < 0) + return r; + + u->id = s; + + free(u->instance); + u->instance = i; + + unit_add_to_dbus_queue(u); + + return 0; +} + +int unit_set_description(Unit *u, const char *description) { + char *s; + + assert(u); + + if (!(s = strdup(description))) + return -ENOMEM; + + free(u->description); + u->description = s; + + unit_add_to_dbus_queue(u); + return 0; +} + +bool unit_check_gc(Unit *u) { + assert(u); + + if (u->load_state == UNIT_STUB) + return true; + + if (UNIT_VTABLE(u)->no_gc) + return true; + + if (u->no_gc) + return true; + + if (u->job) + return true; + + if (unit_active_state(u) != UNIT_INACTIVE) + return true; + + if (UNIT_VTABLE(u)->check_gc) + if (UNIT_VTABLE(u)->check_gc(u)) + return true; + + return false; +} + +void unit_add_to_load_queue(Unit *u) { + assert(u); + assert(u->type != _UNIT_TYPE_INVALID); + + if (u->load_state != UNIT_STUB || u->in_load_queue) + return; + + LIST_PREPEND(Unit, load_queue, u->manager->load_queue, u); + u->in_load_queue = true; +} + +void unit_add_to_cleanup_queue(Unit *u) { + assert(u); + + if (u->in_cleanup_queue) + return; + + LIST_PREPEND(Unit, cleanup_queue, u->manager->cleanup_queue, u); + u->in_cleanup_queue = true; +} + +void unit_add_to_gc_queue(Unit *u) { + assert(u); + + if (u->in_gc_queue || u->in_cleanup_queue) + return; + + if (unit_check_gc(u)) + return; + + LIST_PREPEND(Unit, gc_queue, u->manager->gc_queue, u); + u->in_gc_queue = true; + + u->manager->n_in_gc_queue ++; + + if (u->manager->gc_queue_timestamp <= 0) + u->manager->gc_queue_timestamp = now(CLOCK_MONOTONIC); +} + +void unit_add_to_dbus_queue(Unit *u) { + assert(u); + assert(u->type != _UNIT_TYPE_INVALID); + + if (u->load_state == UNIT_STUB || u->in_dbus_queue) + return; + + /* Shortcut things if nobody cares */ + if (!bus_has_subscriber(u->manager)) { + u->sent_dbus_new_signal = true; + return; + } + + LIST_PREPEND(Unit, dbus_queue, u->manager->dbus_unit_queue, u); + u->in_dbus_queue = true; +} + +static void bidi_set_free(Unit *u, Set *s) { + Iterator i; + Unit *other; + + assert(u); + + /* Frees the set and makes sure we are dropped from the + * inverse pointers */ + + SET_FOREACH(other, s, i) { + UnitDependency d; + + for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) + set_remove(other->dependencies[d], u); + + unit_add_to_gc_queue(other); + } + + set_free(s); +} + +void unit_free(Unit *u) { + UnitDependency d; + Iterator i; + char *t; + + assert(u); + + bus_unit_send_removed_signal(u); + + if (u->load_state != UNIT_STUB) + if (UNIT_VTABLE(u)->done) + UNIT_VTABLE(u)->done(u); + + SET_FOREACH(t, u->names, i) + hashmap_remove_value(u->manager->units, t, u); + + if (u->job) + job_free(u->job); + + for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) + bidi_set_free(u, u->dependencies[d]); + + if (u->type != _UNIT_TYPE_INVALID) + LIST_REMOVE(Unit, units_by_type, u->manager->units_by_type[u->type], u); + + if (u->in_load_queue) + LIST_REMOVE(Unit, load_queue, u->manager->load_queue, u); + + if (u->in_dbus_queue) + LIST_REMOVE(Unit, dbus_queue, u->manager->dbus_unit_queue, u); + + if (u->in_cleanup_queue) + LIST_REMOVE(Unit, cleanup_queue, u->manager->cleanup_queue, u); + + if (u->in_gc_queue) { + LIST_REMOVE(Unit, gc_queue, u->manager->gc_queue, u); + u->manager->n_in_gc_queue--; + } + + cgroup_bonding_free_list(u->cgroup_bondings, u->manager->n_reloading <= 0); + cgroup_attribute_free_list(u->cgroup_attributes); + + free(u->description); + free(u->fragment_path); + free(u->instance); + + set_free_free(u->names); + + condition_free_list(u->conditions); + + while (u->refs) + unit_ref_unset(u->refs); + + free(u); +} + +UnitActiveState unit_active_state(Unit *u) { + assert(u); + + if (u->load_state == UNIT_MERGED) + return unit_active_state(unit_follow_merge(u)); + + /* After a reload it might happen that a unit is not correctly + * loaded but still has a process around. That's why we won't + * shortcut failed loading to UNIT_INACTIVE_FAILED. */ + + return UNIT_VTABLE(u)->active_state(u); +} + +const char* unit_sub_state_to_string(Unit *u) { + assert(u); + + return UNIT_VTABLE(u)->sub_state_to_string(u); +} + +static void complete_move(Set **s, Set **other) { + assert(s); + assert(other); + + if (!*other) + return; + + if (*s) + set_move(*s, *other); + else { + *s = *other; + *other = NULL; + } +} + +static void merge_names(Unit *u, Unit *other) { + char *t; + Iterator i; + + assert(u); + assert(other); + + complete_move(&u->names, &other->names); + + set_free_free(other->names); + other->names = NULL; + other->id = NULL; + + SET_FOREACH(t, u->names, i) + assert_se(hashmap_replace(u->manager->units, t, u) == 0); +} + +static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) { + Iterator i; + Unit *back; + int r; + + assert(u); + assert(other); + assert(d < _UNIT_DEPENDENCY_MAX); + + /* Fix backwards pointers */ + SET_FOREACH(back, other->dependencies[d], i) { + UnitDependency k; + + for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++) + if ((r = set_remove_and_put(back->dependencies[k], other, u)) < 0) { + + if (r == -EEXIST) + set_remove(back->dependencies[k], other); + else + assert(r == -ENOENT); + } + } + + complete_move(&u->dependencies[d], &other->dependencies[d]); + + set_free(other->dependencies[d]); + other->dependencies[d] = NULL; +} + +int unit_merge(Unit *u, Unit *other) { + UnitDependency d; + + assert(u); + assert(other); + assert(u->manager == other->manager); + assert(u->type != _UNIT_TYPE_INVALID); + + other = unit_follow_merge(other); + + if (other == u) + return 0; + + if (u->type != other->type) + return -EINVAL; + + if (!u->instance != !other->instance) + return -EINVAL; + + if (other->load_state != UNIT_STUB && + other->load_state != UNIT_ERROR) + return -EEXIST; + + if (other->job) + return -EEXIST; + + if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) + return -EEXIST; + + /* Merge names */ + merge_names(u, other); + + /* Redirect all references */ + while (other->refs) + unit_ref_set(other->refs, u); + + /* Merge dependencies */ + for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) + merge_dependencies(u, other, d); + + other->load_state = UNIT_MERGED; + other->merged_into = u; + + /* If there is still some data attached to the other node, we + * don't need it anymore, and can free it. */ + if (other->load_state != UNIT_STUB) + if (UNIT_VTABLE(other)->done) + UNIT_VTABLE(other)->done(other); + + unit_add_to_dbus_queue(u); + unit_add_to_cleanup_queue(other); + + return 0; +} + +int unit_merge_by_name(Unit *u, const char *name) { + Unit *other; + int r; + char *s = NULL; + + assert(u); + assert(name); + + if (unit_name_is_template(name)) { + if (!u->instance) + return -EINVAL; + + if (!(s = unit_name_replace_instance(name, u->instance))) + return -ENOMEM; + + name = s; + } + + if (!(other = manager_get_unit(u->manager, name))) + r = unit_add_name(u, name); + else + r = unit_merge(u, other); + + free(s); + return r; +} + +Unit* unit_follow_merge(Unit *u) { + assert(u); + + while (u->load_state == UNIT_MERGED) + assert_se(u = u->merged_into); + + return u; +} + +int unit_add_exec_dependencies(Unit *u, ExecContext *c) { + int r; + + assert(u); + assert(c); + + if (c->std_output != EXEC_OUTPUT_KMSG && + c->std_output != EXEC_OUTPUT_SYSLOG && + c->std_output != EXEC_OUTPUT_JOURNAL && + c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE && + c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE && + c->std_output != EXEC_OUTPUT_JOURNAL_AND_CONSOLE && + c->std_error != EXEC_OUTPUT_KMSG && + c->std_error != EXEC_OUTPUT_SYSLOG && + c->std_error != EXEC_OUTPUT_JOURNAL && + c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE && + c->std_error != EXEC_OUTPUT_JOURNAL_AND_CONSOLE && + c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE) + return 0; + + /* If syslog or kernel logging is requested, make sure our own + * logging daemon is run first. */ + + if (u->manager->running_as == MANAGER_SYSTEM) + if ((r = unit_add_two_dependencies_by_name(u, UNIT_REQUIRES, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true)) < 0) + return r; + + return 0; +} + +const char *unit_description(Unit *u) { + assert(u); + + if (u->description) + return u->description; + + return strna(u->id); +} + +void unit_dump(Unit *u, FILE *f, const char *prefix) { + char *t; + UnitDependency d; + Iterator i; + char *p2; + const char *prefix2; + char + timestamp1[FORMAT_TIMESTAMP_MAX], + timestamp2[FORMAT_TIMESTAMP_MAX], + timestamp3[FORMAT_TIMESTAMP_MAX], + timestamp4[FORMAT_TIMESTAMP_MAX], + timespan[FORMAT_TIMESPAN_MAX]; + Unit *following; + + assert(u); + assert(u->type >= 0); + + if (!prefix) + prefix = ""; + p2 = strappend(prefix, "\t"); + prefix2 = p2 ? p2 : prefix; + + fprintf(f, + "%s-> Unit %s:\n" + "%s\tDescription: %s\n" + "%s\tInstance: %s\n" + "%s\tUnit Load State: %s\n" + "%s\tUnit Active State: %s\n" + "%s\tInactive Exit Timestamp: %s\n" + "%s\tActive Enter Timestamp: %s\n" + "%s\tActive Exit Timestamp: %s\n" + "%s\tInactive Enter Timestamp: %s\n" + "%s\tGC Check Good: %s\n" + "%s\tNeed Daemon Reload: %s\n", + prefix, u->id, + prefix, unit_description(u), + prefix, strna(u->instance), + prefix, unit_load_state_to_string(u->load_state), + prefix, unit_active_state_to_string(unit_active_state(u)), + prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->inactive_exit_timestamp.realtime)), + prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->active_enter_timestamp.realtime)), + prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->active_exit_timestamp.realtime)), + prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)), + prefix, yes_no(unit_check_gc(u)), + prefix, yes_no(unit_need_daemon_reload(u))); + + SET_FOREACH(t, u->names, i) + fprintf(f, "%s\tName: %s\n", prefix, t); + + if ((following = unit_following(u))) + fprintf(f, "%s\tFollowing: %s\n", prefix, following->id); + + if (u->fragment_path) + fprintf(f, "%s\tFragment Path: %s\n", prefix, u->fragment_path); + + if (u->job_timeout > 0) + fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout)); + + condition_dump_list(u->conditions, f, prefix); + + if (dual_timestamp_is_set(&u->condition_timestamp)) + fprintf(f, + "%s\tCondition Timestamp: %s\n" + "%s\tCondition Result: %s\n", + prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->condition_timestamp.realtime)), + prefix, yes_no(u->condition_result)); + + for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) { + Unit *other; + + SET_FOREACH(other, u->dependencies[d], i) + fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id); + } + + if (u->load_state == UNIT_LOADED) { + CGroupBonding *b; + CGroupAttribute *a; + + fprintf(f, + "%s\tStopWhenUnneeded: %s\n" + "%s\tRefuseManualStart: %s\n" + "%s\tRefuseManualStop: %s\n" + "%s\tDefaultDependencies: %s\n" + "%s\tOnFailureIsolate: %s\n" + "%s\tIgnoreOnIsolate: %s\n" + "%s\tIgnoreOnSnapshot: %s\n", + prefix, yes_no(u->stop_when_unneeded), + prefix, yes_no(u->refuse_manual_start), + prefix, yes_no(u->refuse_manual_stop), + prefix, yes_no(u->default_dependencies), + prefix, yes_no(u->on_failure_isolate), + prefix, yes_no(u->ignore_on_isolate), + prefix, yes_no(u->ignore_on_snapshot)); + + LIST_FOREACH(by_unit, b, u->cgroup_bondings) + fprintf(f, "%s\tControlGroup: %s:%s\n", + prefix, b->controller, b->path); + + LIST_FOREACH(by_unit, a, u->cgroup_attributes) { + char *v = NULL; + + if (a->map_callback) + a->map_callback(a->controller, a->name, a->value, &v); + + fprintf(f, "%s\tControlGroupAttribute: %s %s \"%s\"\n", + prefix, a->controller, a->name, v ? v : a->value); + + free(v); + } + + if (UNIT_VTABLE(u)->dump) + UNIT_VTABLE(u)->dump(u, f, prefix2); + + } else if (u->load_state == UNIT_MERGED) + fprintf(f, + "%s\tMerged into: %s\n", + prefix, u->merged_into->id); + else if (u->load_state == UNIT_ERROR) + fprintf(f, "%s\tLoad Error Code: %s\n", prefix, strerror(-u->load_error)); + + + if (u->job) + job_dump(u->job, f, prefix2); + + free(p2); +} + +/* Common implementation for multiple backends */ +int unit_load_fragment_and_dropin(Unit *u) { + int r; + + assert(u); + + /* Load a .service file */ + if ((r = unit_load_fragment(u)) < 0) + return r; + + if (u->load_state == UNIT_STUB) + return -ENOENT; + + /* Load drop-in directory data */ + if ((r = unit_load_dropin(unit_follow_merge(u))) < 0) + return r; + + return 0; +} + +/* Common implementation for multiple backends */ +int unit_load_fragment_and_dropin_optional(Unit *u) { + int r; + + assert(u); + + /* Same as unit_load_fragment_and_dropin(), but whether + * something can be loaded or not doesn't matter. */ + + /* Load a .service file */ + if ((r = unit_load_fragment(u)) < 0) + return r; + + if (u->load_state == UNIT_STUB) + u->load_state = UNIT_LOADED; + + /* Load drop-in directory data */ + if ((r = unit_load_dropin(unit_follow_merge(u))) < 0) + return r; + + return 0; +} + +int unit_add_default_target_dependency(Unit *u, Unit *target) { + assert(u); + assert(target); + + if (target->type != UNIT_TARGET) + return 0; + + /* Only add the dependency if both units are loaded, so that + * that loop check below is reliable */ + if (u->load_state != UNIT_LOADED || + target->load_state != UNIT_LOADED) + return 0; + + /* If either side wants no automatic dependencies, then let's + * skip this */ + if (!u->default_dependencies || + !target->default_dependencies) + return 0; + + /* Don't create loops */ + if (set_get(target->dependencies[UNIT_BEFORE], u)) + return 0; + + return unit_add_dependency(target, UNIT_AFTER, u, true); +} + +static int unit_add_default_dependencies(Unit *u) { + static const UnitDependency deps[] = { + UNIT_REQUIRED_BY, + UNIT_REQUIRED_BY_OVERRIDABLE, + UNIT_WANTED_BY, + UNIT_BOUND_BY + }; + + Unit *target; + Iterator i; + int r; + unsigned k; + + assert(u); + + for (k = 0; k < ELEMENTSOF(deps); k++) + SET_FOREACH(target, u->dependencies[deps[k]], i) + if ((r = unit_add_default_target_dependency(u, target)) < 0) + return r; + + return 0; +} + +int unit_load(Unit *u) { + int r; + + assert(u); + + if (u->in_load_queue) { + LIST_REMOVE(Unit, load_queue, u->manager->load_queue, u); + u->in_load_queue = false; + } + + if (u->type == _UNIT_TYPE_INVALID) + return -EINVAL; + + if (u->load_state != UNIT_STUB) + return 0; + + if (UNIT_VTABLE(u)->load) + if ((r = UNIT_VTABLE(u)->load(u)) < 0) + goto fail; + + if (u->load_state == UNIT_STUB) { + r = -ENOENT; + goto fail; + } + + if (u->load_state == UNIT_LOADED && + u->default_dependencies) + if ((r = unit_add_default_dependencies(u)) < 0) + goto fail; + + if (u->on_failure_isolate && + set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) { + + log_error("More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.", + u->id); + + r = -EINVAL; + goto fail; + } + + assert((u->load_state != UNIT_MERGED) == !u->merged_into); + + unit_add_to_dbus_queue(unit_follow_merge(u)); + unit_add_to_gc_queue(u); + + return 0; + +fail: + u->load_state = UNIT_ERROR; + u->load_error = r; + unit_add_to_dbus_queue(u); + unit_add_to_gc_queue(u); + + log_debug("Failed to load configuration for %s: %s", u->id, strerror(-r)); + + return r; +} + +bool unit_condition_test(Unit *u) { + assert(u); + + dual_timestamp_get(&u->condition_timestamp); + u->condition_result = condition_test_list(u->conditions); + + return u->condition_result; +} + +/* Errors: + * -EBADR: This unit type does not support starting. + * -EALREADY: Unit is already started. + * -EAGAIN: An operation is already in progress. Retry later. + * -ECANCELED: Too many requests for now. + */ +int unit_start(Unit *u) { + UnitActiveState state; + Unit *following; + + assert(u); + + if (u->load_state != UNIT_LOADED) + return -EINVAL; + + /* If this is already started, then this will succeed. Note + * that this will even succeed if this unit is not startable + * by the user. This is relied on to detect when we need to + * wait for units and when waiting is finished. */ + state = unit_active_state(u); + if (UNIT_IS_ACTIVE_OR_RELOADING(state)) + return -EALREADY; + + /* If the conditions failed, don't do anything at all. If we + * already are activating this call might still be useful to + * speed up activation in case there is some hold-off time, + * but we don't want to recheck the condition in that case. */ + if (state != UNIT_ACTIVATING && + !unit_condition_test(u)) { + log_debug("Starting of %s requested but condition failed. Ignoring.", u->id); + return -EALREADY; + } + + /* Forward to the main object, if we aren't it. */ + if ((following = unit_following(u))) { + log_debug("Redirecting start request from %s to %s.", u->id, following->id); + return unit_start(following); + } + + /* If it is stopped, but we cannot start it, then fail */ + if (!UNIT_VTABLE(u)->start) + return -EBADR; + + /* We don't suppress calls to ->start() here when we are + * already starting, to allow this request to be used as a + * "hurry up" call, for example when the unit is in some "auto + * restart" state where it waits for a holdoff timer to elapse + * before it will start again. */ + + unit_add_to_dbus_queue(u); + + unit_status_printf(u, NULL, "Starting %s...", unit_description(u)); + return UNIT_VTABLE(u)->start(u); +} + +bool unit_can_start(Unit *u) { + assert(u); + + return !!UNIT_VTABLE(u)->start; +} + +bool unit_can_isolate(Unit *u) { + assert(u); + + return unit_can_start(u) && + u->allow_isolate; +} + +/* Errors: + * -EBADR: This unit type does not support stopping. + * -EALREADY: Unit is already stopped. + * -EAGAIN: An operation is already in progress. Retry later. + */ +int unit_stop(Unit *u) { + UnitActiveState state; + Unit *following; + + assert(u); + + state = unit_active_state(u); + if (UNIT_IS_INACTIVE_OR_FAILED(state)) + return -EALREADY; + + if ((following = unit_following(u))) { + log_debug("Redirecting stop request from %s to %s.", u->id, following->id); + return unit_stop(following); + } + + if (!UNIT_VTABLE(u)->stop) + return -EBADR; + + unit_add_to_dbus_queue(u); + + unit_status_printf(u, NULL, "Stopping %s...", unit_description(u)); + return UNIT_VTABLE(u)->stop(u); +} + +/* Errors: + * -EBADR: This unit type does not support reloading. + * -ENOEXEC: Unit is not started. + * -EAGAIN: An operation is already in progress. Retry later. + */ +int unit_reload(Unit *u) { + UnitActiveState state; + Unit *following; + + assert(u); + + if (u->load_state != UNIT_LOADED) + return -EINVAL; + + if (!unit_can_reload(u)) + return -EBADR; + + state = unit_active_state(u); + if (state == UNIT_RELOADING) + return -EALREADY; + + if (state != UNIT_ACTIVE) + return -ENOEXEC; + + if ((following = unit_following(u))) { + log_debug("Redirecting reload request from %s to %s.", u->id, following->id); + return unit_reload(following); + } + + unit_add_to_dbus_queue(u); + return UNIT_VTABLE(u)->reload(u); +} + +bool unit_can_reload(Unit *u) { + assert(u); + + if (!UNIT_VTABLE(u)->reload) + return false; + + if (!UNIT_VTABLE(u)->can_reload) + return true; + + return UNIT_VTABLE(u)->can_reload(u); +} + +static void unit_check_unneeded(Unit *u) { + Iterator i; + Unit *other; + + assert(u); + + /* If this service shall be shut down when unneeded then do + * so. */ + + if (!u->stop_when_unneeded) + return; + + if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) + return; + + SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i) + if (unit_pending_active(other)) + return; + + SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i) + if (unit_pending_active(other)) + return; + + SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i) + if (unit_pending_active(other)) + return; + + SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i) + if (unit_pending_active(other)) + return; + + log_info("Service %s is not needed anymore. Stopping.", u->id); + + /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */ + manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL); +} + +static void retroactively_start_dependencies(Unit *u) { + Iterator i; + Unit *other; + + assert(u); + assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))); + + SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i) + if (!set_get(u->dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL); + + SET_FOREACH(other, u->dependencies[UNIT_BIND_TO], i) + if (!set_get(u->dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL); + + SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i) + if (!set_get(u->dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL); + + SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i) + if (!set_get(u->dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL); + + SET_FOREACH(other, u->dependencies[UNIT_WANTS], i) + if (!set_get(u->dependencies[UNIT_AFTER], other) && + !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL); + + SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL); + + SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL); +} + +static void retroactively_stop_dependencies(Unit *u) { + Iterator i; + Unit *other; + + assert(u); + assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u))); + + /* Pull down units which are bound to us recursively if enabled */ + SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL); +} + +static void check_unneeded_dependencies(Unit *u) { + Iterator i; + Unit *other; + + assert(u); + assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u))); + + /* Garbage collect services that might not be needed anymore, if enabled */ + SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + unit_check_unneeded(other); + SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + unit_check_unneeded(other); + SET_FOREACH(other, u->dependencies[UNIT_WANTS], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + unit_check_unneeded(other); + SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + unit_check_unneeded(other); + SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + unit_check_unneeded(other); + SET_FOREACH(other, u->dependencies[UNIT_BIND_TO], i) + if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other))) + unit_check_unneeded(other); +} + +void unit_trigger_on_failure(Unit *u) { + Unit *other; + Iterator i; + + assert(u); + + if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0) + return; + + log_info("Triggering OnFailure= dependencies of %s.", u->id); + + SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) { + int r; + + if ((r = manager_add_job(u->manager, JOB_START, other, u->on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL)) < 0) + log_error("Failed to enqueue OnFailure= job: %s", strerror(-r)); + } +} + +void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) { + bool unexpected; + + assert(u); + assert(os < _UNIT_ACTIVE_STATE_MAX); + assert(ns < _UNIT_ACTIVE_STATE_MAX); + + /* Note that this is called for all low-level state changes, + * even if they might map to the same high-level + * UnitActiveState! That means that ns == os is OK an expected + * behaviour here. For example: if a mount point is remounted + * this function will be called too! */ + + if (u->manager->n_reloading <= 0) { + dual_timestamp ts; + + dual_timestamp_get(&ts); + + if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns)) + u->inactive_exit_timestamp = ts; + else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns)) + u->inactive_enter_timestamp = ts; + + if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns)) + u->active_enter_timestamp = ts; + else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns)) + u->active_exit_timestamp = ts; + + timer_unit_notify(u, ns); + path_unit_notify(u, ns); + } + + if (UNIT_IS_INACTIVE_OR_FAILED(ns)) + cgroup_bonding_trim_list(u->cgroup_bondings, true); + + if (u->job) { + unexpected = false; + + if (u->job->state == JOB_WAITING) + + /* So we reached a different state for this + * job. Let's see if we can run it now if it + * failed previously due to EAGAIN. */ + job_add_to_run_queue(u->job); + + /* Let's check whether this state change constitutes a + * finished job, or maybe contradicts a running job and + * hence needs to invalidate jobs. */ + + switch (u->job->type) { + + case JOB_START: + case JOB_VERIFY_ACTIVE: + + if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) + job_finish_and_invalidate(u->job, JOB_DONE); + else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) { + unexpected = true; + + if (UNIT_IS_INACTIVE_OR_FAILED(ns)) + job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE); + } + + break; + + case JOB_RELOAD: + case JOB_RELOAD_OR_START: + + if (u->job->state == JOB_RUNNING) { + if (ns == UNIT_ACTIVE) + job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED); + else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) { + unexpected = true; + + if (UNIT_IS_INACTIVE_OR_FAILED(ns)) + job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE); + } + } + + break; + + case JOB_STOP: + case JOB_RESTART: + case JOB_TRY_RESTART: + + if (UNIT_IS_INACTIVE_OR_FAILED(ns)) + job_finish_and_invalidate(u->job, JOB_DONE); + else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) { + unexpected = true; + job_finish_and_invalidate(u->job, JOB_FAILED); + } + + break; + + default: + assert_not_reached("Job type unknown"); + } + + } else + unexpected = true; + + if (u->manager->n_reloading <= 0) { + + /* If this state change happened without being + * requested by a job, then let's retroactively start + * or stop dependencies. We skip that step when + * deserializing, since we don't want to create any + * additional jobs just because something is already + * activated. */ + + if (unexpected) { + if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns)) + retroactively_start_dependencies(u); + else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) + retroactively_stop_dependencies(u); + } + + /* stop unneeded units regardless if going down was expected or not */ + if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns)) + check_unneeded_dependencies(u); + + if (ns != os && ns == UNIT_FAILED) { + log_notice("Unit %s entered failed state.", u->id); + unit_trigger_on_failure(u); + } + } + + /* Some names are special */ + if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) { + + if (unit_has_name(u, SPECIAL_DBUS_SERVICE)) + /* The bus just might have become available, + * hence try to connect to it, if we aren't + * yet connected. */ + bus_init(u->manager, true); + + if (u->type == UNIT_SERVICE && + !UNIT_IS_ACTIVE_OR_RELOADING(os) && + u->manager->n_reloading <= 0) { + /* Write audit record if we have just finished starting up */ + manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_START, true); + u->in_audit = true; + } + + if (!UNIT_IS_ACTIVE_OR_RELOADING(os)) + manager_send_unit_plymouth(u->manager, u); + + } else { + + /* We don't care about D-Bus here, since we'll get an + * asynchronous notification for it anyway. */ + + if (u->type == UNIT_SERVICE && + UNIT_IS_INACTIVE_OR_FAILED(ns) && + !UNIT_IS_INACTIVE_OR_FAILED(os) && + u->manager->n_reloading <= 0) { + + /* Hmm, if there was no start record written + * write it now, so that we always have a nice + * pair */ + if (!u->in_audit) { + manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE); + + if (ns == UNIT_INACTIVE) + manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_STOP, true); + } else + /* Write audit record if we have just finished shutting down */ + manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE); + + u->in_audit = false; + } + } + + manager_recheck_journal(u->manager); + + /* Maybe we finished startup and are now ready for being + * stopped because unneeded? */ + unit_check_unneeded(u); + + unit_add_to_dbus_queue(u); + unit_add_to_gc_queue(u); +} + +int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) { + struct epoll_event ev; + + assert(u); + assert(fd >= 0); + assert(w); + assert(w->type == WATCH_INVALID || (w->type == WATCH_FD && w->fd == fd && w->data.unit == u)); + + zero(ev); + ev.data.ptr = w; + ev.events = events; + + if (epoll_ctl(u->manager->epoll_fd, + w->type == WATCH_INVALID ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, + fd, + &ev) < 0) + return -errno; + + w->fd = fd; + w->type = WATCH_FD; + w->data.unit = u; + + return 0; +} + +void unit_unwatch_fd(Unit *u, Watch *w) { + assert(u); + assert(w); + + if (w->type == WATCH_INVALID) + return; + + assert(w->type == WATCH_FD); + assert(w->data.unit == u); + assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0); + + w->fd = -1; + w->type = WATCH_INVALID; + w->data.unit = NULL; +} + +int unit_watch_pid(Unit *u, pid_t pid) { + assert(u); + assert(pid >= 1); + + /* Watch a specific PID. We only support one unit watching + * each PID for now. */ + + return hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u); +} + +void unit_unwatch_pid(Unit *u, pid_t pid) { + assert(u); + assert(pid >= 1); + + hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u); +} + +int unit_watch_timer(Unit *u, usec_t delay, Watch *w) { + struct itimerspec its; + int flags, fd; + bool ours; + + assert(u); + assert(w); + assert(w->type == WATCH_INVALID || (w->type == WATCH_UNIT_TIMER && w->data.unit == u)); + + /* This will try to reuse the old timer if there is one */ + + if (w->type == WATCH_UNIT_TIMER) { + assert(w->data.unit == u); + assert(w->fd >= 0); + + ours = false; + fd = w->fd; + } else if (w->type == WATCH_INVALID) { + + ours = true; + if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) + return -errno; + } else + assert_not_reached("Invalid watch type"); + + zero(its); + + if (delay <= 0) { + /* Set absolute time in the past, but not 0, since we + * don't want to disarm the timer */ + its.it_value.tv_sec = 0; + its.it_value.tv_nsec = 1; + + flags = TFD_TIMER_ABSTIME; + } else { + timespec_store(&its.it_value, delay); + flags = 0; + } + + /* This will also flush the elapse counter */ + if (timerfd_settime(fd, flags, &its, NULL) < 0) + goto fail; + + if (w->type == WATCH_INVALID) { + struct epoll_event ev; + + zero(ev); + ev.data.ptr = w; + ev.events = EPOLLIN; + + if (epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) + goto fail; + } + + w->type = WATCH_UNIT_TIMER; + w->fd = fd; + w->data.unit = u; + + return 0; + +fail: + if (ours) + close_nointr_nofail(fd); + + return -errno; +} + +void unit_unwatch_timer(Unit *u, Watch *w) { + assert(u); + assert(w); + + if (w->type == WATCH_INVALID) + return; + + assert(w->type == WATCH_UNIT_TIMER); + assert(w->data.unit == u); + assert(w->fd >= 0); + + assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0); + close_nointr_nofail(w->fd); + + w->fd = -1; + w->type = WATCH_INVALID; + w->data.unit = NULL; +} + +bool unit_job_is_applicable(Unit *u, JobType j) { + assert(u); + assert(j >= 0 && j < _JOB_TYPE_MAX); + + switch (j) { + + case JOB_VERIFY_ACTIVE: + case JOB_START: + case JOB_STOP: + return true; + + case JOB_RESTART: + case JOB_TRY_RESTART: + return unit_can_start(u); + + case JOB_RELOAD: + return unit_can_reload(u); + + case JOB_RELOAD_OR_START: + return unit_can_reload(u) && unit_can_start(u); + + default: + assert_not_reached("Invalid job type"); + } +} + +int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) { + + static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = { + [UNIT_REQUIRES] = UNIT_REQUIRED_BY, + [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE, + [UNIT_WANTS] = UNIT_WANTED_BY, + [UNIT_REQUISITE] = UNIT_REQUIRED_BY, + [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE, + [UNIT_BIND_TO] = UNIT_BOUND_BY, + [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID, + [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID, + [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID, + [UNIT_BOUND_BY] = UNIT_BIND_TO, + [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY, + [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS, + [UNIT_BEFORE] = UNIT_AFTER, + [UNIT_AFTER] = UNIT_BEFORE, + [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID, + [UNIT_REFERENCES] = UNIT_REFERENCED_BY, + [UNIT_REFERENCED_BY] = UNIT_REFERENCES, + [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY, + [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS, + [UNIT_PROPAGATE_RELOAD_TO] = UNIT_PROPAGATE_RELOAD_FROM, + [UNIT_PROPAGATE_RELOAD_FROM] = UNIT_PROPAGATE_RELOAD_TO + }; + int r, q = 0, v = 0, w = 0; + + assert(u); + assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX); + assert(other); + + u = unit_follow_merge(u); + other = unit_follow_merge(other); + + /* We won't allow dependencies on ourselves. We will not + * consider them an error however. */ + if (u == other) + return 0; + + if ((r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func)) < 0) + return r; + + if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID) + if ((r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0) + return r; + + if (add_reference) + if ((r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 || + (r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0) + return r; + + if ((q = set_put(u->dependencies[d], other)) < 0) + return q; + + if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID) + if ((v = set_put(other->dependencies[inverse_table[d]], u)) < 0) { + r = v; + goto fail; + } + + if (add_reference) { + if ((w = set_put(u->dependencies[UNIT_REFERENCES], other)) < 0) { + r = w; + goto fail; + } + + if ((r = set_put(other->dependencies[UNIT_REFERENCED_BY], u)) < 0) + goto fail; + } + + unit_add_to_dbus_queue(u); + return 0; + +fail: + if (q > 0) + set_remove(u->dependencies[d], other); + + if (v > 0) + set_remove(other->dependencies[inverse_table[d]], u); + + if (w > 0) + set_remove(u->dependencies[UNIT_REFERENCES], other); + + return r; +} + +int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) { + int r; + + assert(u); + + if ((r = unit_add_dependency(u, d, other, add_reference)) < 0) + return r; + + if ((r = unit_add_dependency(u, e, other, add_reference)) < 0) + return r; + + return 0; +} + +static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) { + char *s; + + assert(u); + assert(name || path); + + if (!name) + name = file_name_from_path(path); + + if (!unit_name_is_template(name)) { + *p = NULL; + return name; + } + + if (u->instance) + s = unit_name_replace_instance(name, u->instance); + else { + char *i; + + if (!(i = unit_name_to_prefix(u->id))) + return NULL; + + s = unit_name_replace_instance(name, i); + free(i); + } + + if (!s) + return NULL; + + *p = s; + return s; +} + +int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) { + Unit *other; + int r; + char *s; + + assert(u); + assert(name || path); + + if (!(name = resolve_template(u, name, path, &s))) + return -ENOMEM; + + if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0) + goto finish; + + r = unit_add_dependency(u, d, other, add_reference); + +finish: + free(s); + return r; +} + +int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) { + Unit *other; + int r; + char *s; + + assert(u); + assert(name || path); + + if (!(name = resolve_template(u, name, path, &s))) + return -ENOMEM; + + if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0) + goto finish; + + r = unit_add_two_dependencies(u, d, e, other, add_reference); + +finish: + free(s); + return r; +} + +int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) { + Unit *other; + int r; + char *s; + + assert(u); + assert(name || path); + + if (!(name = resolve_template(u, name, path, &s))) + return -ENOMEM; + + if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0) + goto finish; + + r = unit_add_dependency(other, d, u, add_reference); + +finish: + free(s); + return r; +} + +int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) { + Unit *other; + int r; + char *s; + + assert(u); + assert(name || path); + + if (!(name = resolve_template(u, name, path, &s))) + return -ENOMEM; + + if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0) + goto finish; + + if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0) + goto finish; + +finish: + free(s); + return r; +} + +int set_unit_path(const char *p) { + char *cwd, *c; + int r; + + /* This is mostly for debug purposes */ + + if (path_is_absolute(p)) { + if (!(c = strdup(p))) + return -ENOMEM; + } else { + if (!(cwd = get_current_dir_name())) + return -errno; + + r = asprintf(&c, "%s/%s", cwd, p); + free(cwd); + + if (r < 0) + return -ENOMEM; + } + + if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0) { + r = -errno; + free(c); + return r; + } + + return 0; +} + +char *unit_dbus_path(Unit *u) { + char *p, *e; + + assert(u); + + if (!u->id) + return NULL; + + if (!(e = bus_path_escape(u->id))) + return NULL; + + p = strappend("/org/freedesktop/systemd1/unit/", e); + free(e); + + return p; +} + +int unit_add_cgroup(Unit *u, CGroupBonding *b) { + int r; + + assert(u); + assert(b); + + assert(b->path); + + if (!b->controller) { + if (!(b->controller = strdup(SYSTEMD_CGROUP_CONTROLLER))) + return -ENOMEM; + + b->ours = true; + } + + /* Ensure this hasn't been added yet */ + assert(!b->unit); + + if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) { + CGroupBonding *l; + + l = hashmap_get(u->manager->cgroup_bondings, b->path); + LIST_PREPEND(CGroupBonding, by_path, l, b); + + if ((r = hashmap_replace(u->manager->cgroup_bondings, b->path, l)) < 0) { + LIST_REMOVE(CGroupBonding, by_path, l, b); + return r; + } + } + + LIST_PREPEND(CGroupBonding, by_unit, u->cgroup_bondings, b); + b->unit = u; + + return 0; +} + +static char *default_cgroup_path(Unit *u) { + char *p; + + assert(u); + + if (u->instance) { + char *t; + + t = unit_name_template(u->id); + if (!t) + return NULL; + + p = join(u->manager->cgroup_hierarchy, "/", t, "/", u->instance, NULL); + free(t); + } else + p = join(u->manager->cgroup_hierarchy, "/", u->id, NULL); + + return p; +} + +int unit_add_cgroup_from_text(Unit *u, const char *name) { + char *controller = NULL, *path = NULL; + CGroupBonding *b = NULL; + bool ours = false; + int r; + + assert(u); + assert(name); + + if ((r = cg_split_spec(name, &controller, &path)) < 0) + return r; + + if (!path) { + path = default_cgroup_path(u); + ours = true; + } + + if (!controller) { + controller = strdup(SYSTEMD_CGROUP_CONTROLLER); + ours = true; + } + + if (!path || !controller) { + free(path); + free(controller); + + return -ENOMEM; + } + + if (cgroup_bonding_find_list(u->cgroup_bondings, controller)) { + r = -EEXIST; + goto fail; + } + + if (!(b = new0(CGroupBonding, 1))) { + r = -ENOMEM; + goto fail; + } + + b->controller = controller; + b->path = path; + b->ours = ours; + b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER); + + if ((r = unit_add_cgroup(u, b)) < 0) + goto fail; + + return 0; + +fail: + free(path); + free(controller); + free(b); + + return r; +} + +static int unit_add_one_default_cgroup(Unit *u, const char *controller) { + CGroupBonding *b = NULL; + int r = -ENOMEM; + + assert(u); + + if (!controller) + controller = SYSTEMD_CGROUP_CONTROLLER; + + if (cgroup_bonding_find_list(u->cgroup_bondings, controller)) + return 0; + + if (!(b = new0(CGroupBonding, 1))) + return -ENOMEM; + + if (!(b->controller = strdup(controller))) + goto fail; + + if (!(b->path = default_cgroup_path(u))) + goto fail; + + b->ours = true; + b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER); + + if ((r = unit_add_cgroup(u, b)) < 0) + goto fail; + + return 0; + +fail: + free(b->path); + free(b->controller); + free(b); + + return r; +} + +int unit_add_default_cgroups(Unit *u) { + CGroupAttribute *a; + char **c; + int r; + + assert(u); + + /* Adds in the default cgroups, if they weren't specified + * otherwise. */ + + if (!u->manager->cgroup_hierarchy) + return 0; + + if ((r = unit_add_one_default_cgroup(u, NULL)) < 0) + return r; + + STRV_FOREACH(c, u->manager->default_controllers) + unit_add_one_default_cgroup(u, *c); + + LIST_FOREACH(by_unit, a, u->cgroup_attributes) + unit_add_one_default_cgroup(u, a->controller); + + return 0; +} + +CGroupBonding* unit_get_default_cgroup(Unit *u) { + assert(u); + + return cgroup_bonding_find_list(u->cgroup_bondings, SYSTEMD_CGROUP_CONTROLLER); +} + +int unit_add_cgroup_attribute(Unit *u, const char *controller, const char *name, const char *value, CGroupAttributeMapCallback map_callback) { + int r; + char *c = NULL; + CGroupAttribute *a; + + assert(u); + assert(name); + assert(value); + + if (!controller) { + const char *dot; + + dot = strchr(name, '.'); + if (!dot) + return -EINVAL; + + c = strndup(name, dot - name); + if (!c) + return -ENOMEM; + + controller = c; + } + + if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) { + r = -EINVAL; + goto finish; + } + + a = new0(CGroupAttribute, 1); + if (!a) { + r = -ENOMEM; + goto finish; + } + + if (c) { + a->controller = c; + c = NULL; + } else + a->controller = strdup(controller); + + a->name = strdup(name); + a->value = strdup(value); + + if (!a->controller || !a->name || !a->value) { + free(a->controller); + free(a->name); + free(a->value); + free(a); + + return -ENOMEM; + } + + a->map_callback = map_callback; + + LIST_PREPEND(CGroupAttribute, by_unit, u->cgroup_attributes, a); + + r = 0; + +finish: + free(c); + return r; +} + +int unit_load_related_unit(Unit *u, const char *type, Unit **_found) { + char *t; + int r; + + assert(u); + assert(type); + assert(_found); + + if (!(t = unit_name_change_suffix(u->id, type))) + return -ENOMEM; + + assert(!unit_has_name(u, t)); + + r = manager_load_unit(u->manager, t, NULL, NULL, _found); + free(t); + + assert(r < 0 || *_found != u); + + return r; +} + +int unit_get_related_unit(Unit *u, const char *type, Unit **_found) { + Unit *found; + char *t; + + assert(u); + assert(type); + assert(_found); + + if (!(t = unit_name_change_suffix(u->id, type))) + return -ENOMEM; + + assert(!unit_has_name(u, t)); + + found = manager_get_unit(u->manager, t); + free(t); + + if (!found) + return -ENOENT; + + *_found = found; + return 0; +} + +static char *specifier_prefix_and_instance(char specifier, void *data, void *userdata) { + Unit *u = userdata; + assert(u); + + return unit_name_to_prefix_and_instance(u->id); +} + +static char *specifier_prefix(char specifier, void *data, void *userdata) { + Unit *u = userdata; + assert(u); + + return unit_name_to_prefix(u->id); +} + +static char *specifier_prefix_unescaped(char specifier, void *data, void *userdata) { + Unit *u = userdata; + char *p, *r; + + assert(u); + + if (!(p = unit_name_to_prefix(u->id))) + return NULL; + + r = unit_name_unescape(p); + free(p); + + return r; +} + +static char *specifier_instance_unescaped(char specifier, void *data, void *userdata) { + Unit *u = userdata; + assert(u); + + if (u->instance) + return unit_name_unescape(u->instance); + + return strdup(""); +} + +static char *specifier_filename(char specifier, void *data, void *userdata) { + Unit *u = userdata; + assert(u); + + if (u->instance) + return unit_name_path_unescape(u->instance); + + return unit_name_to_path(u->instance); +} + +static char *specifier_cgroup(char specifier, void *data, void *userdata) { + Unit *u = userdata; + assert(u); + + return default_cgroup_path(u); +} + +static char *specifier_cgroup_root(char specifier, void *data, void *userdata) { + Unit *u = userdata; + char *p; + assert(u); + + if (specifier == 'r') + return strdup(u->manager->cgroup_hierarchy); + + if (parent_of_path(u->manager->cgroup_hierarchy, &p) < 0) + return strdup(""); + + if (streq(p, "/")) { + free(p); + return strdup(""); + } + + return p; +} + +static char *specifier_runtime(char specifier, void *data, void *userdata) { + Unit *u = userdata; + assert(u); + + if (u->manager->running_as == MANAGER_USER) { + const char *e; + + e = getenv("XDG_RUNTIME_DIR"); + if (e) + return strdup(e); + } + + return strdup("/run"); +} + +char *unit_name_printf(Unit *u, const char* format) { + + /* + * This will use the passed string as format string and + * replace the following specifiers: + * + * %n: the full id of the unit (foo@bar.waldo) + * %N: the id of the unit without the suffix (foo@bar) + * %p: the prefix (foo) + * %i: the instance (bar) + */ + + const Specifier table[] = { + { 'n', specifier_string, u->id }, + { 'N', specifier_prefix_and_instance, NULL }, + { 'p', specifier_prefix, NULL }, + { 'i', specifier_string, u->instance }, + { 0, NULL, NULL } + }; + + assert(u); + assert(format); + + return specifier_printf(format, table, u); +} + +char *unit_full_printf(Unit *u, const char *format) { + + /* This is similar to unit_name_printf() but also supports + * unescaping. Also, adds a couple of additional codes: + * + * %c cgroup path of unit + * %r root cgroup path of this systemd instance (e.g. "/user/lennart/shared/systemd-4711") + * %R parent of root cgroup path (e.g. "/usr/lennart/shared") + * %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR) + */ + + const Specifier table[] = { + { 'n', specifier_string, u->id }, + { 'N', specifier_prefix_and_instance, NULL }, + { 'p', specifier_prefix, NULL }, + { 'P', specifier_prefix_unescaped, NULL }, + { 'i', specifier_string, u->instance }, + { 'I', specifier_instance_unescaped, NULL }, + { 'f', specifier_filename, NULL }, + { 'c', specifier_cgroup, NULL }, + { 'r', specifier_cgroup_root, NULL }, + { 'R', specifier_cgroup_root, NULL }, + { 't', specifier_runtime, NULL }, + { 0, NULL, NULL } + }; + + assert(u); + assert(format); + + return specifier_printf(format, table, u); +} + +char **unit_full_printf_strv(Unit *u, char **l) { + size_t n; + char **r, **i, **j; + + /* Applies unit_full_printf to every entry in l */ + + assert(u); + + n = strv_length(l); + if (!(r = new(char*, n+1))) + return NULL; + + for (i = l, j = r; *i; i++, j++) + if (!(*j = unit_full_printf(u, *i))) + goto fail; + + *j = NULL; + return r; + +fail: + for (j--; j >= r; j--) + free(*j); + + free(r); + + return NULL; +} + +int unit_watch_bus_name(Unit *u, const char *name) { + assert(u); + assert(name); + + /* Watch a specific name on the bus. We only support one unit + * watching each name for now. */ + + return hashmap_put(u->manager->watch_bus, name, u); +} + +void unit_unwatch_bus_name(Unit *u, const char *name) { + assert(u); + assert(name); + + hashmap_remove_value(u->manager->watch_bus, name, u); +} + +bool unit_can_serialize(Unit *u) { + assert(u); + + return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item; +} + +int unit_serialize(Unit *u, FILE *f, FDSet *fds) { + int r; + + assert(u); + assert(f); + assert(fds); + + if (!unit_can_serialize(u)) + return 0; + + if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0) + return r; + + if (u->job) + unit_serialize_item(u, f, "job", job_type_to_string(u->job->type)); + + dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp); + dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp); + dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp); + dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp); + dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp); + + if (dual_timestamp_is_set(&u->condition_timestamp)) + unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result)); + + /* End marker */ + fputc('\n', f); + return 0; +} + +void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) { + va_list ap; + + assert(u); + assert(f); + assert(key); + assert(format); + + fputs(key, f); + fputc('=', f); + + va_start(ap, format); + vfprintf(f, format, ap); + va_end(ap); + + fputc('\n', f); +} + +void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) { + assert(u); + assert(f); + assert(key); + assert(value); + + fprintf(f, "%s=%s\n", key, value); +} + +int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { + int r; + + assert(u); + assert(f); + assert(fds); + + if (!unit_can_serialize(u)) + return 0; + + for (;;) { + char line[LINE_MAX], *l, *v; + size_t k; + + if (!fgets(line, sizeof(line), f)) { + if (feof(f)) + return 0; + return -errno; + } + + char_array_0(line); + l = strstrip(line); + + /* End marker */ + if (l[0] == 0) + return 0; + + k = strcspn(l, "="); + + if (l[k] == '=') { + l[k] = 0; + v = l+k+1; + } else + v = l+k; + + if (streq(l, "job")) { + JobType type; + + if ((type = job_type_from_string(v)) < 0) + log_debug("Failed to parse job type value %s", v); + else + u->deserialized_job = type; + + continue; + } else if (streq(l, "inactive-exit-timestamp")) { + dual_timestamp_deserialize(v, &u->inactive_exit_timestamp); + continue; + } else if (streq(l, "active-enter-timestamp")) { + dual_timestamp_deserialize(v, &u->active_enter_timestamp); + continue; + } else if (streq(l, "active-exit-timestamp")) { + dual_timestamp_deserialize(v, &u->active_exit_timestamp); + continue; + } else if (streq(l, "inactive-enter-timestamp")) { + dual_timestamp_deserialize(v, &u->inactive_enter_timestamp); + continue; + } else if (streq(l, "condition-timestamp")) { + dual_timestamp_deserialize(v, &u->condition_timestamp); + continue; + } else if (streq(l, "condition-result")) { + int b; + + if ((b = parse_boolean(v)) < 0) + log_debug("Failed to parse condition result value %s", v); + else + u->condition_result = b; + + continue; + } + + if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0) + return r; + } +} + +int unit_add_node_link(Unit *u, const char *what, bool wants) { + Unit *device; + char *e; + int r; + + assert(u); + + if (!what) + return 0; + + /* Adds in links to the device node that this unit is based on */ + + if (!is_device_path(what)) + return 0; + + if (!(e = unit_name_build_escape(what+1, NULL, ".device"))) + return -ENOMEM; + + r = manager_load_unit(u->manager, e, NULL, NULL, &device); + free(e); + + if (r < 0) + return r; + + if ((r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BIND_TO, device, true)) < 0) + return r; + + if (wants) + if ((r = unit_add_dependency(device, UNIT_WANTS, u, false)) < 0) + return r; + + return 0; +} + +int unit_coldplug(Unit *u) { + int r; + + assert(u); + + if (UNIT_VTABLE(u)->coldplug) + if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0) + return r; + + if (u->deserialized_job >= 0) { + if ((r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL)) < 0) + return r; + + u->deserialized_job = _JOB_TYPE_INVALID; + } + + return 0; +} + +void unit_status_printf(Unit *u, const char *status, const char *format, ...) { + va_list ap; + + assert(u); + assert(format); + + if (!UNIT_VTABLE(u)->show_status) + return; + + if (!manager_get_show_status(u->manager)) + return; + + if (!manager_is_booting_or_shutting_down(u->manager)) + return; + + va_start(ap, format); + status_vprintf(status, true, format, ap); + va_end(ap); +} + +bool unit_need_daemon_reload(Unit *u) { + assert(u); + + if (u->fragment_path) { + struct stat st; + + zero(st); + if (stat(u->fragment_path, &st) < 0) + /* What, cannot access this anymore? */ + return true; + + if (u->fragment_mtime > 0 && + timespec_load(&st.st_mtim) != u->fragment_mtime) + return true; + } + + if (UNIT_VTABLE(u)->need_daemon_reload) + return UNIT_VTABLE(u)->need_daemon_reload(u); + + return false; +} + +void unit_reset_failed(Unit *u) { + assert(u); + + if (UNIT_VTABLE(u)->reset_failed) + UNIT_VTABLE(u)->reset_failed(u); +} + +Unit *unit_following(Unit *u) { + assert(u); + + if (UNIT_VTABLE(u)->following) + return UNIT_VTABLE(u)->following(u); + + return NULL; +} + +bool unit_pending_inactive(Unit *u) { + assert(u); + + /* Returns true if the unit is inactive or going down */ + + if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u))) + return true; + + if (u->job && u->job->type == JOB_STOP) + return true; + + return false; +} + +bool unit_pending_active(Unit *u) { + assert(u); + + /* Returns true if the unit is active or going up */ + + if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) + return true; + + if (u->job && + (u->job->type == JOB_START || + u->job->type == JOB_RELOAD_OR_START || + u->job->type == JOB_RESTART)) + return true; + + return false; +} + +UnitType unit_name_to_type(const char *n) { + UnitType t; + + assert(n); + + for (t = 0; t < _UNIT_TYPE_MAX; t++) + if (endswith(n, unit_vtable[t]->suffix)) + return t; + + return _UNIT_TYPE_INVALID; +} + +bool unit_name_is_valid(const char *n, bool template_ok) { + UnitType t; + + t = unit_name_to_type(n); + if (t < 0 || t >= _UNIT_TYPE_MAX) + return false; + + return unit_name_is_valid_no_type(n, template_ok); +} + +int unit_kill(Unit *u, KillWho w, KillMode m, int signo, DBusError *error) { + assert(u); + assert(w >= 0 && w < _KILL_WHO_MAX); + assert(m >= 0 && m < _KILL_MODE_MAX); + assert(signo > 0); + assert(signo < _NSIG); + + if (m == KILL_NONE) + return 0; + + if (!UNIT_VTABLE(u)->kill) + return -ENOTSUP; + + return UNIT_VTABLE(u)->kill(u, w, m, signo, error); +} + +int unit_following_set(Unit *u, Set **s) { + assert(u); + assert(s); + + if (UNIT_VTABLE(u)->following_set) + return UNIT_VTABLE(u)->following_set(u, s); + + *s = NULL; + return 0; +} + +UnitFileState unit_get_unit_file_state(Unit *u) { + assert(u); + + if (u->unit_file_state < 0 && u->fragment_path) + u->unit_file_state = unit_file_get_state( + u->manager->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, + NULL, file_name_from_path(u->fragment_path)); + + return u->unit_file_state; +} + +Unit* unit_ref_set(UnitRef *ref, Unit *u) { + assert(ref); + assert(u); + + if (ref->unit) + unit_ref_unset(ref); + + ref->unit = u; + LIST_PREPEND(UnitRef, refs, u->refs, ref); + return u; +} + +void unit_ref_unset(UnitRef *ref) { + assert(ref); + + if (!ref->unit) + return; + + LIST_REMOVE(UnitRef, refs, ref->unit->refs, ref); + ref->unit = NULL; +} + +static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = { + [UNIT_STUB] = "stub", + [UNIT_LOADED] = "loaded", + [UNIT_ERROR] = "error", + [UNIT_MERGED] = "merged", + [UNIT_MASKED] = "masked" +}; + +DEFINE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState); + +static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = { + [UNIT_ACTIVE] = "active", + [UNIT_RELOADING] = "reloading", + [UNIT_INACTIVE] = "inactive", + [UNIT_FAILED] = "failed", + [UNIT_ACTIVATING] = "activating", + [UNIT_DEACTIVATING] = "deactivating" +}; + +DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState); + +static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = { + [UNIT_REQUIRES] = "Requires", + [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable", + [UNIT_WANTS] = "Wants", + [UNIT_REQUISITE] = "Requisite", + [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable", + [UNIT_REQUIRED_BY] = "RequiredBy", + [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable", + [UNIT_BIND_TO] = "BindTo", + [UNIT_WANTED_BY] = "WantedBy", + [UNIT_CONFLICTS] = "Conflicts", + [UNIT_CONFLICTED_BY] = "ConflictedBy", + [UNIT_BOUND_BY] = "BoundBy", + [UNIT_BEFORE] = "Before", + [UNIT_AFTER] = "After", + [UNIT_REFERENCES] = "References", + [UNIT_REFERENCED_BY] = "ReferencedBy", + [UNIT_ON_FAILURE] = "OnFailure", + [UNIT_TRIGGERS] = "Triggers", + [UNIT_TRIGGERED_BY] = "TriggeredBy", + [UNIT_PROPAGATE_RELOAD_TO] = "PropagateReloadTo", + [UNIT_PROPAGATE_RELOAD_FROM] = "PropagateReloadFrom" +}; + +DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency); diff --git a/src/unit.h b/src/unit.h new file mode 100644 index 0000000..756f465 --- /dev/null +++ b/src/unit.h @@ -0,0 +1,562 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foounithfoo +#define foounithfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include + +typedef struct Unit Unit; +typedef struct UnitVTable UnitVTable; +typedef enum UnitType UnitType; +typedef enum UnitLoadState UnitLoadState; +typedef enum UnitActiveState UnitActiveState; +typedef enum UnitDependency UnitDependency; +typedef struct UnitRef UnitRef; + +#include "set.h" +#include "util.h" +#include "list.h" +#include "socket-util.h" +#include "execute.h" +#include "condition.h" +#include "install.h" + +enum UnitType { + UNIT_SERVICE = 0, + UNIT_SOCKET, + UNIT_TARGET, + UNIT_DEVICE, + UNIT_MOUNT, + UNIT_AUTOMOUNT, + UNIT_SNAPSHOT, + UNIT_TIMER, + UNIT_SWAP, + UNIT_PATH, + _UNIT_TYPE_MAX, + _UNIT_TYPE_INVALID = -1 +}; + +enum UnitLoadState { + UNIT_STUB, + UNIT_LOADED, + UNIT_ERROR, + UNIT_MERGED, + UNIT_MASKED, + _UNIT_LOAD_STATE_MAX, + _UNIT_LOAD_STATE_INVALID = -1 +}; + +enum UnitActiveState { + UNIT_ACTIVE, + UNIT_RELOADING, + UNIT_INACTIVE, + UNIT_FAILED, + UNIT_ACTIVATING, + UNIT_DEACTIVATING, + _UNIT_ACTIVE_STATE_MAX, + _UNIT_ACTIVE_STATE_INVALID = -1 +}; + +static inline bool UNIT_IS_ACTIVE_OR_RELOADING(UnitActiveState t) { + return t == UNIT_ACTIVE || t == UNIT_RELOADING; +} + +static inline bool UNIT_IS_ACTIVE_OR_ACTIVATING(UnitActiveState t) { + return t == UNIT_ACTIVE || t == UNIT_ACTIVATING || t == UNIT_RELOADING; +} + +static inline bool UNIT_IS_INACTIVE_OR_DEACTIVATING(UnitActiveState t) { + return t == UNIT_INACTIVE || t == UNIT_FAILED || t == UNIT_DEACTIVATING; +} + +static inline bool UNIT_IS_INACTIVE_OR_FAILED(UnitActiveState t) { + return t == UNIT_INACTIVE || t == UNIT_FAILED; +} + +enum UnitDependency { + /* Positive dependencies */ + UNIT_REQUIRES, + UNIT_REQUIRES_OVERRIDABLE, + UNIT_REQUISITE, + UNIT_REQUISITE_OVERRIDABLE, + UNIT_WANTS, + UNIT_BIND_TO, + + /* Inverse of the above */ + UNIT_REQUIRED_BY, /* inverse of 'requires' and 'requisite' is 'required_by' */ + UNIT_REQUIRED_BY_OVERRIDABLE, /* inverse of 'requires_overridable' and 'requisite_overridable' is 'soft_required_by' */ + UNIT_WANTED_BY, /* inverse of 'wants' */ + UNIT_BOUND_BY, /* inverse of 'bind_to' */ + + /* Negative dependencies */ + UNIT_CONFLICTS, /* inverse of 'conflicts' is 'conflicted_by' */ + UNIT_CONFLICTED_BY, + + /* Order */ + UNIT_BEFORE, /* inverse of 'before' is 'after' and vice versa */ + UNIT_AFTER, + + /* On Failure */ + UNIT_ON_FAILURE, + + /* Triggers (i.e. a socket triggers a service) */ + UNIT_TRIGGERS, + UNIT_TRIGGERED_BY, + + /* Propagate reloads */ + UNIT_PROPAGATE_RELOAD_TO, + UNIT_PROPAGATE_RELOAD_FROM, + + /* Reference information for GC logic */ + UNIT_REFERENCES, /* Inverse of 'references' is 'referenced_by' */ + UNIT_REFERENCED_BY, + + _UNIT_DEPENDENCY_MAX, + _UNIT_DEPENDENCY_INVALID = -1 +}; + +#include "manager.h" +#include "job.h" +#include "cgroup.h" +#include "cgroup-attr.h" + +struct Unit { + Manager *manager; + + UnitType type; + UnitLoadState load_state; + Unit *merged_into; + + char *id; /* One name is special because we use it for identification. Points to an entry in the names set */ + char *instance; + + Set *names; + Set *dependencies[_UNIT_DEPENDENCY_MAX]; + + char *description; + + char *fragment_path; /* if loaded from a config file this is the primary path to it */ + usec_t fragment_mtime; + + /* If there is something to do with this unit, then this is + * the job for it */ + Job *job; + + usec_t job_timeout; + + /* References to this */ + LIST_HEAD(UnitRef, refs); + + /* Conditions to check */ + LIST_HEAD(Condition, conditions); + + dual_timestamp condition_timestamp; + + dual_timestamp inactive_exit_timestamp; + dual_timestamp active_enter_timestamp; + dual_timestamp active_exit_timestamp; + dual_timestamp inactive_enter_timestamp; + + /* Counterparts in the cgroup filesystem */ + CGroupBonding *cgroup_bondings; + CGroupAttribute *cgroup_attributes; + + /* Per type list */ + LIST_FIELDS(Unit, units_by_type); + + /* Load queue */ + LIST_FIELDS(Unit, load_queue); + + /* D-Bus queue */ + LIST_FIELDS(Unit, dbus_queue); + + /* Cleanup queue */ + LIST_FIELDS(Unit, cleanup_queue); + + /* GC queue */ + LIST_FIELDS(Unit, gc_queue); + + /* Used during GC sweeps */ + unsigned gc_marker; + + /* When deserializing, temporarily store the job type for this + * unit here, if there was a job scheduled */ + int deserialized_job; /* This is actually of type JobType */ + + /* Error code when we didn't manage to load the unit (negative) */ + int load_error; + + /* Cached unit file state */ + UnitFileState unit_file_state; + + /* Garbage collect us we nobody wants or requires us anymore */ + bool stop_when_unneeded; + + /* Create default dependencies */ + bool default_dependencies; + + /* Refuse manual starting, allow starting only indirectly via dependency. */ + bool refuse_manual_start; + + /* Don't allow the user to stop this unit manually, allow stopping only indirectly via dependency. */ + bool refuse_manual_stop; + + /* Allow isolation requests */ + bool allow_isolate; + + /* Isolate OnFailure unit */ + bool on_failure_isolate; + + /* Ignore this unit when isolating */ + bool ignore_on_isolate; + + /* Ignore this unit when snapshotting */ + bool ignore_on_snapshot; + + /* Did the last condition check suceed? */ + bool condition_result; + + bool in_load_queue:1; + bool in_dbus_queue:1; + bool in_cleanup_queue:1; + bool in_gc_queue:1; + + bool sent_dbus_new_signal:1; + + bool no_gc:1; + + bool in_audit:1; +}; + +struct UnitRef { + /* Keeps tracks of references to a unit. This is useful so + * that we can merge two units if necessary and correct all + * references to them */ + + Unit* unit; + LIST_FIELDS(UnitRef, refs); +}; + +#include "service.h" +#include "timer.h" +#include "socket.h" +#include "target.h" +#include "device.h" +#include "mount.h" +#include "automount.h" +#include "snapshot.h" +#include "swap.h" +#include "path.h" + +struct UnitVTable { + const char *suffix; + + /* How much memory does an object of this unit type need */ + size_t object_size; + + /* Config file sections this unit type understands, separated + * by NUL chars */ + const char *sections; + + /* This should reset all type-specific variables. This should + * not allocate memory, and is called with zero-initialized + * data. It should hence only initialize variables that need + * to be set != 0. */ + void (*init)(Unit *u); + + /* This should free all type-specific variables. It should be + * idempotent. */ + void (*done)(Unit *u); + + /* Actually load data from disk. This may fail, and should set + * load_state to UNIT_LOADED, UNIT_MERGED or leave it at + * UNIT_STUB if no configuration could be found. */ + int (*load)(Unit *u); + + /* If a a lot of units got created via enumerate(), this is + * where to actually set the state and call unit_notify(). */ + int (*coldplug)(Unit *u); + + void (*dump)(Unit *u, FILE *f, const char *prefix); + + int (*start)(Unit *u); + int (*stop)(Unit *u); + int (*reload)(Unit *u); + + int (*kill)(Unit *u, KillWho w, KillMode m, int signo, DBusError *error); + + bool (*can_reload)(Unit *u); + + /* Write all data that cannot be restored from other sources + * away using unit_serialize_item() */ + int (*serialize)(Unit *u, FILE *f, FDSet *fds); + + /* Restore one item from the serialization */ + int (*deserialize_item)(Unit *u, const char *key, const char *data, FDSet *fds); + + /* Boils down the more complex internal state of this unit to + * a simpler one that the engine can understand */ + UnitActiveState (*active_state)(Unit *u); + + /* Returns the substate specific to this unit type as + * string. This is purely information so that we can give the + * user a more fine grained explanation in which actual state a + * unit is in. */ + const char* (*sub_state_to_string)(Unit *u); + + /* Return true when there is reason to keep this entry around + * even nothing references it and it isn't active in any + * way */ + bool (*check_gc)(Unit *u); + + /* Return true when this unit is suitable for snapshotting */ + bool (*check_snapshot)(Unit *u); + + void (*fd_event)(Unit *u, int fd, uint32_t events, Watch *w); + void (*sigchld_event)(Unit *u, pid_t pid, int code, int status); + void (*timer_event)(Unit *u, uint64_t n_elapsed, Watch *w); + + /* Check whether unit needs a daemon reload */ + bool (*need_daemon_reload)(Unit *u); + + /* Reset failed state if we are in failed state */ + void (*reset_failed)(Unit *u); + + /* Called whenever any of the cgroups this unit watches for + * ran empty */ + void (*cgroup_notify_empty)(Unit *u); + + /* Called whenever a process of this unit sends us a message */ + void (*notify_message)(Unit *u, pid_t pid, char **tags); + + /* Called whenever a name thus Unit registered for comes or + * goes away. */ + void (*bus_name_owner_change)(Unit *u, const char *name, const char *old_owner, const char *new_owner); + + /* Called whenever a bus PID lookup finishes */ + void (*bus_query_pid_done)(Unit *u, const char *name, pid_t pid); + + /* Called for each message received on the bus */ + DBusHandlerResult (*bus_message_handler)(Unit *u, DBusConnection *c, DBusMessage *message); + + /* Return the unit this unit is following */ + Unit *(*following)(Unit *u); + + /* Return the set of units that are following each other */ + int (*following_set)(Unit *u, Set **s); + + /* This is called for each unit type and should be used to + * enumerate existing devices and load them. However, + * everything that is loaded here should still stay in + * inactive state. It is the job of the coldplug() call above + * to put the units into the initial state. */ + int (*enumerate)(Manager *m); + + /* Type specific cleanups. */ + void (*shutdown)(Manager *m); + + /* When sending out PropertiesChanged signal, which properties + * shall be invalidated? This is a NUL separated list of + * strings, to minimize relocations a little. */ + const char *bus_invalidating_properties; + + /* The interface name */ + const char *bus_interface; + + /* Can units of this type have multiple names? */ + bool no_alias:1; + + /* Instances make no sense for this type */ + bool no_instances:1; + + /* Exclude from automatic gc */ + bool no_gc:1; + + /* Show status updates on the console */ + bool show_status:1; +}; + +extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX]; + +#define UNIT_VTABLE(u) unit_vtable[(u)->type] + +/* For casting a unit into the various unit types */ +#define DEFINE_CAST(UPPERCASE, MixedCase) \ + static inline MixedCase* UPPERCASE(Unit *u) { \ + if (_unlikely_(!u || u->type != UNIT_##UPPERCASE)) \ + return NULL; \ + \ + return (MixedCase*) u; \ + } + +/* For casting the various unit types into a unit */ +#define UNIT(u) (&(u)->meta) + +DEFINE_CAST(SOCKET, Socket); +DEFINE_CAST(TIMER, Timer); +DEFINE_CAST(SERVICE, Service); +DEFINE_CAST(TARGET, Target); +DEFINE_CAST(DEVICE, Device); +DEFINE_CAST(MOUNT, Mount); +DEFINE_CAST(AUTOMOUNT, Automount); +DEFINE_CAST(SNAPSHOT, Snapshot); +DEFINE_CAST(SWAP, Swap); +DEFINE_CAST(PATH, Path); + +Unit *unit_new(Manager *m, size_t size); +void unit_free(Unit *u); + +int unit_add_name(Unit *u, const char *name); + +int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference); +int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference); + +int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *filename, bool add_reference); +int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference); + +int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *filename, bool add_reference); +int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference); + +int unit_add_exec_dependencies(Unit *u, ExecContext *c); + +int unit_add_cgroup(Unit *u, CGroupBonding *b); +int unit_add_cgroup_from_text(Unit *u, const char *name); +int unit_add_default_cgroups(Unit *u); +CGroupBonding* unit_get_default_cgroup(Unit *u); +int unit_add_cgroup_attribute(Unit *u, const char *controller, const char *name, const char *value, CGroupAttributeMapCallback map_callback); + +int unit_choose_id(Unit *u, const char *name); +int unit_set_description(Unit *u, const char *description); + +bool unit_check_gc(Unit *u); + +void unit_add_to_load_queue(Unit *u); +void unit_add_to_dbus_queue(Unit *u); +void unit_add_to_cleanup_queue(Unit *u); +void unit_add_to_gc_queue(Unit *u); + +int unit_merge(Unit *u, Unit *other); +int unit_merge_by_name(Unit *u, const char *other); + +Unit *unit_follow_merge(Unit *u); + +int unit_load_fragment_and_dropin(Unit *u); +int unit_load_fragment_and_dropin_optional(Unit *u); +int unit_load(Unit *unit); + +const char *unit_description(Unit *u); + +bool unit_has_name(Unit *u, const char *name); + +UnitActiveState unit_active_state(Unit *u); + +const char* unit_sub_state_to_string(Unit *u); + +void unit_dump(Unit *u, FILE *f, const char *prefix); + +bool unit_can_reload(Unit *u); +bool unit_can_start(Unit *u); +bool unit_can_isolate(Unit *u); + +int unit_start(Unit *u); +int unit_stop(Unit *u); +int unit_reload(Unit *u); + +int unit_kill(Unit *u, KillWho w, KillMode m, int signo, DBusError *error); + +void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success); + +int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w); +void unit_unwatch_fd(Unit *u, Watch *w); + +int unit_watch_pid(Unit *u, pid_t pid); +void unit_unwatch_pid(Unit *u, pid_t pid); + +int unit_watch_timer(Unit *u, usec_t delay, Watch *w); +void unit_unwatch_timer(Unit *u, Watch *w); + +int unit_watch_bus_name(Unit *u, const char *name); +void unit_unwatch_bus_name(Unit *u, const char *name); + +bool unit_job_is_applicable(Unit *u, JobType j); + +int set_unit_path(const char *p); + +char *unit_dbus_path(Unit *u); + +int unit_load_related_unit(Unit *u, const char *type, Unit **_found); +int unit_get_related_unit(Unit *u, const char *type, Unit **_found); + +char *unit_name_printf(Unit *u, const char* text); +char *unit_full_printf(Unit *u, const char *text); +char **unit_full_printf_strv(Unit *u, char **l); + +bool unit_can_serialize(Unit *u); +int unit_serialize(Unit *u, FILE *f, FDSet *fds); +void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *value, ...) _printf_attr_(4,5); +void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value); +int unit_deserialize(Unit *u, FILE *f, FDSet *fds); + +int unit_add_node_link(Unit *u, const char *what, bool wants); + +int unit_coldplug(Unit *u); + +void unit_status_printf(Unit *u, const char *status, const char *format, ...); + +bool unit_need_daemon_reload(Unit *u); + +void unit_reset_failed(Unit *u); + +Unit *unit_following(Unit *u); + +bool unit_pending_inactive(Unit *u); +bool unit_pending_active(Unit *u); + +int unit_add_default_target_dependency(Unit *u, Unit *target); + +int unit_following_set(Unit *u, Set **s); + +UnitType unit_name_to_type(const char *n); +bool unit_name_is_valid(const char *n, bool template_ok); + +void unit_trigger_on_failure(Unit *u); + +bool unit_condition_test(Unit *u); + +UnitFileState unit_get_unit_file_state(Unit *u); + +Unit* unit_ref_set(UnitRef *ref, Unit *u); +void unit_ref_unset(UnitRef *ref); + +#define UNIT_DEREF(ref) ((ref).unit) + +const char *unit_load_state_to_string(UnitLoadState i); +UnitLoadState unit_load_state_from_string(const char *s); + +const char *unit_active_state_to_string(UnitActiveState i); +UnitActiveState unit_active_state_from_string(const char *s); + +const char *unit_dependency_to_string(UnitDependency i); +UnitDependency unit_dependency_from_string(const char *s); + +#endif diff --git a/src/update-utmp.c b/src/update-utmp.c new file mode 100644 index 0000000..0d177d6 --- /dev/null +++ b/src/update-utmp.c @@ -0,0 +1,423 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include + +#include + +#ifdef HAVE_AUDIT +#include +#endif + +#include "log.h" +#include "macro.h" +#include "util.h" +#include "special.h" +#include "utmp-wtmp.h" +#include "dbus-common.h" + +typedef struct Context { + DBusConnection *bus; +#ifdef HAVE_AUDIT + int audit_fd; +#endif +} Context; + +static usec_t get_startup_time(Context *c) { + const char + *interface = "org.freedesktop.systemd1.Manager", + *property = "StartupTimestamp"; + + DBusError error; + usec_t t = 0; + DBusMessage *m = NULL, *reply = NULL; + DBusMessageIter iter, sub; + + dbus_error_init(&error); + + assert(c); + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.DBus.Properties", + "Get"))) { + log_error("Could not allocate message."); + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(c->bus, m, -1, &error))) { + log_error("Failed to send command: %s", bus_error_message(&error)); + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT64) { + log_error("Failed to parse reply."); + goto finish; + } + + dbus_message_iter_get_basic(&sub, &t); + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return t; +} + +static int get_current_runlevel(Context *c) { + static const struct { + const int runlevel; + const char *special; + } table[] = { + /* The first target of this list that is active or has + * a job scheduled wins. We prefer runlevels 5 and 3 + * here over the others, since these are the main + * runlevels used on Fedora. It might make sense to + * change the order on some distributions. */ + { '5', SPECIAL_RUNLEVEL5_TARGET }, + { '3', SPECIAL_RUNLEVEL3_TARGET }, + { '4', SPECIAL_RUNLEVEL4_TARGET }, + { '2', SPECIAL_RUNLEVEL2_TARGET }, + { 'S', SPECIAL_RESCUE_TARGET }, + }; + const char + *interface = "org.freedesktop.systemd1.Unit", + *property = "ActiveState"; + + DBusMessage *m = NULL, *reply = NULL; + int r = 0; + unsigned i; + DBusError error; + + assert(c); + + dbus_error_init(&error); + + for (i = 0; i < ELEMENTSOF(table); i++) { + const char *path = NULL, *state; + DBusMessageIter iter, sub; + + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnit"))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &table[i].special, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + if (!(reply = dbus_connection_send_with_reply_and_block(c->bus, m, -1, &error))) { + dbus_error_free(&error); + continue; + } + + if (!dbus_message_get_args(reply, &error, + DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + dbus_message_unref(m); + if (!(m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get"))) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + dbus_message_unref(reply); + if (!(reply = dbus_connection_send_with_reply_and_block(c->bus, m, -1, &error))) { + log_error("Failed to send command: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_get_basic(&sub, &state); + + if (streq(state, "active") || streq(state, "reloading")) + r = table[i].runlevel; + + dbus_message_unref(m); + dbus_message_unref(reply); + m = reply = NULL; + + if (r) + break; + } + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static int on_reboot(Context *c) { + int r = 0, q; + usec_t t; + + assert(c); + + /* We finished start-up, so let's write the utmp + * record and send the audit msg */ + +#ifdef HAVE_AUDIT + if (c->audit_fd >= 0) + if (audit_log_user_message(c->audit_fd, AUDIT_SYSTEM_BOOT, "init", NULL, NULL, NULL, 1) < 0) { + log_error("Failed to send audit message: %m"); + r = -errno; + } +#endif + + /* If this call fails it will return 0, which + * utmp_put_reboot() will then fix to the current time */ + t = get_startup_time(c); + + if ((q = utmp_put_reboot(t)) < 0) { + log_error("Failed to write utmp record: %s", strerror(-q)); + r = q; + } + + return r; +} + +static int on_shutdown(Context *c) { + int r = 0, q; + + assert(c); + + /* We started shut-down, so let's write the utmp + * record and send the audit msg */ + +#ifdef HAVE_AUDIT + if (c->audit_fd >= 0) + if (audit_log_user_message(c->audit_fd, AUDIT_SYSTEM_SHUTDOWN, "init", NULL, NULL, NULL, 1) < 0) { + log_error("Failed to send audit message: %m"); + r = -errno; + } +#endif + + if ((q = utmp_put_shutdown()) < 0) { + log_error("Failed to write utmp record: %s", strerror(-q)); + r = q; + } + + return r; +} + +static int on_runlevel(Context *c) { + int r = 0, q, previous, runlevel; + + assert(c); + + /* We finished changing runlevel, so let's write the + * utmp record and send the audit msg */ + + /* First, get last runlevel */ + if ((q = utmp_get_runlevel(&previous, NULL)) < 0) { + + if (q != -ESRCH && q != -ENOENT) { + log_error("Failed to get current runlevel: %s", strerror(-q)); + return q; + } + + /* Hmm, we didn't find any runlevel, that means we + * have been rebooted */ + r = on_reboot(c); + previous = 0; + } + + /* Secondly, get new runlevel */ + if ((runlevel = get_current_runlevel(c)) < 0) + return runlevel; + + if (previous == runlevel) + return 0; + +#ifdef HAVE_AUDIT + if (c->audit_fd >= 0) { + char *s = NULL; + + if (asprintf(&s, "old-level=%c new-level=%c", + previous > 0 ? previous : 'N', + runlevel > 0 ? runlevel : 'N') < 0) + return -ENOMEM; + + if (audit_log_user_message(c->audit_fd, AUDIT_SYSTEM_RUNLEVEL, s, NULL, NULL, NULL, 1) < 0) { + log_error("Failed to send audit message: %m"); + r = -errno; + } + + free(s); + } +#endif + + if ((q = utmp_put_runlevel(runlevel, previous)) < 0) { + log_error("Failed to write utmp record: %s", strerror(-q)); + r = q; + } + + return r; +} + +int main(int argc, char *argv[]) { + int r; + DBusError error; + Context c; + + dbus_error_init(&error); + + zero(c); +#ifdef HAVE_AUDIT + c.audit_fd = -1; +#endif + + if (getppid() != 1) { + log_error("This program should be invoked by init only."); + return EXIT_FAILURE; + } + + if (argc != 2) { + log_error("This program requires one argument."); + return EXIT_FAILURE; + } + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + +#ifdef HAVE_AUDIT + if ((c.audit_fd = audit_open()) < 0 && + /* If the kernel lacks netlink or audit support, + * don't worry about it. */ + errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT) + log_error("Failed to connect to audit log: %m"); +#endif + + if (bus_connect(DBUS_BUS_SYSTEM, &c.bus, NULL, &error) < 0) { + log_error("Failed to get D-Bus connection: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + log_debug("systemd-update-utmp running as pid %lu", (unsigned long) getpid()); + + if (streq(argv[1], "reboot")) + r = on_reboot(&c); + else if (streq(argv[1], "shutdown")) + r = on_shutdown(&c); + else if (streq(argv[1], "runlevel")) + r = on_runlevel(&c); + else { + log_error("Unknown command %s", argv[1]); + r = -EINVAL; + } + + log_debug("systemd-update-utmp stopped as pid %lu", (unsigned long) getpid()); + +finish: +#ifdef HAVE_AUDIT + if (c.audit_fd >= 0) + audit_close(c.audit_fd); +#endif + + if (c.bus) { + dbus_connection_flush(c.bus); + dbus_connection_close(c.bus); + dbus_connection_unref(c.bus); + } + + dbus_error_free(&error); + dbus_shutdown(); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/src/user.conf b/src/user.conf new file mode 100644 index 0000000..9508a02 --- /dev/null +++ b/src/user.conf @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd 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. +# +# See systemd.conf(5) for details + +[Manager] +#LogLevel=info +#LogTarget=console +#LogColor=yes +#LogLocation=no +#DefaultControllers=cpu +#DefaultStandardOutput=inherit +#DefaultStandardError=inherit diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..e9869ea --- /dev/null +++ b/src/util.c @@ -0,0 +1,6198 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "util.h" +#include "ioprio.h" +#include "missing.h" +#include "log.h" +#include "strv.h" +#include "label.h" +#include "exit-status.h" +#include "hashmap.h" + +int saved_argc = 0; +char **saved_argv = NULL; + +size_t page_size(void) { + static __thread size_t pgsz = 0; + long r; + + if (_likely_(pgsz > 0)) + return pgsz; + + assert_se((r = sysconf(_SC_PAGESIZE)) > 0); + + pgsz = (size_t) r; + + return pgsz; +} + +bool streq_ptr(const char *a, const char *b) { + + /* Like streq(), but tries to make sense of NULL pointers */ + + if (a && b) + return streq(a, b); + + if (!a && !b) + return true; + + return false; +} + +usec_t now(clockid_t clock_id) { + struct timespec ts; + + assert_se(clock_gettime(clock_id, &ts) == 0); + + return timespec_load(&ts); +} + +dual_timestamp* dual_timestamp_get(dual_timestamp *ts) { + assert(ts); + + ts->realtime = now(CLOCK_REALTIME); + ts->monotonic = now(CLOCK_MONOTONIC); + + return ts; +} + +dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) { + int64_t delta; + assert(ts); + + ts->realtime = u; + + if (u == 0) + ts->monotonic = 0; + else { + delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u; + + ts->monotonic = now(CLOCK_MONOTONIC); + + if ((int64_t) ts->monotonic > delta) + ts->monotonic -= delta; + else + ts->monotonic = 0; + } + + return ts; +} + +usec_t timespec_load(const struct timespec *ts) { + assert(ts); + + return + (usec_t) ts->tv_sec * USEC_PER_SEC + + (usec_t) ts->tv_nsec / NSEC_PER_USEC; +} + +struct timespec *timespec_store(struct timespec *ts, usec_t u) { + assert(ts); + + ts->tv_sec = (time_t) (u / USEC_PER_SEC); + ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC); + + return ts; +} + +usec_t timeval_load(const struct timeval *tv) { + assert(tv); + + return + (usec_t) tv->tv_sec * USEC_PER_SEC + + (usec_t) tv->tv_usec; +} + +struct timeval *timeval_store(struct timeval *tv, usec_t u) { + assert(tv); + + tv->tv_sec = (time_t) (u / USEC_PER_SEC); + tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC); + + return tv; +} + +bool endswith(const char *s, const char *postfix) { + size_t sl, pl; + + assert(s); + assert(postfix); + + sl = strlen(s); + pl = strlen(postfix); + + if (pl == 0) + return true; + + if (sl < pl) + return false; + + return memcmp(s + sl - pl, postfix, pl) == 0; +} + +bool startswith(const char *s, const char *prefix) { + size_t sl, pl; + + assert(s); + assert(prefix); + + sl = strlen(s); + pl = strlen(prefix); + + if (pl == 0) + return true; + + if (sl < pl) + return false; + + return memcmp(s, prefix, pl) == 0; +} + +bool startswith_no_case(const char *s, const char *prefix) { + size_t sl, pl; + unsigned i; + + assert(s); + assert(prefix); + + sl = strlen(s); + pl = strlen(prefix); + + if (pl == 0) + return true; + + if (sl < pl) + return false; + + for(i = 0; i < pl; ++i) { + if (tolower(s[i]) != tolower(prefix[i])) + return false; + } + + return true; +} + +bool first_word(const char *s, const char *word) { + size_t sl, wl; + + assert(s); + assert(word); + + sl = strlen(s); + wl = strlen(word); + + if (sl < wl) + return false; + + if (wl == 0) + return true; + + if (memcmp(s, word, wl) != 0) + return false; + + return s[wl] == 0 || + strchr(WHITESPACE, s[wl]); +} + +int close_nointr(int fd) { + assert(fd >= 0); + + for (;;) { + int r; + + r = close(fd); + if (r >= 0) + return r; + + if (errno != EINTR) + return -errno; + } +} + +void close_nointr_nofail(int fd) { + int saved_errno = errno; + + /* like close_nointr() but cannot fail, and guarantees errno + * is unchanged */ + + assert_se(close_nointr(fd) == 0); + + errno = saved_errno; +} + +void close_many(const int fds[], unsigned n_fd) { + unsigned i; + + for (i = 0; i < n_fd; i++) + close_nointr_nofail(fds[i]); +} + +int parse_boolean(const char *v) { + assert(v); + + if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on")) + return 1; + else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off")) + return 0; + + return -EINVAL; +} + +int parse_pid(const char *s, pid_t* ret_pid) { + unsigned long ul = 0; + pid_t pid; + int r; + + assert(s); + assert(ret_pid); + + if ((r = safe_atolu(s, &ul)) < 0) + return r; + + pid = (pid_t) ul; + + if ((unsigned long) pid != ul) + return -ERANGE; + + if (pid <= 0) + return -ERANGE; + + *ret_pid = pid; + return 0; +} + +int parse_uid(const char *s, uid_t* ret_uid) { + unsigned long ul = 0; + uid_t uid; + int r; + + assert(s); + assert(ret_uid); + + if ((r = safe_atolu(s, &ul)) < 0) + return r; + + uid = (uid_t) ul; + + if ((unsigned long) uid != ul) + return -ERANGE; + + *ret_uid = uid; + return 0; +} + +int safe_atou(const char *s, unsigned *ret_u) { + char *x = NULL; + unsigned long l; + + assert(s); + assert(ret_u); + + errno = 0; + l = strtoul(s, &x, 0); + + if (!x || *x || errno) + return errno ? -errno : -EINVAL; + + if ((unsigned long) (unsigned) l != l) + return -ERANGE; + + *ret_u = (unsigned) l; + return 0; +} + +int safe_atoi(const char *s, int *ret_i) { + char *x = NULL; + long l; + + assert(s); + assert(ret_i); + + errno = 0; + l = strtol(s, &x, 0); + + if (!x || *x || errno) + return errno ? -errno : -EINVAL; + + if ((long) (int) l != l) + return -ERANGE; + + *ret_i = (int) l; + return 0; +} + +int safe_atollu(const char *s, long long unsigned *ret_llu) { + char *x = NULL; + unsigned long long l; + + assert(s); + assert(ret_llu); + + errno = 0; + l = strtoull(s, &x, 0); + + if (!x || *x || errno) + return errno ? -errno : -EINVAL; + + *ret_llu = l; + return 0; +} + +int safe_atolli(const char *s, long long int *ret_lli) { + char *x = NULL; + long long l; + + assert(s); + assert(ret_lli); + + errno = 0; + l = strtoll(s, &x, 0); + + if (!x || *x || errno) + return errno ? -errno : -EINVAL; + + *ret_lli = l; + return 0; +} + +/* Split a string into words. */ +char *split(const char *c, size_t *l, const char *separator, char **state) { + char *current; + + current = *state ? *state : (char*) c; + + if (!*current || *c == 0) + return NULL; + + current += strspn(current, separator); + *l = strcspn(current, separator); + *state = current+*l; + + return (char*) current; +} + +/* Split a string into words, but consider strings enclosed in '' and + * "" as words even if they include spaces. */ +char *split_quoted(const char *c, size_t *l, char **state) { + char *current, *e; + bool escaped = false; + + current = *state ? *state : (char*) c; + + if (!*current || *c == 0) + return NULL; + + current += strspn(current, WHITESPACE); + + if (*current == '\'') { + current ++; + + for (e = current; *e; e++) { + if (escaped) + escaped = false; + else if (*e == '\\') + escaped = true; + else if (*e == '\'') + break; + } + + *l = e-current; + *state = *e == 0 ? e : e+1; + } else if (*current == '\"') { + current ++; + + for (e = current; *e; e++) { + if (escaped) + escaped = false; + else if (*e == '\\') + escaped = true; + else if (*e == '\"') + break; + } + + *l = e-current; + *state = *e == 0 ? e : e+1; + } else { + for (e = current; *e; e++) { + if (escaped) + escaped = false; + else if (*e == '\\') + escaped = true; + else if (strchr(WHITESPACE, *e)) + break; + } + *l = e-current; + *state = e; + } + + return (char*) current; +} + +char **split_path_and_make_absolute(const char *p) { + char **l; + assert(p); + + if (!(l = strv_split(p, ":"))) + return NULL; + + if (!strv_path_make_absolute_cwd(l)) { + strv_free(l); + return NULL; + } + + return l; +} + +int get_parent_of_pid(pid_t pid, pid_t *_ppid) { + int r; + FILE *f; + char fn[PATH_MAX], line[LINE_MAX], *p; + long unsigned ppid; + + assert(pid > 0); + assert(_ppid); + + assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1)); + char_array_0(fn); + + if (!(f = fopen(fn, "re"))) + return -errno; + + if (!(fgets(line, sizeof(line), f))) { + r = feof(f) ? -EIO : -errno; + fclose(f); + return r; + } + + fclose(f); + + /* Let's skip the pid and comm fields. The latter is enclosed + * in () but does not escape any () in its value, so let's + * skip over it manually */ + + if (!(p = strrchr(line, ')'))) + return -EIO; + + p++; + + if (sscanf(p, " " + "%*c " /* state */ + "%lu ", /* ppid */ + &ppid) != 1) + return -EIO; + + if ((long unsigned) (pid_t) ppid != ppid) + return -ERANGE; + + *_ppid = (pid_t) ppid; + + return 0; +} + +int get_starttime_of_pid(pid_t pid, unsigned long long *st) { + int r; + FILE *f; + char fn[PATH_MAX], line[LINE_MAX], *p; + + assert(pid > 0); + assert(st); + + assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1)); + char_array_0(fn); + + if (!(f = fopen(fn, "re"))) + return -errno; + + if (!(fgets(line, sizeof(line), f))) { + r = feof(f) ? -EIO : -errno; + fclose(f); + return r; + } + + fclose(f); + + /* Let's skip the pid and comm fields. The latter is enclosed + * in () but does not escape any () in its value, so let's + * skip over it manually */ + + if (!(p = strrchr(line, ')'))) + return -EIO; + + p++; + + if (sscanf(p, " " + "%*c " /* state */ + "%*d " /* ppid */ + "%*d " /* pgrp */ + "%*d " /* session */ + "%*d " /* tty_nr */ + "%*d " /* tpgid */ + "%*u " /* flags */ + "%*u " /* minflt */ + "%*u " /* cminflt */ + "%*u " /* majflt */ + "%*u " /* cmajflt */ + "%*u " /* utime */ + "%*u " /* stime */ + "%*d " /* cutime */ + "%*d " /* cstime */ + "%*d " /* priority */ + "%*d " /* nice */ + "%*d " /* num_threads */ + "%*d " /* itrealvalue */ + "%llu " /* starttime */, + st) != 1) + return -EIO; + + return 0; +} + +int write_one_line_file(const char *fn, const char *line) { + FILE *f; + int r; + + assert(fn); + assert(line); + + if (!(f = fopen(fn, "we"))) + return -errno; + + errno = 0; + if (fputs(line, f) < 0) { + r = -errno; + goto finish; + } + + if (!endswith(line, "\n")) + fputc('\n', f); + + fflush(f); + + if (ferror(f)) { + if (errno != 0) + r = -errno; + else + r = -EIO; + } else + r = 0; + +finish: + fclose(f); + return r; +} + +int fchmod_umask(int fd, mode_t m) { + mode_t u; + int r; + + u = umask(0777); + r = fchmod(fd, m & (~u)) < 0 ? -errno : 0; + umask(u); + + return r; +} + +int write_one_line_file_atomic(const char *fn, const char *line) { + FILE *f; + int r; + char *p; + + assert(fn); + assert(line); + + r = fopen_temporary(fn, &f, &p); + if (r < 0) + return r; + + fchmod_umask(fileno(f), 0644); + + errno = 0; + if (fputs(line, f) < 0) { + r = -errno; + goto finish; + } + + if (!endswith(line, "\n")) + fputc('\n', f); + + fflush(f); + + if (ferror(f)) { + if (errno != 0) + r = -errno; + else + r = -EIO; + } else { + if (rename(p, fn) < 0) + r = -errno; + else + r = 0; + } + +finish: + if (r < 0) + unlink(p); + + fclose(f); + free(p); + + return r; +} + +int read_one_line_file(const char *fn, char **line) { + FILE *f; + int r; + char t[LINE_MAX], *c; + + assert(fn); + assert(line); + + f = fopen(fn, "re"); + if (!f) + return -errno; + + if (!fgets(t, sizeof(t), f)) { + + if (ferror(f)) { + r = -errno; + goto finish; + } + + t[0] = 0; + } + + c = strdup(t); + if (!c) { + r = -ENOMEM; + goto finish; + } + + truncate_nl(c); + + *line = c; + r = 0; + +finish: + fclose(f); + return r; +} + +int read_full_file(const char *fn, char **contents, size_t *size) { + FILE *f; + int r; + size_t n, l; + char *buf = NULL; + struct stat st; + + if (!(f = fopen(fn, "re"))) + return -errno; + + if (fstat(fileno(f), &st) < 0) { + r = -errno; + goto finish; + } + + /* Safety check */ + if (st.st_size > 4*1024*1024) { + r = -E2BIG; + goto finish; + } + + n = st.st_size > 0 ? st.st_size : LINE_MAX; + l = 0; + + for (;;) { + char *t; + size_t k; + + if (!(t = realloc(buf, n+1))) { + r = -ENOMEM; + goto finish; + } + + buf = t; + k = fread(buf + l, 1, n - l, f); + + if (k <= 0) { + if (ferror(f)) { + r = -errno; + goto finish; + } + + break; + } + + l += k; + n *= 2; + + /* Safety check */ + if (n > 4*1024*1024) { + r = -E2BIG; + goto finish; + } + } + + buf[l] = 0; + *contents = buf; + buf = NULL; + + if (size) + *size = l; + + r = 0; + +finish: + fclose(f); + free(buf); + + return r; +} + +int parse_env_file( + const char *fname, + const char *separator, ...) { + + int r = 0; + char *contents = NULL, *p; + + assert(fname); + assert(separator); + + if ((r = read_full_file(fname, &contents, NULL)) < 0) + return r; + + p = contents; + for (;;) { + const char *key = NULL; + + p += strspn(p, separator); + p += strspn(p, WHITESPACE); + + if (!*p) + break; + + if (!strchr(COMMENTS, *p)) { + va_list ap; + char **value; + + va_start(ap, separator); + while ((key = va_arg(ap, char *))) { + size_t n; + char *v; + + value = va_arg(ap, char **); + + n = strlen(key); + if (strncmp(p, key, n) != 0 || + p[n] != '=') + continue; + + p += n + 1; + n = strcspn(p, separator); + + if (n >= 2 && + strchr(QUOTES, p[0]) && + p[n-1] == p[0]) + v = strndup(p+1, n-2); + else + v = strndup(p, n); + + if (!v) { + r = -ENOMEM; + va_end(ap); + goto fail; + } + + if (v[0] == '\0') { + /* return empty value strings as NULL */ + free(v); + v = NULL; + } + + free(*value); + *value = v; + + p += n; + + r ++; + break; + } + va_end(ap); + } + + if (!key) + p += strcspn(p, separator); + } + +fail: + free(contents); + return r; +} + +int load_env_file( + const char *fname, + char ***rl) { + + FILE *f; + char **m = 0; + int r; + + assert(fname); + assert(rl); + + if (!(f = fopen(fname, "re"))) + return -errno; + + while (!feof(f)) { + char l[LINE_MAX], *p, *u; + char **t; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + r = -errno; + goto finish; + } + + p = strstrip(l); + + if (!*p) + continue; + + if (strchr(COMMENTS, *p)) + continue; + + if (!(u = normalize_env_assignment(p))) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + t = strv_append(m, u); + free(u); + + if (!t) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } + + strv_free(m); + m = t; + } + + r = 0; + + *rl = m; + m = NULL; + +finish: + if (f) + fclose(f); + + strv_free(m); + + return r; +} + +int write_env_file(const char *fname, char **l) { + char **i, *p; + FILE *f; + int r; + + r = fopen_temporary(fname, &f, &p); + if (r < 0) + return r; + + fchmod_umask(fileno(f), 0644); + + errno = 0; + STRV_FOREACH(i, l) { + fputs(*i, f); + fputc('\n', f); + } + + fflush(f); + + if (ferror(f)) { + if (errno != 0) + r = -errno; + else + r = -EIO; + } else { + if (rename(p, fname) < 0) + r = -errno; + else + r = 0; + } + + if (r < 0) + unlink(p); + + fclose(f); + free(p); + + return r; +} + +char *truncate_nl(char *s) { + assert(s); + + s[strcspn(s, NEWLINE)] = 0; + return s; +} + +int get_process_comm(pid_t pid, char **name) { + int r; + + assert(name); + + if (pid == 0) + r = read_one_line_file("/proc/self/comm", name); + else { + char *p; + if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0) + return -ENOMEM; + + r = read_one_line_file(p, name); + free(p); + } + + return r; +} + +int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) { + char *r, *k; + int c; + bool space = false; + size_t left; + FILE *f; + + assert(max_length > 0); + assert(line); + + if (pid == 0) + f = fopen("/proc/self/cmdline", "re"); + else { + char *p; + if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0) + return -ENOMEM; + + f = fopen(p, "re"); + free(p); + } + + if (!f) + return -errno; + + r = new(char, max_length); + if (!r) { + fclose(f); + return -ENOMEM; + } + + k = r; + left = max_length; + while ((c = getc(f)) != EOF) { + + if (isprint(c)) { + if (space) { + if (left <= 4) + break; + + *(k++) = ' '; + left--; + space = false; + } + + if (left <= 4) + break; + + *(k++) = (char) c; + left--; + } else + space = true; + } + + if (left <= 4) { + size_t n = MIN(left-1, 3U); + memcpy(k, "...", n); + k[n] = 0; + } else + *k = 0; + + fclose(f); + + /* Kernel threads have no argv[] */ + if (r[0] == 0) { + char *t; + int h; + + free(r); + + if (!comm_fallback) + return -ENOENT; + + h = get_process_comm(pid, &t); + if (h < 0) + return h; + + r = join("[", t, "]", NULL); + free(t); + + if (!r) + return -ENOMEM; + } + + *line = r; + return 0; +} + +int is_kernel_thread(pid_t pid) { + char *p; + size_t count; + char c; + bool eof; + FILE *f; + + if (pid == 0) + return 0; + + if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0) + return -ENOMEM; + + f = fopen(p, "re"); + free(p); + + if (!f) + return -errno; + + count = fread(&c, 1, 1, f); + eof = feof(f); + fclose(f); + + /* Kernel threads have an empty cmdline */ + + if (count <= 0) + return eof ? 1 : -errno; + + return 0; +} + +int get_process_exe(pid_t pid, char **name) { + int r; + + assert(name); + + if (pid == 0) + r = readlink_malloc("/proc/self/exe", name); + else { + char *p; + if (asprintf(&p, "/proc/%lu/exe", (unsigned long) pid) < 0) + return -ENOMEM; + + r = readlink_malloc(p, name); + free(p); + } + + return r; +} + +int get_process_uid(pid_t pid, uid_t *uid) { + char *p; + FILE *f; + int r; + + assert(uid); + + if (pid == 0) + return getuid(); + + if (asprintf(&p, "/proc/%lu/status", (unsigned long) pid) < 0) + return -ENOMEM; + + f = fopen(p, "re"); + free(p); + + if (!f) + return -errno; + + while (!feof(f)) { + char line[LINE_MAX], *l; + + if (!fgets(line, sizeof(line), f)) { + if (feof(f)) + break; + + r = -errno; + goto finish; + } + + l = strstrip(line); + + if (startswith(l, "Uid:")) { + l += 4; + l += strspn(l, WHITESPACE); + + l[strcspn(l, WHITESPACE)] = 0; + + r = parse_uid(l, uid); + goto finish; + } + } + + r = -EIO; + +finish: + fclose(f); + + return r; +} + +char *strnappend(const char *s, const char *suffix, size_t b) { + size_t a; + char *r; + + if (!s && !suffix) + return strdup(""); + + if (!s) + return strndup(suffix, b); + + if (!suffix) + return strdup(s); + + assert(s); + assert(suffix); + + a = strlen(s); + + if (!(r = new(char, a+b+1))) + return NULL; + + memcpy(r, s, a); + memcpy(r+a, suffix, b); + r[a+b] = 0; + + return r; +} + +char *strappend(const char *s, const char *suffix) { + return strnappend(s, suffix, suffix ? strlen(suffix) : 0); +} + +int readlink_malloc(const char *p, char **r) { + size_t l = 100; + + assert(p); + assert(r); + + for (;;) { + char *c; + ssize_t n; + + if (!(c = new(char, l))) + return -ENOMEM; + + if ((n = readlink(p, c, l-1)) < 0) { + int ret = -errno; + free(c); + return ret; + } + + if ((size_t) n < l-1) { + c[n] = 0; + *r = c; + return 0; + } + + free(c); + l *= 2; + } +} + +int readlink_and_make_absolute(const char *p, char **r) { + char *target, *k; + int j; + + assert(p); + assert(r); + + if ((j = readlink_malloc(p, &target)) < 0) + return j; + + k = file_in_same_dir(p, target); + free(target); + + if (!k) + return -ENOMEM; + + *r = k; + return 0; +} + +int readlink_and_canonicalize(const char *p, char **r) { + char *t, *s; + int j; + + assert(p); + assert(r); + + j = readlink_and_make_absolute(p, &t); + if (j < 0) + return j; + + s = canonicalize_file_name(t); + if (s) { + free(t); + *r = s; + } else + *r = t; + + path_kill_slashes(*r); + + return 0; +} + +int parent_of_path(const char *path, char **_r) { + const char *e, *a = NULL, *b = NULL, *p; + char *r; + bool slash = false; + + assert(path); + assert(_r); + + if (!*path) + return -EINVAL; + + for (e = path; *e; e++) { + + if (!slash && *e == '/') { + a = b; + b = e; + slash = true; + } else if (slash && *e != '/') + slash = false; + } + + if (*(e-1) == '/') + p = a; + else + p = b; + + if (!p) + return -EINVAL; + + if (p == path) + r = strdup("/"); + else + r = strndup(path, p-path); + + if (!r) + return -ENOMEM; + + *_r = r; + return 0; +} + + +char *file_name_from_path(const char *p) { + char *r; + + assert(p); + + if ((r = strrchr(p, '/'))) + return r + 1; + + return (char*) p; +} + +bool path_is_absolute(const char *p) { + assert(p); + + return p[0] == '/'; +} + +bool is_path(const char *p) { + + return !!strchr(p, '/'); +} + +char *path_make_absolute(const char *p, const char *prefix) { + assert(p); + + /* Makes every item in the list an absolute path by prepending + * the prefix, if specified and necessary */ + + if (path_is_absolute(p) || !prefix) + return strdup(p); + + return join(prefix, "/", p, NULL); +} + +char *path_make_absolute_cwd(const char *p) { + char *cwd, *r; + + assert(p); + + /* Similar to path_make_absolute(), but prefixes with the + * current working directory. */ + + if (path_is_absolute(p)) + return strdup(p); + + if (!(cwd = get_current_dir_name())) + return NULL; + + r = path_make_absolute(p, cwd); + free(cwd); + + return r; +} + +char **strv_path_make_absolute_cwd(char **l) { + char **s; + + /* Goes through every item in the string list and makes it + * absolute. This works in place and won't rollback any + * changes on failure. */ + + STRV_FOREACH(s, l) { + char *t; + + if (!(t = path_make_absolute_cwd(*s))) + return NULL; + + free(*s); + *s = t; + } + + return l; +} + +char **strv_path_canonicalize(char **l) { + char **s; + unsigned k = 0; + bool enomem = false; + + if (strv_isempty(l)) + return l; + + /* Goes through every item in the string list and canonicalize + * the path. This works in place and won't rollback any + * changes on failure. */ + + STRV_FOREACH(s, l) { + char *t, *u; + + t = path_make_absolute_cwd(*s); + free(*s); + + if (!t) { + enomem = true; + continue; + } + + errno = 0; + u = canonicalize_file_name(t); + free(t); + + if (!u) { + if (errno == ENOMEM || !errno) + enomem = true; + + continue; + } + + l[k++] = u; + } + + l[k] = NULL; + + if (enomem) + return NULL; + + return l; +} + +char **strv_path_remove_empty(char **l) { + char **f, **t; + + if (!l) + return NULL; + + for (f = t = l; *f; f++) { + + if (dir_is_empty(*f) > 0) { + free(*f); + continue; + } + + *(t++) = *f; + } + + *t = NULL; + return l; +} + +int reset_all_signal_handlers(void) { + int sig; + + for (sig = 1; sig < _NSIG; sig++) { + struct sigaction sa; + + if (sig == SIGKILL || sig == SIGSTOP) + continue; + + zero(sa); + sa.sa_handler = SIG_DFL; + sa.sa_flags = SA_RESTART; + + /* On Linux the first two RT signals are reserved by + * glibc, and sigaction() will return EINVAL for them. */ + if ((sigaction(sig, &sa, NULL) < 0)) + if (errno != EINVAL) + return -errno; + } + + return 0; +} + +char *strstrip(char *s) { + char *e; + + /* Drops trailing whitespace. Modifies the string in + * place. Returns pointer to first non-space character */ + + s += strspn(s, WHITESPACE); + + for (e = strchr(s, 0); e > s; e --) + if (!strchr(WHITESPACE, e[-1])) + break; + + *e = 0; + + return s; +} + +char *delete_chars(char *s, const char *bad) { + char *f, *t; + + /* Drops all whitespace, regardless where in the string */ + + for (f = s, t = s; *f; f++) { + if (strchr(bad, *f)) + continue; + + *(t++) = *f; + } + + *t = 0; + + return s; +} + +bool in_charset(const char *s, const char* charset) { + const char *i; + + assert(s); + assert(charset); + + for (i = s; *i; i++) + if (!strchr(charset, *i)) + return false; + + return true; +} + +char *file_in_same_dir(const char *path, const char *filename) { + char *e, *r; + size_t k; + + assert(path); + assert(filename); + + /* This removes the last component of path and appends + * filename, unless the latter is absolute anyway or the + * former isn't */ + + if (path_is_absolute(filename)) + return strdup(filename); + + if (!(e = strrchr(path, '/'))) + return strdup(filename); + + k = strlen(filename); + if (!(r = new(char, e-path+1+k+1))) + return NULL; + + memcpy(r, path, e-path+1); + memcpy(r+(e-path)+1, filename, k+1); + + return r; +} + +int safe_mkdir(const char *path, mode_t mode, uid_t uid, gid_t gid) { + struct stat st; + + if (label_mkdir(path, mode) >= 0) + if (chmod_and_chown(path, mode, uid, gid) < 0) + return -errno; + + if (lstat(path, &st) < 0) + return -errno; + + if ((st.st_mode & 0777) != mode || + st.st_uid != uid || + st.st_gid != gid || + !S_ISDIR(st.st_mode)) { + errno = EEXIST; + return -errno; + } + + return 0; +} + + +int mkdir_parents(const char *path, mode_t mode) { + const char *p, *e; + + assert(path); + + /* Creates every parent directory in the path except the last + * component. */ + + p = path + strspn(path, "/"); + for (;;) { + int r; + char *t; + + e = p + strcspn(p, "/"); + p = e + strspn(e, "/"); + + /* Is this the last component? If so, then we're + * done */ + if (*p == 0) + return 0; + + if (!(t = strndup(path, e - path))) + return -ENOMEM; + + r = label_mkdir(t, mode); + free(t); + + if (r < 0 && errno != EEXIST) + return -errno; + } +} + +int mkdir_p(const char *path, mode_t mode) { + int r; + + /* Like mkdir -p */ + + if ((r = mkdir_parents(path, mode)) < 0) + return r; + + if (label_mkdir(path, mode) < 0 && errno != EEXIST) + return -errno; + + return 0; +} + +int rmdir_parents(const char *path, const char *stop) { + size_t l; + int r = 0; + + assert(path); + assert(stop); + + l = strlen(path); + + /* Skip trailing slashes */ + while (l > 0 && path[l-1] == '/') + l--; + + while (l > 0) { + char *t; + + /* Skip last component */ + while (l > 0 && path[l-1] != '/') + l--; + + /* Skip trailing slashes */ + while (l > 0 && path[l-1] == '/') + l--; + + if (l <= 0) + break; + + if (!(t = strndup(path, l))) + return -ENOMEM; + + if (path_startswith(stop, t)) { + free(t); + return 0; + } + + r = rmdir(t); + free(t); + + if (r < 0) + if (errno != ENOENT) + return -errno; + } + + return 0; +} + + +char hexchar(int x) { + static const char table[16] = "0123456789abcdef"; + + return table[x & 15]; +} + +int unhexchar(char c) { + + if (c >= '0' && c <= '9') + return c - '0'; + + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + + return -1; +} + +char octchar(int x) { + return '0' + (x & 7); +} + +int unoctchar(char c) { + + if (c >= '0' && c <= '7') + return c - '0'; + + return -1; +} + +char decchar(int x) { + return '0' + (x % 10); +} + +int undecchar(char c) { + + if (c >= '0' && c <= '9') + return c - '0'; + + return -1; +} + +char *cescape(const char *s) { + char *r, *t; + const char *f; + + assert(s); + + /* Does C style string escaping. */ + + if (!(r = new(char, strlen(s)*4 + 1))) + return NULL; + + for (f = s, t = r; *f; f++) + + switch (*f) { + + case '\a': + *(t++) = '\\'; + *(t++) = 'a'; + break; + case '\b': + *(t++) = '\\'; + *(t++) = 'b'; + break; + case '\f': + *(t++) = '\\'; + *(t++) = 'f'; + break; + case '\n': + *(t++) = '\\'; + *(t++) = 'n'; + break; + case '\r': + *(t++) = '\\'; + *(t++) = 'r'; + break; + case '\t': + *(t++) = '\\'; + *(t++) = 't'; + break; + case '\v': + *(t++) = '\\'; + *(t++) = 'v'; + break; + case '\\': + *(t++) = '\\'; + *(t++) = '\\'; + break; + case '"': + *(t++) = '\\'; + *(t++) = '"'; + break; + case '\'': + *(t++) = '\\'; + *(t++) = '\''; + break; + + default: + /* For special chars we prefer octal over + * hexadecimal encoding, simply because glib's + * g_strescape() does the same */ + if ((*f < ' ') || (*f >= 127)) { + *(t++) = '\\'; + *(t++) = octchar((unsigned char) *f >> 6); + *(t++) = octchar((unsigned char) *f >> 3); + *(t++) = octchar((unsigned char) *f); + } else + *(t++) = *f; + break; + } + + *t = 0; + + return r; +} + +char *cunescape_length(const char *s, size_t length) { + char *r, *t; + const char *f; + + assert(s); + + /* Undoes C style string escaping */ + + if (!(r = new(char, length+1))) + return r; + + for (f = s, t = r; f < s + length; f++) { + + if (*f != '\\') { + *(t++) = *f; + continue; + } + + f++; + + switch (*f) { + + case 'a': + *(t++) = '\a'; + break; + case 'b': + *(t++) = '\b'; + break; + case 'f': + *(t++) = '\f'; + break; + case 'n': + *(t++) = '\n'; + break; + case 'r': + *(t++) = '\r'; + break; + case 't': + *(t++) = '\t'; + break; + case 'v': + *(t++) = '\v'; + break; + case '\\': + *(t++) = '\\'; + break; + case '"': + *(t++) = '"'; + break; + case '\'': + *(t++) = '\''; + break; + + case 's': + /* This is an extension of the XDG syntax files */ + *(t++) = ' '; + break; + + case 'x': { + /* hexadecimal encoding */ + int a, b; + + if ((a = unhexchar(f[1])) < 0 || + (b = unhexchar(f[2])) < 0) { + /* Invalid escape code, let's take it literal then */ + *(t++) = '\\'; + *(t++) = 'x'; + } else { + *(t++) = (char) ((a << 4) | b); + f += 2; + } + + break; + } + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': { + /* octal encoding */ + int a, b, c; + + if ((a = unoctchar(f[0])) < 0 || + (b = unoctchar(f[1])) < 0 || + (c = unoctchar(f[2])) < 0) { + /* Invalid escape code, let's take it literal then */ + *(t++) = '\\'; + *(t++) = f[0]; + } else { + *(t++) = (char) ((a << 6) | (b << 3) | c); + f += 2; + } + + break; + } + + case 0: + /* premature end of string.*/ + *(t++) = '\\'; + goto finish; + + default: + /* Invalid escape code, let's take it literal then */ + *(t++) = '\\'; + *(t++) = *f; + break; + } + } + +finish: + *t = 0; + return r; +} + +char *cunescape(const char *s) { + return cunescape_length(s, strlen(s)); +} + +char *xescape(const char *s, const char *bad) { + char *r, *t; + const char *f; + + /* Escapes all chars in bad, in addition to \ and all special + * chars, in \xFF style escaping. May be reversed with + * cunescape. */ + + if (!(r = new(char, strlen(s)*4+1))) + return NULL; + + for (f = s, t = r; *f; f++) { + + if ((*f < ' ') || (*f >= 127) || + (*f == '\\') || strchr(bad, *f)) { + *(t++) = '\\'; + *(t++) = 'x'; + *(t++) = hexchar(*f >> 4); + *(t++) = hexchar(*f); + } else + *(t++) = *f; + } + + *t = 0; + + return r; +} + +char *bus_path_escape(const char *s) { + char *r, *t; + const char *f; + + assert(s); + + /* Escapes all chars that D-Bus' object path cannot deal + * with. Can be reverse with bus_path_unescape() */ + + if (!(r = new(char, strlen(s)*3+1))) + return NULL; + + for (f = s, t = r; *f; f++) { + + if (!(*f >= 'A' && *f <= 'Z') && + !(*f >= 'a' && *f <= 'z') && + !(*f >= '0' && *f <= '9')) { + *(t++) = '_'; + *(t++) = hexchar(*f >> 4); + *(t++) = hexchar(*f); + } else + *(t++) = *f; + } + + *t = 0; + + return r; +} + +char *bus_path_unescape(const char *f) { + char *r, *t; + + assert(f); + + if (!(r = strdup(f))) + return NULL; + + for (t = r; *f; f++) { + + if (*f == '_') { + int a, b; + + if ((a = unhexchar(f[1])) < 0 || + (b = unhexchar(f[2])) < 0) { + /* Invalid escape code, let's take it literal then */ + *(t++) = '_'; + } else { + *(t++) = (char) ((a << 4) | b); + f += 2; + } + } else + *(t++) = *f; + } + + *t = 0; + + return r; +} + +char *path_kill_slashes(char *path) { + char *f, *t; + bool slash = false; + + /* Removes redundant inner and trailing slashes. Modifies the + * passed string in-place. + * + * ///foo///bar/ becomes /foo/bar + */ + + for (f = path, t = path; *f; f++) { + + if (*f == '/') { + slash = true; + continue; + } + + if (slash) { + slash = false; + *(t++) = '/'; + } + + *(t++) = *f; + } + + /* Special rule, if we are talking of the root directory, a + trailing slash is good */ + + if (t == path && slash) + *(t++) = '/'; + + *t = 0; + return path; +} + +bool path_startswith(const char *path, const char *prefix) { + assert(path); + assert(prefix); + + if ((path[0] == '/') != (prefix[0] == '/')) + return false; + + for (;;) { + size_t a, b; + + path += strspn(path, "/"); + prefix += strspn(prefix, "/"); + + if (*prefix == 0) + return true; + + if (*path == 0) + return false; + + a = strcspn(path, "/"); + b = strcspn(prefix, "/"); + + if (a != b) + return false; + + if (memcmp(path, prefix, a) != 0) + return false; + + path += a; + prefix += b; + } +} + +bool path_equal(const char *a, const char *b) { + assert(a); + assert(b); + + if ((a[0] == '/') != (b[0] == '/')) + return false; + + for (;;) { + size_t j, k; + + a += strspn(a, "/"); + b += strspn(b, "/"); + + if (*a == 0 && *b == 0) + return true; + + if (*a == 0 || *b == 0) + return false; + + j = strcspn(a, "/"); + k = strcspn(b, "/"); + + if (j != k) + return false; + + if (memcmp(a, b, j) != 0) + return false; + + a += j; + b += k; + } +} + +char *ascii_strlower(char *t) { + char *p; + + assert(t); + + for (p = t; *p; p++) + if (*p >= 'A' && *p <= 'Z') + *p = *p - 'A' + 'a'; + + return t; +} + +bool ignore_file(const char *filename) { + assert(filename); + + return + filename[0] == '.' || + streq(filename, "lost+found") || + streq(filename, "aquota.user") || + streq(filename, "aquota.group") || + endswith(filename, "~") || + endswith(filename, ".rpmnew") || + endswith(filename, ".rpmsave") || + endswith(filename, ".rpmorig") || + endswith(filename, ".dpkg-old") || + endswith(filename, ".dpkg-new") || + endswith(filename, ".swp"); +} + +int fd_nonblock(int fd, bool nonblock) { + int flags; + + assert(fd >= 0); + + if ((flags = fcntl(fd, F_GETFL, 0)) < 0) + return -errno; + + if (nonblock) + flags |= O_NONBLOCK; + else + flags &= ~O_NONBLOCK; + + if (fcntl(fd, F_SETFL, flags) < 0) + return -errno; + + return 0; +} + +int fd_cloexec(int fd, bool cloexec) { + int flags; + + assert(fd >= 0); + + if ((flags = fcntl(fd, F_GETFD, 0)) < 0) + return -errno; + + if (cloexec) + flags |= FD_CLOEXEC; + else + flags &= ~FD_CLOEXEC; + + if (fcntl(fd, F_SETFD, flags) < 0) + return -errno; + + return 0; +} + +int close_all_fds(const int except[], unsigned n_except) { + DIR *d; + struct dirent *de; + int r = 0; + + if (!(d = opendir("/proc/self/fd"))) + return -errno; + + while ((de = readdir(d))) { + int fd = -1; + + if (ignore_file(de->d_name)) + continue; + + if (safe_atoi(de->d_name, &fd) < 0) + /* Let's better ignore this, just in case */ + continue; + + if (fd < 3) + continue; + + if (fd == dirfd(d)) + continue; + + if (except) { + bool found; + unsigned i; + + found = false; + for (i = 0; i < n_except; i++) + if (except[i] == fd) { + found = true; + break; + } + + if (found) + continue; + } + + if (close_nointr(fd) < 0) { + /* Valgrind has its own FD and doesn't want to have it closed */ + if (errno != EBADF && r == 0) + r = -errno; + } + } + + closedir(d); + return r; +} + +bool chars_intersect(const char *a, const char *b) { + const char *p; + + /* Returns true if any of the chars in a are in b. */ + for (p = a; *p; p++) + if (strchr(b, *p)) + return true; + + return false; +} + +char *format_timestamp(char *buf, size_t l, usec_t t) { + struct tm tm; + time_t sec; + + assert(buf); + assert(l > 0); + + if (t <= 0) + return NULL; + + sec = (time_t) (t / USEC_PER_SEC); + + if (strftime(buf, l, "%a, %d %b %Y %H:%M:%S %z", localtime_r(&sec, &tm)) <= 0) + return NULL; + + return buf; +} + +char *format_timestamp_pretty(char *buf, size_t l, usec_t t) { + usec_t n, d; + + n = now(CLOCK_REALTIME); + + if (t <= 0 || t > n || t + USEC_PER_DAY*7 <= t) + return NULL; + + d = n - t; + + if (d >= USEC_PER_YEAR) + snprintf(buf, l, "%llu years and %llu months ago", + (unsigned long long) (d / USEC_PER_YEAR), + (unsigned long long) ((d % USEC_PER_YEAR) / USEC_PER_MONTH)); + else if (d >= USEC_PER_MONTH) + snprintf(buf, l, "%llu months and %llu days ago", + (unsigned long long) (d / USEC_PER_MONTH), + (unsigned long long) ((d % USEC_PER_MONTH) / USEC_PER_DAY)); + else if (d >= USEC_PER_WEEK) + snprintf(buf, l, "%llu weeks and %llu days ago", + (unsigned long long) (d / USEC_PER_WEEK), + (unsigned long long) ((d % USEC_PER_WEEK) / USEC_PER_DAY)); + else if (d >= 2*USEC_PER_DAY) + snprintf(buf, l, "%llu days ago", (unsigned long long) (d / USEC_PER_DAY)); + else if (d >= 25*USEC_PER_HOUR) + snprintf(buf, l, "1 day and %lluh ago", + (unsigned long long) ((d - USEC_PER_DAY) / USEC_PER_HOUR)); + else if (d >= 6*USEC_PER_HOUR) + snprintf(buf, l, "%lluh ago", + (unsigned long long) (d / USEC_PER_HOUR)); + else if (d >= USEC_PER_HOUR) + snprintf(buf, l, "%lluh %llumin ago", + (unsigned long long) (d / USEC_PER_HOUR), + (unsigned long long) ((d % USEC_PER_HOUR) / USEC_PER_MINUTE)); + else if (d >= 5*USEC_PER_MINUTE) + snprintf(buf, l, "%llumin ago", + (unsigned long long) (d / USEC_PER_MINUTE)); + else if (d >= USEC_PER_MINUTE) + snprintf(buf, l, "%llumin %llus ago", + (unsigned long long) (d / USEC_PER_MINUTE), + (unsigned long long) ((d % USEC_PER_MINUTE) / USEC_PER_SEC)); + else if (d >= USEC_PER_SEC) + snprintf(buf, l, "%llus ago", + (unsigned long long) (d / USEC_PER_SEC)); + else if (d >= USEC_PER_MSEC) + snprintf(buf, l, "%llums ago", + (unsigned long long) (d / USEC_PER_MSEC)); + else if (d > 0) + snprintf(buf, l, "%lluus ago", + (unsigned long long) d); + else + snprintf(buf, l, "now"); + + buf[l-1] = 0; + return buf; +} + +char *format_timespan(char *buf, size_t l, usec_t t) { + static const struct { + const char *suffix; + usec_t usec; + } table[] = { + { "w", USEC_PER_WEEK }, + { "d", USEC_PER_DAY }, + { "h", USEC_PER_HOUR }, + { "min", USEC_PER_MINUTE }, + { "s", USEC_PER_SEC }, + { "ms", USEC_PER_MSEC }, + { "us", 1 }, + }; + + unsigned i; + char *p = buf; + + assert(buf); + assert(l > 0); + + if (t == (usec_t) -1) + return NULL; + + if (t == 0) { + snprintf(p, l, "0"); + p[l-1] = 0; + return p; + } + + /* The result of this function can be parsed with parse_usec */ + + for (i = 0; i < ELEMENTSOF(table); i++) { + int k; + size_t n; + + if (t < table[i].usec) + continue; + + if (l <= 1) + break; + + k = snprintf(p, l, "%s%llu%s", p > buf ? " " : "", (unsigned long long) (t / table[i].usec), table[i].suffix); + n = MIN((size_t) k, l); + + l -= n; + p += n; + + t %= table[i].usec; + } + + *p = 0; + + return buf; +} + +bool fstype_is_network(const char *fstype) { + static const char * const table[] = { + "cifs", + "smbfs", + "ncpfs", + "nfs", + "nfs4", + "gfs", + "gfs2" + }; + + unsigned i; + + for (i = 0; i < ELEMENTSOF(table); i++) + if (streq(table[i], fstype)) + return true; + + return false; +} + +int chvt(int vt) { + int fd, r = 0; + + if ((fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0) + return -errno; + + if (vt < 0) { + int tiocl[2] = { + TIOCL_GETKMSGREDIRECT, + 0 + }; + + if (ioctl(fd, TIOCLINUX, tiocl) < 0) { + r = -errno; + goto fail; + } + + vt = tiocl[0] <= 0 ? 1 : tiocl[0]; + } + + if (ioctl(fd, VT_ACTIVATE, vt) < 0) + r = -errno; + +fail: + close_nointr_nofail(fd); + return r; +} + +int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) { + struct termios old_termios, new_termios; + char c; + char line[LINE_MAX]; + + assert(f); + assert(ret); + + if (tcgetattr(fileno(f), &old_termios) >= 0) { + new_termios = old_termios; + + new_termios.c_lflag &= ~ICANON; + new_termios.c_cc[VMIN] = 1; + new_termios.c_cc[VTIME] = 0; + + if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) { + size_t k; + + if (t != (usec_t) -1) { + if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) { + tcsetattr(fileno(f), TCSADRAIN, &old_termios); + return -ETIMEDOUT; + } + } + + k = fread(&c, 1, 1, f); + + tcsetattr(fileno(f), TCSADRAIN, &old_termios); + + if (k <= 0) + return -EIO; + + if (need_nl) + *need_nl = c != '\n'; + + *ret = c; + return 0; + } + } + + if (t != (usec_t) -1) + if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) + return -ETIMEDOUT; + + if (!fgets(line, sizeof(line), f)) + return -EIO; + + truncate_nl(line); + + if (strlen(line) != 1) + return -EBADMSG; + + if (need_nl) + *need_nl = false; + + *ret = line[0]; + return 0; +} + +int ask(char *ret, const char *replies, const char *text, ...) { + bool on_tty; + + assert(ret); + assert(replies); + assert(text); + + on_tty = isatty(STDOUT_FILENO); + + for (;;) { + va_list ap; + char c; + int r; + bool need_nl = true; + + if (on_tty) + fputs(ANSI_HIGHLIGHT_ON, stdout); + + va_start(ap, text); + vprintf(text, ap); + va_end(ap); + + if (on_tty) + fputs(ANSI_HIGHLIGHT_OFF, stdout); + + fflush(stdout); + + r = read_one_char(stdin, &c, (usec_t) -1, &need_nl); + if (r < 0) { + + if (r == -EBADMSG) { + puts("Bad input, please try again."); + continue; + } + + putchar('\n'); + return r; + } + + if (need_nl) + putchar('\n'); + + if (strchr(replies, c)) { + *ret = c; + return 0; + } + + puts("Read unexpected character, please try again."); + } +} + +int reset_terminal_fd(int fd, bool switch_to_text) { + struct termios termios; + int r = 0; + + /* Set terminal to some sane defaults */ + + assert(fd >= 0); + + /* We leave locked terminal attributes untouched, so that + * Plymouth may set whatever it wants to set, and we don't + * interfere with that. */ + + /* Disable exclusive mode, just in case */ + ioctl(fd, TIOCNXCL); + + /* Switch to text mode */ + if (switch_to_text) + ioctl(fd, KDSETMODE, KD_TEXT); + + /* Enable console unicode mode */ + ioctl(fd, KDSKBMODE, K_UNICODE); + + if (tcgetattr(fd, &termios) < 0) { + r = -errno; + goto finish; + } + + /* We only reset the stuff that matters to the software. How + * hardware is set up we don't touch assuming that somebody + * else will do that for us */ + + termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC); + termios.c_iflag |= ICRNL | IMAXBEL | IUTF8; + termios.c_oflag |= ONLCR; + termios.c_cflag |= CREAD; + termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE; + + termios.c_cc[VINTR] = 03; /* ^C */ + termios.c_cc[VQUIT] = 034; /* ^\ */ + termios.c_cc[VERASE] = 0177; + termios.c_cc[VKILL] = 025; /* ^X */ + termios.c_cc[VEOF] = 04; /* ^D */ + termios.c_cc[VSTART] = 021; /* ^Q */ + termios.c_cc[VSTOP] = 023; /* ^S */ + termios.c_cc[VSUSP] = 032; /* ^Z */ + termios.c_cc[VLNEXT] = 026; /* ^V */ + termios.c_cc[VWERASE] = 027; /* ^W */ + termios.c_cc[VREPRINT] = 022; /* ^R */ + termios.c_cc[VEOL] = 0; + termios.c_cc[VEOL2] = 0; + + termios.c_cc[VTIME] = 0; + termios.c_cc[VMIN] = 1; + + if (tcsetattr(fd, TCSANOW, &termios) < 0) + r = -errno; + +finish: + /* Just in case, flush all crap out */ + tcflush(fd, TCIOFLUSH); + + return r; +} + +int reset_terminal(const char *name) { + int fd, r; + + fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + r = reset_terminal_fd(fd, true); + close_nointr_nofail(fd); + + return r; +} + +int open_terminal(const char *name, int mode) { + int fd, r; + unsigned c = 0; + + /* + * If a TTY is in the process of being closed opening it might + * cause EIO. This is horribly awful, but unlikely to be + * changed in the kernel. Hence we work around this problem by + * retrying a couple of times. + * + * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245 + */ + + for (;;) { + if ((fd = open(name, mode)) >= 0) + break; + + if (errno != EIO) + return -errno; + + if (c >= 20) + return -errno; + + usleep(50 * USEC_PER_MSEC); + c++; + } + + if (fd < 0) + return -errno; + + if ((r = isatty(fd)) < 0) { + close_nointr_nofail(fd); + return -errno; + } + + if (!r) { + close_nointr_nofail(fd); + return -ENOTTY; + } + + return fd; +} + +int flush_fd(int fd) { + struct pollfd pollfd; + + zero(pollfd); + pollfd.fd = fd; + pollfd.events = POLLIN; + + for (;;) { + char buf[LINE_MAX]; + ssize_t l; + int r; + + if ((r = poll(&pollfd, 1, 0)) < 0) { + + if (errno == EINTR) + continue; + + return -errno; + } + + if (r == 0) + return 0; + + if ((l = read(fd, buf, sizeof(buf))) < 0) { + + if (errno == EINTR) + continue; + + if (errno == EAGAIN) + return 0; + + return -errno; + } + + if (l <= 0) + return 0; + } +} + +int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocstty_eperm) { + int fd = -1, notify = -1, r, wd = -1; + + assert(name); + + /* We use inotify to be notified when the tty is closed. We + * create the watch before checking if we can actually acquire + * it, so that we don't lose any event. + * + * Note: strictly speaking this actually watches for the + * device being closed, it does *not* really watch whether a + * tty loses its controlling process. However, unless some + * rogue process uses TIOCNOTTY on /dev/tty *after* closing + * its tty otherwise this will not become a problem. As long + * as the administrator makes sure not configure any service + * on the same tty as an untrusted user this should not be a + * problem. (Which he probably should not do anyway.) */ + + if (!fail && !force) { + if ((notify = inotify_init1(IN_CLOEXEC)) < 0) { + r = -errno; + goto fail; + } + + if ((wd = inotify_add_watch(notify, name, IN_CLOSE)) < 0) { + r = -errno; + goto fail; + } + } + + for (;;) { + if (notify >= 0) + if ((r = flush_fd(notify)) < 0) + goto fail; + + /* We pass here O_NOCTTY only so that we can check the return + * value TIOCSCTTY and have a reliable way to figure out if we + * successfully became the controlling process of the tty */ + if ((fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0) + return fd; + + /* First, try to get the tty */ + r = ioctl(fd, TIOCSCTTY, force); + + /* Sometimes it makes sense to ignore TIOCSCTTY + * returning EPERM, i.e. when very likely we already + * are have this controlling terminal. */ + if (r < 0 && errno == EPERM && ignore_tiocstty_eperm) + r = 0; + + if (r < 0 && (force || fail || errno != EPERM)) { + r = -errno; + goto fail; + } + + if (r >= 0) + break; + + assert(!fail); + assert(!force); + assert(notify >= 0); + + for (;;) { + uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX]; + ssize_t l; + struct inotify_event *e; + + if ((l = read(notify, inotify_buffer, sizeof(inotify_buffer))) < 0) { + + if (errno == EINTR) + continue; + + r = -errno; + goto fail; + } + + e = (struct inotify_event*) inotify_buffer; + + while (l > 0) { + size_t step; + + if (e->wd != wd || !(e->mask & IN_CLOSE)) { + r = -EIO; + goto fail; + } + + step = sizeof(struct inotify_event) + e->len; + assert(step <= (size_t) l); + + e = (struct inotify_event*) ((uint8_t*) e + step); + l -= step; + } + + break; + } + + /* We close the tty fd here since if the old session + * ended our handle will be dead. It's important that + * we do this after sleeping, so that we don't enter + * an endless loop. */ + close_nointr_nofail(fd); + } + + if (notify >= 0) + close_nointr_nofail(notify); + + r = reset_terminal_fd(fd, true); + if (r < 0) + log_warning("Failed to reset terminal: %s", strerror(-r)); + + return fd; + +fail: + if (fd >= 0) + close_nointr_nofail(fd); + + if (notify >= 0) + close_nointr_nofail(notify); + + return r; +} + +int release_terminal(void) { + int r = 0, fd; + struct sigaction sa_old, sa_new; + + if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC)) < 0) + return -errno; + + /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed + * by our own TIOCNOTTY */ + + zero(sa_new); + sa_new.sa_handler = SIG_IGN; + sa_new.sa_flags = SA_RESTART; + assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0); + + if (ioctl(fd, TIOCNOTTY) < 0) + r = -errno; + + assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0); + + close_nointr_nofail(fd); + return r; +} + +int sigaction_many(const struct sigaction *sa, ...) { + va_list ap; + int r = 0, sig; + + va_start(ap, sa); + while ((sig = va_arg(ap, int)) > 0) + if (sigaction(sig, sa, NULL) < 0) + r = -errno; + va_end(ap); + + return r; +} + +int ignore_signals(int sig, ...) { + struct sigaction sa; + va_list ap; + int r = 0; + + zero(sa); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_RESTART; + + if (sigaction(sig, &sa, NULL) < 0) + r = -errno; + + va_start(ap, sig); + while ((sig = va_arg(ap, int)) > 0) + if (sigaction(sig, &sa, NULL) < 0) + r = -errno; + va_end(ap); + + return r; +} + +int default_signals(int sig, ...) { + struct sigaction sa; + va_list ap; + int r = 0; + + zero(sa); + sa.sa_handler = SIG_DFL; + sa.sa_flags = SA_RESTART; + + if (sigaction(sig, &sa, NULL) < 0) + r = -errno; + + va_start(ap, sig); + while ((sig = va_arg(ap, int)) > 0) + if (sigaction(sig, &sa, NULL) < 0) + r = -errno; + va_end(ap); + + return r; +} + +int close_pipe(int p[]) { + int a = 0, b = 0; + + assert(p); + + if (p[0] >= 0) { + a = close_nointr(p[0]); + p[0] = -1; + } + + if (p[1] >= 0) { + b = close_nointr(p[1]); + p[1] = -1; + } + + return a < 0 ? a : b; +} + +ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) { + uint8_t *p; + ssize_t n = 0; + + assert(fd >= 0); + assert(buf); + + p = buf; + + while (nbytes > 0) { + ssize_t k; + + if ((k = read(fd, p, nbytes)) <= 0) { + + if (k < 0 && errno == EINTR) + continue; + + if (k < 0 && errno == EAGAIN && do_poll) { + struct pollfd pollfd; + + zero(pollfd); + pollfd.fd = fd; + pollfd.events = POLLIN; + + if (poll(&pollfd, 1, -1) < 0) { + if (errno == EINTR) + continue; + + return n > 0 ? n : -errno; + } + + if (pollfd.revents != POLLIN) + return n > 0 ? n : -EIO; + + continue; + } + + return n > 0 ? n : (k < 0 ? -errno : 0); + } + + p += k; + nbytes -= k; + n += k; + } + + return n; +} + +ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) { + const uint8_t *p; + ssize_t n = 0; + + assert(fd >= 0); + assert(buf); + + p = buf; + + while (nbytes > 0) { + ssize_t k; + + k = write(fd, p, nbytes); + if (k <= 0) { + + if (k < 0 && errno == EINTR) + continue; + + if (k < 0 && errno == EAGAIN && do_poll) { + struct pollfd pollfd; + + zero(pollfd); + pollfd.fd = fd; + pollfd.events = POLLOUT; + + if (poll(&pollfd, 1, -1) < 0) { + if (errno == EINTR) + continue; + + return n > 0 ? n : -errno; + } + + if (pollfd.revents != POLLOUT) + return n > 0 ? n : -EIO; + + continue; + } + + return n > 0 ? n : (k < 0 ? -errno : 0); + } + + p += k; + nbytes -= k; + n += k; + } + + return n; +} + +int path_is_mount_point(const char *t, bool allow_symlink) { + struct stat a, b; + char *parent; + int r; + + if (allow_symlink) + r = stat(t, &a); + else + r = lstat(t, &a); + + if (r < 0) { + if (errno == ENOENT) + return 0; + + return -errno; + } + + r = parent_of_path(t, &parent); + if (r < 0) + return r; + + r = lstat(parent, &b); + free(parent); + + if (r < 0) + return -errno; + + return a.st_dev != b.st_dev; +} + +int parse_usec(const char *t, usec_t *usec) { + static const struct { + const char *suffix; + usec_t usec; + } table[] = { + { "sec", USEC_PER_SEC }, + { "s", USEC_PER_SEC }, + { "min", USEC_PER_MINUTE }, + { "hr", USEC_PER_HOUR }, + { "h", USEC_PER_HOUR }, + { "d", USEC_PER_DAY }, + { "w", USEC_PER_WEEK }, + { "msec", USEC_PER_MSEC }, + { "ms", USEC_PER_MSEC }, + { "m", USEC_PER_MINUTE }, + { "usec", 1ULL }, + { "us", 1ULL }, + { "", USEC_PER_SEC }, + }; + + const char *p; + usec_t r = 0; + + assert(t); + assert(usec); + + p = t; + do { + long long l; + char *e; + unsigned i; + + errno = 0; + l = strtoll(p, &e, 10); + + if (errno != 0) + return -errno; + + if (l < 0) + return -ERANGE; + + if (e == p) + return -EINVAL; + + e += strspn(e, WHITESPACE); + + for (i = 0; i < ELEMENTSOF(table); i++) + if (startswith(e, table[i].suffix)) { + r += (usec_t) l * table[i].usec; + p = e + strlen(table[i].suffix); + break; + } + + if (i >= ELEMENTSOF(table)) + return -EINVAL; + + } while (*p != 0); + + *usec = r; + + return 0; +} + +int parse_bytes(const char *t, off_t *bytes) { + static const struct { + const char *suffix; + off_t factor; + } table[] = { + { "B", 1 }, + { "K", 1024ULL }, + { "M", 1024ULL*1024ULL }, + { "G", 1024ULL*1024ULL*1024ULL }, + { "T", 1024ULL*1024ULL*1024ULL*1024ULL }, + { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "", 1 }, + }; + + const char *p; + off_t r = 0; + + assert(t); + assert(bytes); + + p = t; + do { + long long l; + char *e; + unsigned i; + + errno = 0; + l = strtoll(p, &e, 10); + + if (errno != 0) + return -errno; + + if (l < 0) + return -ERANGE; + + if (e == p) + return -EINVAL; + + e += strspn(e, WHITESPACE); + + for (i = 0; i < ELEMENTSOF(table); i++) + if (startswith(e, table[i].suffix)) { + r += (off_t) l * table[i].factor; + p = e + strlen(table[i].suffix); + break; + } + + if (i >= ELEMENTSOF(table)) + return -EINVAL; + + } while (*p != 0); + + *bytes = r; + + return 0; +} + +int make_stdio(int fd) { + int r, s, t; + + assert(fd >= 0); + + r = dup2(fd, STDIN_FILENO); + s = dup2(fd, STDOUT_FILENO); + t = dup2(fd, STDERR_FILENO); + + if (fd >= 3) + close_nointr_nofail(fd); + + if (r < 0 || s < 0 || t < 0) + return -errno; + + fd_cloexec(STDIN_FILENO, false); + fd_cloexec(STDOUT_FILENO, false); + fd_cloexec(STDERR_FILENO, false); + + return 0; +} + +int make_null_stdio(void) { + int null_fd; + + if ((null_fd = open("/dev/null", O_RDWR|O_NOCTTY)) < 0) + return -errno; + + return make_stdio(null_fd); +} + +bool is_device_path(const char *path) { + + /* Returns true on paths that refer to a device, either in + * sysfs or in /dev */ + + return + path_startswith(path, "/dev/") || + path_startswith(path, "/sys/"); +} + +int dir_is_empty(const char *path) { + DIR *d; + int r; + struct dirent buf, *de; + + if (!(d = opendir(path))) + return -errno; + + for (;;) { + if ((r = readdir_r(d, &buf, &de)) > 0) { + r = -r; + break; + } + + if (!de) { + r = 1; + break; + } + + if (!ignore_file(de->d_name)) { + r = 0; + break; + } + } + + closedir(d); + return r; +} + +unsigned long long random_ull(void) { + int fd; + uint64_t ull; + ssize_t r; + + if ((fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0) + goto fallback; + + r = loop_read(fd, &ull, sizeof(ull), true); + close_nointr_nofail(fd); + + if (r != sizeof(ull)) + goto fallback; + + return ull; + +fallback: + return random() * RAND_MAX + random(); +} + +void rename_process(const char name[8]) { + assert(name); + + /* This is a like a poor man's setproctitle(). It changes the + * comm field, argv[0], and also the glibc's internally used + * name of the process. For the first one a limit of 16 chars + * applies, to the second one usually one of 10 (i.e. length + * of "/sbin/init"), to the third one one of 7 (i.e. length of + * "systemd"). If you pass a longer string it will be + * truncated */ + + prctl(PR_SET_NAME, name); + + if (program_invocation_name) + strncpy(program_invocation_name, name, strlen(program_invocation_name)); + + if (saved_argc > 0) { + int i; + + if (saved_argv[0]) + strncpy(saved_argv[0], name, strlen(saved_argv[0])); + + for (i = 1; i < saved_argc; i++) { + if (!saved_argv[i]) + break; + + memset(saved_argv[i], 0, strlen(saved_argv[i])); + } + } +} + +void sigset_add_many(sigset_t *ss, ...) { + va_list ap; + int sig; + + assert(ss); + + va_start(ap, ss); + while ((sig = va_arg(ap, int)) > 0) + assert_se(sigaddset(ss, sig) == 0); + va_end(ap); +} + +char* gethostname_malloc(void) { + struct utsname u; + + assert_se(uname(&u) >= 0); + + if (u.nodename[0]) + return strdup(u.nodename); + + return strdup(u.sysname); +} + +char* getlogname_malloc(void) { + uid_t uid; + long bufsize; + char *buf, *name; + struct passwd pwbuf, *pw = NULL; + struct stat st; + + if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0) + uid = st.st_uid; + else + uid = getuid(); + + /* Shortcut things to avoid NSS lookups */ + if (uid == 0) + return strdup("root"); + + if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) <= 0) + bufsize = 4096; + + if (!(buf = malloc(bufsize))) + return NULL; + + if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw) { + name = strdup(pw->pw_name); + free(buf); + return name; + } + + free(buf); + + if (asprintf(&name, "%lu", (unsigned long) uid) < 0) + return NULL; + + return name; +} + +int getttyname_malloc(int fd, char **r) { + char path[PATH_MAX], *c; + int k; + + assert(r); + + if ((k = ttyname_r(fd, path, sizeof(path))) != 0) + return -k; + + char_array_0(path); + + if (!(c = strdup(startswith(path, "/dev/") ? path + 5 : path))) + return -ENOMEM; + + *r = c; + return 0; +} + +int getttyname_harder(int fd, char **r) { + int k; + char *s; + + if ((k = getttyname_malloc(fd, &s)) < 0) + return k; + + if (streq(s, "tty")) { + free(s); + return get_ctty(0, NULL, r); + } + + *r = s; + return 0; +} + +int get_ctty_devnr(pid_t pid, dev_t *d) { + int k; + char line[LINE_MAX], *p, *fn; + unsigned long ttynr; + FILE *f; + + if (asprintf(&fn, "/proc/%lu/stat", (unsigned long) (pid <= 0 ? getpid() : pid)) < 0) + return -ENOMEM; + + f = fopen(fn, "re"); + free(fn); + if (!f) + return -errno; + + if (!fgets(line, sizeof(line), f)) { + k = feof(f) ? -EIO : -errno; + fclose(f); + return k; + } + + fclose(f); + + p = strrchr(line, ')'); + if (!p) + return -EIO; + + p++; + + if (sscanf(p, " " + "%*c " /* state */ + "%*d " /* ppid */ + "%*d " /* pgrp */ + "%*d " /* session */ + "%lu ", /* ttynr */ + &ttynr) != 1) + return -EIO; + + *d = (dev_t) ttynr; + return 0; +} + +int get_ctty(pid_t pid, dev_t *_devnr, char **r) { + int k; + char fn[PATH_MAX], *s, *b, *p; + dev_t devnr; + + assert(r); + + k = get_ctty_devnr(pid, &devnr); + if (k < 0) + return k; + + snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr)); + char_array_0(fn); + + if ((k = readlink_malloc(fn, &s)) < 0) { + + if (k != -ENOENT) + return k; + + /* This is an ugly hack */ + if (major(devnr) == 136) { + if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0) + return -ENOMEM; + + *r = b; + if (_devnr) + *_devnr = devnr; + + return 0; + } + + /* Probably something like the ptys which have no + * symlink in /dev/char. Let's return something + * vaguely useful. */ + + if (!(b = strdup(fn + 5))) + return -ENOMEM; + + *r = b; + if (_devnr) + *_devnr = devnr; + + return 0; + } + + if (startswith(s, "/dev/")) + p = s + 5; + else if (startswith(s, "../")) + p = s + 3; + else + p = s; + + b = strdup(p); + free(s); + + if (!b) + return -ENOMEM; + + *r = b; + if (_devnr) + *_devnr = devnr; + + return 0; +} + +static int rm_rf_children(int fd, bool only_dirs, bool honour_sticky) { + DIR *d; + int ret = 0; + + assert(fd >= 0); + + /* This returns the first error we run into, but nevertheless + * tries to go on */ + + if (!(d = fdopendir(fd))) { + close_nointr_nofail(fd); + + return errno == ENOENT ? 0 : -errno; + } + + for (;;) { + struct dirent buf, *de; + bool is_dir, keep_around = false; + int r; + + if ((r = readdir_r(d, &buf, &de)) != 0) { + if (ret == 0) + ret = -r; + break; + } + + if (!de) + break; + + if (streq(de->d_name, ".") || streq(de->d_name, "..")) + continue; + + if (de->d_type == DT_UNKNOWN) { + struct stat st; + + if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + continue; + } + + if (honour_sticky) + keep_around = + (st.st_uid == 0 || st.st_uid == getuid()) && + (st.st_mode & S_ISVTX); + + is_dir = S_ISDIR(st.st_mode); + + } else { + if (honour_sticky) { + struct stat st; + + if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + continue; + } + + keep_around = + (st.st_uid == 0 || st.st_uid == getuid()) && + (st.st_mode & S_ISVTX); + } + + is_dir = de->d_type == DT_DIR; + } + + if (is_dir) { + int subdir_fd; + + if ((subdir_fd = openat(fd, de->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC)) < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + continue; + } + + if ((r = rm_rf_children(subdir_fd, only_dirs, honour_sticky)) < 0) { + if (ret == 0) + ret = r; + } + + if (!keep_around) + if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + } + + } else if (!only_dirs && !keep_around) { + + if (unlinkat(fd, de->d_name, 0) < 0) { + if (ret == 0 && errno != ENOENT) + ret = -errno; + } + } + } + + closedir(d); + + return ret; +} + +int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) { + int fd; + int r; + + assert(path); + + if ((fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC)) < 0) { + + if (errno != ENOTDIR) + return -errno; + + if (delete_root && !only_dirs) + if (unlink(path) < 0) + return -errno; + + return 0; + } + + r = rm_rf_children(fd, only_dirs, honour_sticky); + + if (delete_root) { + + if (honour_sticky && file_is_priv_sticky(path) > 0) + return r; + + if (rmdir(path) < 0 && errno != ENOENT) { + if (r == 0) + r = -errno; + } + } + + return r; +} + +int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { + assert(path); + + /* Under the assumption that we are running privileged we + * first change the access mode and only then hand out + * ownership to avoid a window where access is too open. */ + + if (mode != (mode_t) -1) + if (chmod(path, mode) < 0) + return -errno; + + if (uid != (uid_t) -1 || gid != (gid_t) -1) + if (chown(path, uid, gid) < 0) + return -errno; + + return 0; +} + +int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) { + assert(fd >= 0); + + /* Under the assumption that we are running privileged we + * first change the access mode and only then hand out + * ownership to avoid a window where access is too open. */ + + if (fchmod(fd, mode) < 0) + return -errno; + + if (fchown(fd, uid, gid) < 0) + return -errno; + + return 0; +} + +cpu_set_t* cpu_set_malloc(unsigned *ncpus) { + cpu_set_t *r; + unsigned n = 1024; + + /* Allocates the cpuset in the right size */ + + for (;;) { + if (!(r = CPU_ALLOC(n))) + return NULL; + + if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) { + CPU_ZERO_S(CPU_ALLOC_SIZE(n), r); + + if (ncpus) + *ncpus = n; + + return r; + } + + CPU_FREE(r); + + if (errno != EINVAL) + return NULL; + + n *= 2; + } +} + +void status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) { + char *s = NULL, *spaces = NULL, *e; + int fd = -1, c; + size_t emax, sl, left; + struct iovec iovec[5]; + int n = 0; + + assert(format); + + /* This independent of logging, as status messages are + * optional and go exclusively to the console. */ + + if (vasprintf(&s, format, ap) < 0) + goto finish; + + fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + goto finish; + + if (ellipse) { + c = fd_columns(fd); + if (c <= 0) + c = 80; + + if (status) { + sl = 2 + 6 + 1; /* " [" status "]" */ + emax = (size_t) c > sl ? c - sl - 1 : 0; + } else + emax = c - 1; + + e = ellipsize(s, emax, 75); + if (e) { + free(s); + s = e; + } + } + + zero(iovec); + IOVEC_SET_STRING(iovec[n++], s); + + if (ellipse) { + sl = strlen(s); + left = emax > sl ? emax - sl : 0; + if (left > 0) { + spaces = malloc(left); + if (spaces) { + memset(spaces, ' ', left); + iovec[n].iov_base = spaces; + iovec[n].iov_len = left; + n++; + } + } + } + + if (status) { + IOVEC_SET_STRING(iovec[n++], " ["); + IOVEC_SET_STRING(iovec[n++], status); + IOVEC_SET_STRING(iovec[n++], "]\n"); + } else + IOVEC_SET_STRING(iovec[n++], "\n"); + + writev(fd, iovec, n); + +finish: + free(s); + free(spaces); + + if (fd >= 0) + close_nointr_nofail(fd); +} + +void status_printf(const char *status, bool ellipse, const char *format, ...) { + va_list ap; + + assert(format); + + va_start(ap, format); + status_vprintf(status, ellipse, format, ap); + va_end(ap); +} + +void status_welcome(void) { + char *pretty_name = NULL, *ansi_color = NULL; + const char *const_pretty = NULL, *const_color = NULL; + int r; + + if ((r = parse_env_file("/etc/os-release", NEWLINE, + "PRETTY_NAME", &pretty_name, + "ANSI_COLOR", &ansi_color, + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/os-release: %s", strerror(-r)); + } + + if (!pretty_name && !const_pretty) + const_pretty = "Linux"; + + if (!ansi_color && !const_color) + const_color = "1"; + + status_printf(NULL, + false, + "\nWelcome to \x1B[%sm%s\x1B[0m!\n", + const_color ? const_color : ansi_color, + const_pretty ? const_pretty : pretty_name); + + free(ansi_color); + free(pretty_name); +} + +char *replace_env(const char *format, char **env) { + enum { + WORD, + CURLY, + VARIABLE + } state = WORD; + + const char *e, *word = format; + char *r = NULL, *k; + + assert(format); + + for (e = format; *e; e ++) { + + switch (state) { + + case WORD: + if (*e == '$') + state = CURLY; + break; + + case CURLY: + if (*e == '{') { + if (!(k = strnappend(r, word, e-word-1))) + goto fail; + + free(r); + r = k; + + word = e-1; + state = VARIABLE; + + } else if (*e == '$') { + if (!(k = strnappend(r, word, e-word))) + goto fail; + + free(r); + r = k; + + word = e+1; + state = WORD; + } else + state = WORD; + break; + + case VARIABLE: + if (*e == '}') { + const char *t; + + if (!(t = strv_env_get_with_length(env, word+2, e-word-2))) + t = ""; + + if (!(k = strappend(r, t))) + goto fail; + + free(r); + r = k; + + word = e+1; + state = WORD; + } + break; + } + } + + if (!(k = strnappend(r, word, e-word))) + goto fail; + + free(r); + return k; + +fail: + free(r); + return NULL; +} + +char **replace_env_argv(char **argv, char **env) { + char **r, **i; + unsigned k = 0, l = 0; + + l = strv_length(argv); + + if (!(r = new(char*, l+1))) + return NULL; + + STRV_FOREACH(i, argv) { + + /* If $FOO appears as single word, replace it by the split up variable */ + if ((*i)[0] == '$' && (*i)[1] != '{') { + char *e; + char **w, **m; + unsigned q; + + if ((e = strv_env_get(env, *i+1))) { + + if (!(m = strv_split_quoted(e))) { + r[k] = NULL; + strv_free(r); + return NULL; + } + } else + m = NULL; + + q = strv_length(m); + l = l + q - 1; + + if (!(w = realloc(r, sizeof(char*) * (l+1)))) { + r[k] = NULL; + strv_free(r); + strv_free(m); + return NULL; + } + + r = w; + if (m) { + memcpy(r + k, m, q * sizeof(char*)); + free(m); + } + + k += q; + continue; + } + + /* If ${FOO} appears as part of a word, replace it by the variable as-is */ + if (!(r[k++] = replace_env(*i, env))) { + strv_free(r); + return NULL; + } + } + + r[k] = NULL; + return r; +} + +int fd_columns(int fd) { + struct winsize ws; + zero(ws); + + if (ioctl(fd, TIOCGWINSZ, &ws) < 0) + return -errno; + + if (ws.ws_col <= 0) + return -EIO; + + return ws.ws_col; +} + +unsigned columns(void) { + static __thread int parsed_columns = 0; + const char *e; + + if (_likely_(parsed_columns > 0)) + return parsed_columns; + + e = getenv("COLUMNS"); + if (e) + parsed_columns = atoi(e); + + if (parsed_columns <= 0) + parsed_columns = fd_columns(STDOUT_FILENO); + + if (parsed_columns <= 0) + parsed_columns = 80; + + return parsed_columns; +} + +int fd_lines(int fd) { + struct winsize ws; + zero(ws); + + if (ioctl(fd, TIOCGWINSZ, &ws) < 0) + return -errno; + + if (ws.ws_row <= 0) + return -EIO; + + return ws.ws_row; +} + +unsigned lines(void) { + static __thread int parsed_lines = 0; + const char *e; + + if (_likely_(parsed_lines > 0)) + return parsed_lines; + + e = getenv("LINES"); + if (e) + parsed_lines = atoi(e); + + if (parsed_lines <= 0) + parsed_lines = fd_lines(STDOUT_FILENO); + + if (parsed_lines <= 0) + parsed_lines = 25; + + return parsed_lines; +} + +int running_in_chroot(void) { + struct stat a, b; + + zero(a); + zero(b); + + /* Only works as root */ + + if (stat("/proc/1/root", &a) < 0) + return -errno; + + if (stat("/", &b) < 0) + return -errno; + + return + a.st_dev != b.st_dev || + a.st_ino != b.st_ino; +} + +char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) { + size_t x; + char *r; + + assert(s); + assert(percent <= 100); + assert(new_length >= 3); + + if (old_length <= 3 || old_length <= new_length) + return strndup(s, old_length); + + r = new0(char, new_length+1); + if (!r) + return r; + + x = (new_length * percent) / 100; + + if (x > new_length - 3) + x = new_length - 3; + + memcpy(r, s, x); + r[x] = '.'; + r[x+1] = '.'; + r[x+2] = '.'; + memcpy(r + x + 3, + s + old_length - (new_length - x - 3), + new_length - x - 3); + + return r; +} + +char *ellipsize(const char *s, size_t length, unsigned percent) { + return ellipsize_mem(s, strlen(s), length, percent); +} + +int touch(const char *path) { + int fd; + + assert(path); + + if ((fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644)) < 0) + return -errno; + + close_nointr_nofail(fd); + return 0; +} + +char *unquote(const char *s, const char* quotes) { + size_t l; + assert(s); + + l = strlen(s); + if (l < 2) + return strdup(s); + + if (strchr(quotes, s[0]) && s[l-1] == s[0]) + return strndup(s+1, l-2); + + return strdup(s); +} + +char *normalize_env_assignment(const char *s) { + char *name, *value, *p, *r; + + p = strchr(s, '='); + + if (!p) { + if (!(r = strdup(s))) + return NULL; + + return strstrip(r); + } + + if (!(name = strndup(s, p - s))) + return NULL; + + if (!(p = strdup(p+1))) { + free(name); + return NULL; + } + + value = unquote(strstrip(p), QUOTES); + free(p); + + if (!value) { + free(name); + return NULL; + } + + if (asprintf(&r, "%s=%s", name, value) < 0) + r = NULL; + + free(value); + free(name); + + return r; +} + +int wait_for_terminate(pid_t pid, siginfo_t *status) { + siginfo_t dummy; + + assert(pid >= 1); + + if (!status) + status = &dummy; + + for (;;) { + zero(*status); + + if (waitid(P_PID, pid, status, WEXITED) < 0) { + + if (errno == EINTR) + continue; + + return -errno; + } + + return 0; + } +} + +int wait_for_terminate_and_warn(const char *name, pid_t pid) { + int r; + siginfo_t status; + + assert(name); + assert(pid > 1); + + if ((r = wait_for_terminate(pid, &status)) < 0) { + log_warning("Failed to wait for %s: %s", name, strerror(-r)); + return r; + } + + if (status.si_code == CLD_EXITED) { + if (status.si_status != 0) { + log_warning("%s failed with error code %i.", name, status.si_status); + return status.si_status; + } + + log_debug("%s succeeded.", name); + return 0; + + } else if (status.si_code == CLD_KILLED || + status.si_code == CLD_DUMPED) { + + log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status)); + return -EPROTO; + } + + log_warning("%s failed due to unknown reason.", name); + return -EPROTO; + +} + +void freeze(void) { + + /* Make sure nobody waits for us on a socket anymore */ + close_all_fds(NULL, 0); + + sync(); + + for (;;) + pause(); +} + +bool null_or_empty(struct stat *st) { + assert(st); + + if (S_ISREG(st->st_mode) && st->st_size <= 0) + return true; + + if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) + return true; + + return false; +} + +int null_or_empty_path(const char *fn) { + struct stat st; + + assert(fn); + + if (stat(fn, &st) < 0) + return -errno; + + return null_or_empty(&st); +} + +DIR *xopendirat(int fd, const char *name, int flags) { + int nfd; + DIR *d; + + if ((nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags)) < 0) + return NULL; + + if (!(d = fdopendir(nfd))) { + close_nointr_nofail(nfd); + return NULL; + } + + return d; +} + +int signal_from_string_try_harder(const char *s) { + int signo; + assert(s); + + if ((signo = signal_from_string(s)) <= 0) + if (startswith(s, "SIG")) + return signal_from_string(s+3); + + return signo; +} + +void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) { + + assert(f); + assert(name); + assert(t); + + if (!dual_timestamp_is_set(t)) + return; + + fprintf(f, "%s=%llu %llu\n", + name, + (unsigned long long) t->realtime, + (unsigned long long) t->monotonic); +} + +void dual_timestamp_deserialize(const char *value, dual_timestamp *t) { + unsigned long long a, b; + + assert(value); + assert(t); + + if (sscanf(value, "%lli %llu", &a, &b) != 2) + log_debug("Failed to parse finish timestamp value %s", value); + else { + t->realtime = a; + t->monotonic = b; + } +} + +char *fstab_node_to_udev_node(const char *p) { + char *dn, *t, *u; + int r; + + /* FIXME: to follow udev's logic 100% we need to leave valid + * UTF8 chars unescaped */ + + if (startswith(p, "LABEL=")) { + + if (!(u = unquote(p+6, "\"\'"))) + return NULL; + + t = xescape(u, "/ "); + free(u); + + if (!t) + return NULL; + + r = asprintf(&dn, "/dev/disk/by-label/%s", t); + free(t); + + if (r < 0) + return NULL; + + return dn; + } + + if (startswith(p, "UUID=")) { + + if (!(u = unquote(p+5, "\"\'"))) + return NULL; + + t = xescape(u, "/ "); + free(u); + + if (!t) + return NULL; + + r = asprintf(&dn, "/dev/disk/by-uuid/%s", t); + free(t); + + if (r < 0) + return NULL; + + return dn; + } + + return strdup(p); +} + +void filter_environ(const char *prefix) { + int i, j; + assert(prefix); + + if (!environ) + return; + + for (i = 0, j = 0; environ[i]; i++) { + + if (startswith(environ[i], prefix)) + continue; + + environ[j++] = environ[i]; + } + + environ[j] = NULL; +} + +bool tty_is_vc(const char *tty) { + assert(tty); + + if (startswith(tty, "/dev/")) + tty += 5; + + return vtnr_from_tty(tty) >= 0; +} + +int vtnr_from_tty(const char *tty) { + int i, r; + + assert(tty); + + if (startswith(tty, "/dev/")) + tty += 5; + + if (!startswith(tty, "tty") ) + return -EINVAL; + + if (tty[3] < '0' || tty[3] > '9') + return -EINVAL; + + r = safe_atoi(tty+3, &i); + if (r < 0) + return r; + + if (i < 0 || i > 63) + return -EINVAL; + + return i; +} + +bool tty_is_vc_resolve(const char *tty) { + char *active = NULL; + bool b; + + assert(tty); + + if (startswith(tty, "/dev/")) + tty += 5; + + /* Resolve where /dev/console is pointing to */ + if (streq(tty, "console")) + if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) { + /* If multiple log outputs are configured the + * last one is what /dev/console points to */ + tty = strrchr(active, ' '); + if (tty) + tty++; + else + tty = active; + } + + b = tty_is_vc(tty); + free(active); + + return b; +} + +const char *default_term_for_tty(const char *tty) { + assert(tty); + + return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt100"; +} + +bool dirent_is_file(const struct dirent *de) { + assert(de); + + if (ignore_file(de->d_name)) + return false; + + if (de->d_type != DT_REG && + de->d_type != DT_LNK && + de->d_type != DT_UNKNOWN) + return false; + + return true; +} + +bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) { + assert(de); + + if (!dirent_is_file(de)) + return false; + + return endswith(de->d_name, suffix); +} + +void execute_directory(const char *directory, DIR *d, char *argv[]) { + DIR *_d = NULL; + struct dirent *de; + Hashmap *pids = NULL; + + assert(directory); + + /* Executes all binaries in a directory in parallel and waits + * until all they all finished. */ + + if (!d) { + if (!(_d = opendir(directory))) { + + if (errno == ENOENT) + return; + + log_error("Failed to enumerate directory %s: %m", directory); + return; + } + + d = _d; + } + + if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) { + log_error("Failed to allocate set."); + goto finish; + } + + while ((de = readdir(d))) { + char *path; + pid_t pid; + int k; + + if (!dirent_is_file(de)) + continue; + + if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) { + log_error("Out of memory"); + continue; + } + + if ((pid = fork()) < 0) { + log_error("Failed to fork: %m"); + free(path); + continue; + } + + if (pid == 0) { + char *_argv[2]; + /* Child */ + + if (!argv) { + _argv[0] = path; + _argv[1] = NULL; + argv = _argv; + } else + if (!argv[0]) + argv[0] = path; + + execv(path, argv); + + log_error("Failed to execute %s: %m", path); + _exit(EXIT_FAILURE); + } + + log_debug("Spawned %s as %lu", path, (unsigned long) pid); + + if ((k = hashmap_put(pids, UINT_TO_PTR(pid), path)) < 0) { + log_error("Failed to add PID to set: %s", strerror(-k)); + free(path); + } + } + + while (!hashmap_isempty(pids)) { + pid_t pid = PTR_TO_UINT(hashmap_first_key(pids)); + siginfo_t si; + char *path; + + zero(si); + if (waitid(P_PID, pid, &si, WEXITED) < 0) { + + if (errno == EINTR) + continue; + + log_error("waitid() failed: %m"); + goto finish; + } + + if ((path = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) { + if (!is_clean_exit(si.si_code, si.si_status)) { + if (si.si_code == CLD_EXITED) + log_error("%s exited with exit status %i.", path, si.si_status); + else + log_error("%s terminated by signal %s.", path, signal_to_string(si.si_status)); + } else + log_debug("%s exited successfully.", path); + + free(path); + } + } + +finish: + if (_d) + closedir(_d); + + if (pids) + hashmap_free_free(pids); +} + +int kill_and_sigcont(pid_t pid, int sig) { + int r; + + r = kill(pid, sig) < 0 ? -errno : 0; + + if (r >= 0) + kill(pid, SIGCONT); + + return r; +} + +bool nulstr_contains(const char*nulstr, const char *needle) { + const char *i; + + if (!nulstr) + return false; + + NULSTR_FOREACH(i, nulstr) + if (streq(i, needle)) + return true; + + return false; +} + +bool plymouth_running(void) { + return access("/run/plymouth/pid", F_OK) >= 0; +} + +void parse_syslog_priority(char **p, int *priority) { + int a = 0, b = 0, c = 0; + int k; + + assert(p); + assert(*p); + assert(priority); + + if ((*p)[0] != '<') + return; + + if (!strchr(*p, '>')) + return; + + if ((*p)[2] == '>') { + c = undecchar((*p)[1]); + k = 3; + } else if ((*p)[3] == '>') { + b = undecchar((*p)[1]); + c = undecchar((*p)[2]); + k = 4; + } else if ((*p)[4] == '>') { + a = undecchar((*p)[1]); + b = undecchar((*p)[2]); + c = undecchar((*p)[3]); + k = 5; + } else + return; + + if (a < 0 || b < 0 || c < 0) + return; + + *priority = a*100+b*10+c; + *p += k; +} + +void skip_syslog_pid(char **buf) { + char *p; + + assert(buf); + assert(*buf); + + p = *buf; + + if (*p != '[') + return; + + p++; + p += strspn(p, "0123456789"); + + if (*p != ']') + return; + + p++; + + *buf = p; +} + +void skip_syslog_date(char **buf) { + enum { + LETTER, + SPACE, + NUMBER, + SPACE_OR_NUMBER, + COLON + } sequence[] = { + LETTER, LETTER, LETTER, + SPACE, + SPACE_OR_NUMBER, NUMBER, + SPACE, + SPACE_OR_NUMBER, NUMBER, + COLON, + SPACE_OR_NUMBER, NUMBER, + COLON, + SPACE_OR_NUMBER, NUMBER, + SPACE + }; + + char *p; + unsigned i; + + assert(buf); + assert(*buf); + + p = *buf; + + for (i = 0; i < ELEMENTSOF(sequence); i++, p++) { + + if (!*p) + return; + + switch (sequence[i]) { + + case SPACE: + if (*p != ' ') + return; + break; + + case SPACE_OR_NUMBER: + if (*p == ' ') + break; + + /* fall through */ + + case NUMBER: + if (*p < '0' || *p > '9') + return; + + break; + + case LETTER: + if (!(*p >= 'A' && *p <= 'Z') && + !(*p >= 'a' && *p <= 'z')) + return; + + break; + + case COLON: + if (*p != ':') + return; + break; + + } + } + + *buf = p; +} + +int have_effective_cap(int value) { + cap_t cap; + cap_flag_value_t fv; + int r; + + if (!(cap = cap_get_proc())) + return -errno; + + if (cap_get_flag(cap, value, CAP_EFFECTIVE, &fv) < 0) + r = -errno; + else + r = fv == CAP_SET; + + cap_free(cap); + return r; +} + +char* strshorten(char *s, size_t l) { + assert(s); + + if (l < strlen(s)) + s[l] = 0; + + return s; +} + +static bool hostname_valid_char(char c) { + return + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '-' || + c == '_' || + c == '.'; +} + +bool hostname_is_valid(const char *s) { + const char *p; + + if (isempty(s)) + return false; + + for (p = s; *p; p++) + if (!hostname_valid_char(*p)) + return false; + + if (p-s > HOST_NAME_MAX) + return false; + + return true; +} + +char* hostname_cleanup(char *s) { + char *p, *d; + + for (p = s, d = s; *p; p++) + if ((*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9') || + *p == '-' || + *p == '_' || + *p == '.') + *(d++) = *p; + + *d = 0; + + strshorten(s, HOST_NAME_MAX); + return s; +} + +int pipe_eof(int fd) { + struct pollfd pollfd; + int r; + + zero(pollfd); + pollfd.fd = fd; + pollfd.events = POLLIN|POLLHUP; + + r = poll(&pollfd, 1, 0); + if (r < 0) + return -errno; + + if (r == 0) + return 0; + + return pollfd.revents & POLLHUP; +} + +int fd_wait_for_event(int fd, int event, usec_t t) { + struct pollfd pollfd; + int r; + + zero(pollfd); + pollfd.fd = fd; + pollfd.events = event; + + r = poll(&pollfd, 1, t == (usec_t) -1 ? -1 : (int) (t / USEC_PER_MSEC)); + if (r < 0) + return -errno; + + if (r == 0) + return 0; + + return pollfd.revents; +} + +int fopen_temporary(const char *path, FILE **_f, char **_temp_path) { + FILE *f; + char *t; + const char *fn; + size_t k; + int fd; + + assert(path); + assert(_f); + assert(_temp_path); + + t = new(char, strlen(path) + 1 + 6 + 1); + if (!t) + return -ENOMEM; + + fn = file_name_from_path(path); + k = fn-path; + memcpy(t, path, k); + t[k] = '.'; + stpcpy(stpcpy(t+k+1, fn), "XXXXXX"); + + fd = mkostemp(t, O_WRONLY|O_CLOEXEC); + if (fd < 0) { + free(t); + return -errno; + } + + f = fdopen(fd, "we"); + if (!f) { + unlink(t); + free(t); + return -errno; + } + + *_f = f; + *_temp_path = t; + + return 0; +} + +int terminal_vhangup_fd(int fd) { + assert(fd >= 0); + + if (ioctl(fd, TIOCVHANGUP) < 0) + return -errno; + + return 0; +} + +int terminal_vhangup(const char *name) { + int fd, r; + + fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + r = terminal_vhangup_fd(fd); + close_nointr_nofail(fd); + + return r; +} + +int vt_disallocate(const char *name) { + int fd, r; + unsigned u; + + /* Deallocate the VT if possible. If not possible + * (i.e. because it is the active one), at least clear it + * entirely (including the scrollback buffer) */ + + if (!startswith(name, "/dev/")) + return -EINVAL; + + if (!tty_is_vc(name)) { + /* So this is not a VT. I guess we cannot deallocate + * it then. But let's at least clear the screen */ + + fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + loop_write(fd, + "\033[r" /* clear scrolling region */ + "\033[H" /* move home */ + "\033[2J", /* clear screen */ + 10, false); + close_nointr_nofail(fd); + + return 0; + } + + if (!startswith(name, "/dev/tty")) + return -EINVAL; + + r = safe_atou(name+8, &u); + if (r < 0) + return r; + + if (u <= 0) + return -EINVAL; + + /* Try to deallocate */ + fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + r = ioctl(fd, VT_DISALLOCATE, u); + close_nointr_nofail(fd); + + if (r >= 0) + return 0; + + if (errno != EBUSY) + return -errno; + + /* Couldn't deallocate, so let's clear it fully with + * scrollback */ + fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC); + if (fd < 0) + return fd; + + loop_write(fd, + "\033[r" /* clear scrolling region */ + "\033[H" /* move home */ + "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */ + 10, false); + close_nointr_nofail(fd); + + return 0; +} + +static int files_add(Hashmap *h, const char *path, const char *suffix) { + DIR *dir; + struct dirent buffer, *de; + int r = 0; + + dir = opendir(path); + if (!dir) { + if (errno == ENOENT) + return 0; + return -errno; + } + + for (;;) { + int k; + char *p, *f; + + k = readdir_r(dir, &buffer, &de); + if (k != 0) { + r = -k; + goto finish; + } + + if (!de) + break; + + if (!dirent_is_file_with_suffix(de, suffix)) + continue; + + if (asprintf(&p, "%s/%s", path, de->d_name) < 0) { + r = -ENOMEM; + goto finish; + } + + f = canonicalize_file_name(p); + if (!f) { + log_error("Failed to canonicalize file name '%s': %m", p); + free(p); + continue; + } + free(p); + + log_debug("found: %s\n", f); + if (hashmap_put(h, file_name_from_path(f), f) <= 0) + free(f); + } + +finish: + closedir(dir); + return r; +} + +static int base_cmp(const void *a, const void *b) { + const char *s1, *s2; + + s1 = *(char * const *)a; + s2 = *(char * const *)b; + return strcmp(file_name_from_path(s1), file_name_from_path(s2)); +} + +int conf_files_list(char ***strv, const char *suffix, const char *dir, ...) { + Hashmap *fh = NULL; + char **dirs = NULL; + char **files = NULL; + char **p; + va_list ap; + int r = 0; + + va_start(ap, dir); + dirs = strv_new_ap(dir, ap); + va_end(ap); + if (!dirs) { + r = -ENOMEM; + goto finish; + } + if (!strv_path_canonicalize(dirs)) { + r = -ENOMEM; + goto finish; + } + if (!strv_uniq(dirs)) { + r = -ENOMEM; + goto finish; + } + + fh = hashmap_new(string_hash_func, string_compare_func); + if (!fh) { + r = -ENOMEM; + goto finish; + } + + STRV_FOREACH(p, dirs) { + if (files_add(fh, *p, suffix) < 0) { + log_error("Failed to search for files."); + r = -EINVAL; + goto finish; + } + } + + files = hashmap_get_strv(fh); + if (files == NULL) { + log_error("Failed to compose list of files."); + r = -ENOMEM; + goto finish; + } + + qsort(files, hashmap_size(fh), sizeof(char *), base_cmp); + +finish: + strv_free(dirs); + hashmap_free(fh); + *strv = files; + return r; +} + +int hwclock_is_localtime(void) { + FILE *f; + bool local = false; + + /* + * The third line of adjtime is "UTC" or "LOCAL" or nothing. + * # /etc/adjtime + * 0.0 0 0 + * 0 + * UTC + */ + f = fopen("/etc/adjtime", "re"); + if (f) { + char line[LINE_MAX]; + bool b; + + b = fgets(line, sizeof(line), f) && + fgets(line, sizeof(line), f) && + fgets(line, sizeof(line), f); + + fclose(f); + + if (!b) + return -EIO; + + + truncate_nl(line); + local = streq(line, "LOCAL"); + + } else if (errno != -ENOENT) + return -errno; + + return local; +} + +int hwclock_apply_localtime_delta(int *min) { + const struct timeval *tv_null = NULL; + struct timespec ts; + struct tm *tm; + int minuteswest; + struct timezone tz; + + assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0); + assert_se(tm = localtime(&ts.tv_sec)); + minuteswest = tm->tm_gmtoff / 60; + + tz.tz_minuteswest = -minuteswest; + tz.tz_dsttime = 0; /* DST_NONE*/ + + /* + * If the hardware clock does not run in UTC, but in local time: + * The very first time we set the kernel's timezone, it will warp + * the clock so that it runs in UTC instead of local time. + */ + if (settimeofday(tv_null, &tz) < 0) + return -errno; + if (min) + *min = minuteswest; + return 0; +} + +int hwclock_reset_localtime_delta(void) { + const struct timeval *tv_null = NULL; + struct timezone tz; + + tz.tz_minuteswest = 0; + tz.tz_dsttime = 0; /* DST_NONE*/ + + if (settimeofday(tv_null, &tz) < 0) + return -errno; + + return 0; +} + +int rtc_open(int flags) { + int fd; + DIR *d; + + /* First, we try to make use of the /dev/rtc symlink. If that + * doesn't exist, we open the first RTC which has hctosys=1 + * set. If we don't find any we just take the first RTC that + * exists at all. */ + + fd = open("/dev/rtc", flags); + if (fd >= 0) + return fd; + + d = opendir("/sys/class/rtc"); + if (!d) + goto fallback; + + for (;;) { + char *p, *v; + struct dirent buf, *de; + int r; + + r = readdir_r(d, &buf, &de); + if (r != 0) + goto fallback; + + if (!de) + goto fallback; + + if (ignore_file(de->d_name)) + continue; + + p = join("/sys/class/rtc/", de->d_name, "/hctosys", NULL); + if (!p) { + closedir(d); + return -ENOMEM; + } + + r = read_one_line_file(p, &v); + free(p); + + if (r < 0) + continue; + + r = parse_boolean(v); + free(v); + + if (r <= 0) + continue; + + p = strappend("/dev/", de->d_name); + fd = open(p, flags); + free(p); + + if (fd >= 0) { + closedir(d); + return fd; + } + } + +fallback: + if (d) + closedir(d); + + fd = open("/dev/rtc0", flags); + if (fd < 0) + return -errno; + + return fd; +} + +int hwclock_get_time(struct tm *tm) { + int fd; + int err = 0; + + assert(tm); + + fd = rtc_open(O_RDONLY|O_CLOEXEC); + if (fd < 0) + return -errno; + + /* This leaves the timezone fields of struct tm + * uninitialized! */ + if (ioctl(fd, RTC_RD_TIME, tm) < 0) + err = -errno; + + /* We don't now daylight saving, so we reset this in order not + * to confused mktime(). */ + tm->tm_isdst = -1; + + close_nointr_nofail(fd); + + return err; +} + +int hwclock_set_time(const struct tm *tm) { + int fd; + int err = 0; + + assert(tm); + + fd = rtc_open(O_RDONLY|O_CLOEXEC); + if (fd < 0) + return -errno; + + if (ioctl(fd, RTC_SET_TIME, tm) < 0) + err = -errno; + + close_nointr_nofail(fd); + + return err; +} + +int copy_file(const char *from, const char *to) { + int r, fdf, fdt; + + assert(from); + assert(to); + + fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fdf < 0) + return -errno; + + fdt = open(to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY, 0644); + if (fdt < 0) { + close_nointr_nofail(fdf); + return -errno; + } + + for (;;) { + char buf[PIPE_BUF]; + ssize_t n, k; + + n = read(fdf, buf, sizeof(buf)); + if (n < 0) { + r = -errno; + + close_nointr_nofail(fdf); + close_nointr(fdt); + unlink(to); + + return r; + } + + if (n == 0) + break; + + errno = 0; + k = loop_write(fdt, buf, n, false); + if (n != k) { + r = k < 0 ? k : (errno ? -errno : -EIO); + + close_nointr_nofail(fdf); + close_nointr(fdt); + + unlink(to); + return r; + } + } + + close_nointr_nofail(fdf); + r = close_nointr(fdt); + + if (r < 0) { + unlink(to); + return r; + } + + return 0; +} + +int symlink_or_copy(const char *from, const char *to) { + char *pf = NULL, *pt = NULL; + struct stat a, b; + int r; + + assert(from); + assert(to); + + if (parent_of_path(from, &pf) < 0 || + parent_of_path(to, &pt) < 0) { + r = -ENOMEM; + goto finish; + } + + if (stat(pf, &a) < 0 || + stat(pt, &b) < 0) { + r = -errno; + goto finish; + } + + if (a.st_dev != b.st_dev) { + free(pf); + free(pt); + + return copy_file(from, to); + } + + if (symlink(from, to) < 0) { + r = -errno; + goto finish; + } + + r = 0; + +finish: + free(pf); + free(pt); + + return r; +} + +int symlink_or_copy_atomic(const char *from, const char *to) { + char *t, *x; + const char *fn; + size_t k; + unsigned long long ull; + unsigned i; + int r; + + assert(from); + assert(to); + + t = new(char, strlen(to) + 1 + 16 + 1); + if (!t) + return -ENOMEM; + + fn = file_name_from_path(to); + k = fn-to; + memcpy(t, to, k); + t[k] = '.'; + x = stpcpy(t+k+1, fn); + + ull = random_ull(); + for (i = 0; i < 16; i++) { + *(x++) = hexchar(ull & 0xF); + ull >>= 4; + } + + *x = 0; + + r = symlink_or_copy(from, t); + if (r < 0) { + unlink(t); + free(t); + return r; + } + + if (rename(t, to) < 0) { + r = -errno; + unlink(t); + free(t); + return r; + } + + free(t); + return r; +} + +int audit_session_from_pid(pid_t pid, uint32_t *id) { + char *s; + uint32_t u; + int r; + + assert(id); + + if (have_effective_cap(CAP_AUDIT_CONTROL) <= 0) + return -ENOENT; + + if (pid == 0) + r = read_one_line_file("/proc/self/sessionid", &s); + else { + char *p; + + if (asprintf(&p, "/proc/%lu/sessionid", (unsigned long) pid) < 0) + return -ENOMEM; + + r = read_one_line_file(p, &s); + free(p); + } + + if (r < 0) + return r; + + r = safe_atou32(s, &u); + free(s); + + if (r < 0) + return r; + + if (u == (uint32_t) -1 || u <= 0) + return -ENOENT; + + *id = u; + return 0; +} + +int audit_loginuid_from_pid(pid_t pid, uid_t *uid) { + char *s; + uid_t u; + int r; + + assert(uid); + + /* Only use audit login uid if we are executed with sufficient + * capabilities so that pam_loginuid could do its job. If we + * are lacking the CAP_AUDIT_CONTROL capabality we most likely + * are being run in a container and /proc/self/loginuid is + * useless since it probably contains a uid of the host + * system. */ + + if (have_effective_cap(CAP_AUDIT_CONTROL) <= 0) + return -ENOENT; + + if (pid == 0) + r = read_one_line_file("/proc/self/loginuid", &s); + else { + char *p; + + if (asprintf(&p, "/proc/%lu/loginuid", (unsigned long) pid) < 0) + return -ENOMEM; + + r = read_one_line_file(p, &s); + free(p); + } + + if (r < 0) + return r; + + r = parse_uid(s, &u); + free(s); + + if (r < 0) + return r; + + if (u == (uid_t) -1) + return -ENOENT; + + *uid = (uid_t) u; + return 0; +} + +bool display_is_local(const char *display) { + assert(display); + + return + display[0] == ':' && + display[1] >= '0' && + display[1] <= '9'; +} + +int socket_from_display(const char *display, char **path) { + size_t k; + char *f, *c; + + assert(display); + assert(path); + + if (!display_is_local(display)) + return -EINVAL; + + k = strspn(display+1, "0123456789"); + + f = new(char, sizeof("/tmp/.X11-unix/X") + k); + if (!f) + return -ENOMEM; + + c = stpcpy(f, "/tmp/.X11-unix/X"); + memcpy(c, display+1, k); + c[k] = 0; + + *path = f; + + return 0; +} + +int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home) { + struct passwd *p; + uid_t u; + + assert(username); + assert(*username); + + /* We enforce some special rules for uid=0: in order to avoid + * NSS lookups for root we hardcode its data. */ + + if (streq(*username, "root") || streq(*username, "0")) { + *username = "root"; + + if (uid) + *uid = 0; + + if (gid) + *gid = 0; + + if (home) + *home = "/root"; + return 0; + } + + if (parse_uid(*username, &u) >= 0) { + errno = 0; + p = getpwuid(u); + + /* If there are multiple users with the same id, make + * sure to leave $USER to the configured value instead + * of the first occurrence in the database. However if + * the uid was configured by a numeric uid, then let's + * pick the real username from /etc/passwd. */ + if (p) + *username = p->pw_name; + } else { + errno = 0; + p = getpwnam(*username); + } + + if (!p) + return errno != 0 ? -errno : -ESRCH; + + if (uid) + *uid = p->pw_uid; + + if (gid) + *gid = p->pw_gid; + + if (home) + *home = p->pw_dir; + + return 0; +} + +int get_group_creds(const char **groupname, gid_t *gid) { + struct group *g; + gid_t id; + + assert(groupname); + + /* We enforce some special rules for gid=0: in order to avoid + * NSS lookups for root we hardcode its data. */ + + if (streq(*groupname, "root") || streq(*groupname, "0")) { + *groupname = "root"; + + if (gid) + *gid = 0; + + return 0; + } + + if (parse_gid(*groupname, &id) >= 0) { + errno = 0; + g = getgrgid(id); + + if (g) + *groupname = g->gr_name; + } else { + errno = 0; + g = getgrnam(*groupname); + } + + if (!g) + return errno != 0 ? -errno : -ESRCH; + + if (gid) + *gid = g->gr_gid; + + return 0; +} + +int glob_exists(const char *path) { + glob_t g; + int r, k; + + assert(path); + + zero(g); + errno = 0; + k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g); + + if (k == GLOB_NOMATCH) + r = 0; + else if (k == GLOB_NOSPACE) + r = -ENOMEM; + else if (k == 0) + r = !strv_isempty(g.gl_pathv); + else + r = errno ? -errno : -EIO; + + globfree(&g); + + return r; +} + +int dirent_ensure_type(DIR *d, struct dirent *de) { + struct stat st; + + assert(d); + assert(de); + + if (de->d_type != DT_UNKNOWN) + return 0; + + if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) + return -errno; + + de->d_type = + S_ISREG(st.st_mode) ? DT_REG : + S_ISDIR(st.st_mode) ? DT_DIR : + S_ISLNK(st.st_mode) ? DT_LNK : + S_ISFIFO(st.st_mode) ? DT_FIFO : + S_ISSOCK(st.st_mode) ? DT_SOCK : + S_ISCHR(st.st_mode) ? DT_CHR : + S_ISBLK(st.st_mode) ? DT_BLK : + DT_UNKNOWN; + + return 0; +} + +int in_search_path(const char *path, char **search) { + char **i, *parent; + int r; + + r = parent_of_path(path, &parent); + if (r < 0) + return r; + + r = 0; + + STRV_FOREACH(i, search) { + if (path_equal(parent, *i)) { + r = 1; + break; + } + } + + free(parent); + + return r; +} + +int get_files_in_directory(const char *path, char ***list) { + DIR *d; + int r = 0; + unsigned n = 0; + char **l = NULL; + + assert(path); + + /* Returns all files in a directory in *list, and the number + * of files as return value. If list is NULL returns only the + * number */ + + d = opendir(path); + if (!d) + return -errno; + + for (;;) { + struct dirent buffer, *de; + int k; + + k = readdir_r(d, &buffer, &de); + if (k != 0) { + r = -k; + goto finish; + } + + if (!de) + break; + + dirent_ensure_type(d, de); + + if (!dirent_is_file(de)) + continue; + + if (list) { + if ((unsigned) r >= n) { + char **t; + + n = MAX(16, 2*r); + t = realloc(l, sizeof(char*) * n); + if (!t) { + r = -ENOMEM; + goto finish; + } + + l = t; + } + + assert((unsigned) r < n); + + l[r] = strdup(de->d_name); + if (!l[r]) { + r = -ENOMEM; + goto finish; + } + + l[++r] = NULL; + } else + r++; + } + +finish: + if (d) + closedir(d); + + if (r >= 0) { + if (list) + *list = l; + } else + strv_free(l); + + return r; +} + +char *join(const char *x, ...) { + va_list ap; + size_t l; + char *r, *p; + + va_start(ap, x); + + if (x) { + l = strlen(x); + + for (;;) { + const char *t; + + t = va_arg(ap, const char *); + if (!t) + break; + + l += strlen(t); + } + } else + l = 0; + + va_end(ap); + + r = new(char, l+1); + if (!r) + return NULL; + + if (x) { + p = stpcpy(r, x); + + va_start(ap, x); + + for (;;) { + const char *t; + + t = va_arg(ap, const char *); + if (!t) + break; + + p = stpcpy(p, t); + } + + va_end(ap); + } else + r[0] = 0; + + return r; +} + +bool is_main_thread(void) { + static __thread int cached = 0; + + if (_unlikely_(cached == 0)) + cached = getpid() == gettid() ? 1 : -1; + + return cached > 0; +} + +int block_get_whole_disk(dev_t d, dev_t *ret) { + char *p, *s; + int r; + unsigned n, m; + + assert(ret); + + /* If it has a queue this is good enough for us */ + if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0) + return -ENOMEM; + + r = access(p, F_OK); + free(p); + + if (r >= 0) { + *ret = d; + return 0; + } + + /* If it is a partition find the originating device */ + if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0) + return -ENOMEM; + + r = access(p, F_OK); + free(p); + + if (r < 0) + return -ENOENT; + + /* Get parent dev_t */ + if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0) + return -ENOMEM; + + r = read_one_line_file(p, &s); + free(p); + + if (r < 0) + return r; + + r = sscanf(s, "%u:%u", &m, &n); + free(s); + + if (r != 2) + return -EINVAL; + + /* Only return this if it is really good enough for us. */ + if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0) + return -ENOMEM; + + r = access(p, F_OK); + free(p); + + if (r >= 0) { + *ret = makedev(m, n); + return 0; + } + + return -ENOENT; +} + +int file_is_priv_sticky(const char *p) { + struct stat st; + + assert(p); + + if (lstat(p, &st) < 0) + return -errno; + + return + (st.st_uid == 0 || st.st_uid == getuid()) && + (st.st_mode & S_ISVTX); +} + +static const char *const ioprio_class_table[] = { + [IOPRIO_CLASS_NONE] = "none", + [IOPRIO_CLASS_RT] = "realtime", + [IOPRIO_CLASS_BE] = "best-effort", + [IOPRIO_CLASS_IDLE] = "idle" +}; + +DEFINE_STRING_TABLE_LOOKUP(ioprio_class, int); + +static const char *const sigchld_code_table[] = { + [CLD_EXITED] = "exited", + [CLD_KILLED] = "killed", + [CLD_DUMPED] = "dumped", + [CLD_TRAPPED] = "trapped", + [CLD_STOPPED] = "stopped", + [CLD_CONTINUED] = "continued", +}; + +DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int); + +static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = { + [LOG_FAC(LOG_KERN)] = "kern", + [LOG_FAC(LOG_USER)] = "user", + [LOG_FAC(LOG_MAIL)] = "mail", + [LOG_FAC(LOG_DAEMON)] = "daemon", + [LOG_FAC(LOG_AUTH)] = "auth", + [LOG_FAC(LOG_SYSLOG)] = "syslog", + [LOG_FAC(LOG_LPR)] = "lpr", + [LOG_FAC(LOG_NEWS)] = "news", + [LOG_FAC(LOG_UUCP)] = "uucp", + [LOG_FAC(LOG_CRON)] = "cron", + [LOG_FAC(LOG_AUTHPRIV)] = "authpriv", + [LOG_FAC(LOG_FTP)] = "ftp", + [LOG_FAC(LOG_LOCAL0)] = "local0", + [LOG_FAC(LOG_LOCAL1)] = "local1", + [LOG_FAC(LOG_LOCAL2)] = "local2", + [LOG_FAC(LOG_LOCAL3)] = "local3", + [LOG_FAC(LOG_LOCAL4)] = "local4", + [LOG_FAC(LOG_LOCAL5)] = "local5", + [LOG_FAC(LOG_LOCAL6)] = "local6", + [LOG_FAC(LOG_LOCAL7)] = "local7" +}; + +DEFINE_STRING_TABLE_LOOKUP(log_facility_unshifted, int); + +static const char *const log_level_table[] = { + [LOG_EMERG] = "emerg", + [LOG_ALERT] = "alert", + [LOG_CRIT] = "crit", + [LOG_ERR] = "err", + [LOG_WARNING] = "warning", + [LOG_NOTICE] = "notice", + [LOG_INFO] = "info", + [LOG_DEBUG] = "debug" +}; + +DEFINE_STRING_TABLE_LOOKUP(log_level, int); + +static const char* const sched_policy_table[] = { + [SCHED_OTHER] = "other", + [SCHED_BATCH] = "batch", + [SCHED_IDLE] = "idle", + [SCHED_FIFO] = "fifo", + [SCHED_RR] = "rr" +}; + +DEFINE_STRING_TABLE_LOOKUP(sched_policy, int); + +static const char* const rlimit_table[] = { + [RLIMIT_CPU] = "LimitCPU", + [RLIMIT_FSIZE] = "LimitFSIZE", + [RLIMIT_DATA] = "LimitDATA", + [RLIMIT_STACK] = "LimitSTACK", + [RLIMIT_CORE] = "LimitCORE", + [RLIMIT_RSS] = "LimitRSS", + [RLIMIT_NOFILE] = "LimitNOFILE", + [RLIMIT_AS] = "LimitAS", + [RLIMIT_NPROC] = "LimitNPROC", + [RLIMIT_MEMLOCK] = "LimitMEMLOCK", + [RLIMIT_LOCKS] = "LimitLOCKS", + [RLIMIT_SIGPENDING] = "LimitSIGPENDING", + [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE", + [RLIMIT_NICE] = "LimitNICE", + [RLIMIT_RTPRIO] = "LimitRTPRIO", + [RLIMIT_RTTIME] = "LimitRTTIME" +}; + +DEFINE_STRING_TABLE_LOOKUP(rlimit, int); + +static const char* const ip_tos_table[] = { + [IPTOS_LOWDELAY] = "low-delay", + [IPTOS_THROUGHPUT] = "throughput", + [IPTOS_RELIABILITY] = "reliability", + [IPTOS_LOWCOST] = "low-cost", +}; + +DEFINE_STRING_TABLE_LOOKUP(ip_tos, int); + +static const char *const __signal_table[] = { + [SIGHUP] = "HUP", + [SIGINT] = "INT", + [SIGQUIT] = "QUIT", + [SIGILL] = "ILL", + [SIGTRAP] = "TRAP", + [SIGABRT] = "ABRT", + [SIGBUS] = "BUS", + [SIGFPE] = "FPE", + [SIGKILL] = "KILL", + [SIGUSR1] = "USR1", + [SIGSEGV] = "SEGV", + [SIGUSR2] = "USR2", + [SIGPIPE] = "PIPE", + [SIGALRM] = "ALRM", + [SIGTERM] = "TERM", +#ifdef SIGSTKFLT + [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */ +#endif + [SIGCHLD] = "CHLD", + [SIGCONT] = "CONT", + [SIGSTOP] = "STOP", + [SIGTSTP] = "TSTP", + [SIGTTIN] = "TTIN", + [SIGTTOU] = "TTOU", + [SIGURG] = "URG", + [SIGXCPU] = "XCPU", + [SIGXFSZ] = "XFSZ", + [SIGVTALRM] = "VTALRM", + [SIGPROF] = "PROF", + [SIGWINCH] = "WINCH", + [SIGIO] = "IO", + [SIGPWR] = "PWR", + [SIGSYS] = "SYS" +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int); + +const char *signal_to_string(int signo) { + static __thread char buf[12]; + const char *name; + + name = __signal_to_string(signo); + if (name) + return name; + + if (signo >= SIGRTMIN && signo <= SIGRTMAX) + snprintf(buf, sizeof(buf) - 1, "RTMIN+%d", signo - SIGRTMIN); + else + snprintf(buf, sizeof(buf) - 1, "%d", signo); + char_array_0(buf); + return buf; +} + +int signal_from_string(const char *s) { + int signo; + int offset = 0; + unsigned u; + + signo =__signal_from_string(s); + if (signo > 0) + return signo; + + if (startswith(s, "RTMIN+")) { + s += 6; + offset = SIGRTMIN; + } + if (safe_atou(s, &u) >= 0) { + signo = (int) u + offset; + if (signo > 0 && signo < _NSIG) + return signo; + } + return -1; +} + +bool kexec_loaded(void) { + bool loaded = false; + char *s; + + if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) { + if (s[0] == '1') + loaded = true; + free(s); + } + return loaded; +} + +int strdup_or_null(const char *a, char **b) { + char *c; + + assert(b); + + if (!a) { + *b = NULL; + return 0; + } + + c = strdup(a); + if (!c) + return -ENOMEM; + + *b = c; + return 0; +} + +int prot_from_flags(int flags) { + + switch (flags & O_ACCMODE) { + + case O_RDONLY: + return PROT_READ; + + case O_WRONLY: + return PROT_WRITE; + + case O_RDWR: + return PROT_READ|PROT_WRITE; + + default: + return -EINVAL; + } +} + +unsigned long cap_last_cap(void) { + static __thread unsigned long saved; + static __thread bool valid = false; + unsigned long p; + + if (valid) + return saved; + + p = (unsigned long) CAP_LAST_CAP; + + if (prctl(PR_CAPBSET_READ, p) < 0) { + + /* Hmm, look downwards, until we find one that + * works */ + for (p--; p > 0; p --) + if (prctl(PR_CAPBSET_READ, p) >= 0) + break; + + } else { + + /* Hmm, look upwards, until we find one that doesn't + * work */ + for (;; p++) + if (prctl(PR_CAPBSET_READ, p+1) < 0) + break; + } + + saved = p; + valid = true; + + return p; +} + +char *format_bytes(char *buf, size_t l, off_t t) { + unsigned i; + + static const struct { + const char *suffix; + off_t factor; + } table[] = { + { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL }, + { "T", 1024ULL*1024ULL*1024ULL*1024ULL }, + { "G", 1024ULL*1024ULL*1024ULL }, + { "M", 1024ULL*1024ULL }, + { "K", 1024ULL }, + }; + + for (i = 0; i < ELEMENTSOF(table); i++) { + + if (t >= table[i].factor) { + snprintf(buf, l, + "%llu.%llu%s", + (unsigned long long) (t / table[i].factor), + (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL), + table[i].suffix); + + goto finish; + } + } + + snprintf(buf, l, "%lluB", (unsigned long long) t); + +finish: + buf[l-1] = 0; + return buf; + +} + +void* memdup(const void *p, size_t l) { + void *r; + + assert(p); + + r = malloc(l); + if (!r) + return NULL; + + memcpy(r, p, l); + return r; +} + +int fd_inc_sndbuf(int fd, size_t n) { + int r, value; + socklen_t l = sizeof(value); + + r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l); + if (r >= 0 && + l == sizeof(value) && + (size_t) value >= n*2) + return 0; + + value = (int) n; + r = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)); + if (r < 0) + return -errno; + + return 1; +} + +int fd_inc_rcvbuf(int fd, size_t n) { + int r, value; + socklen_t l = sizeof(value); + + r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l); + if (r >= 0 && + l == sizeof(value) && + (size_t) value >= n*2) + return 0; + + value = (int) n; + r = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)); + if (r < 0) + return -errno; + + return 1; +} diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..890a3b5 --- /dev/null +++ b/src/util.h @@ -0,0 +1,542 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooutilhfoo +#define fooutilhfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" + +typedef uint64_t usec_t; + +typedef struct dual_timestamp { + usec_t realtime; + usec_t monotonic; +} dual_timestamp; + +#define MSEC_PER_SEC 1000ULL +#define USEC_PER_SEC 1000000ULL +#define USEC_PER_MSEC 1000ULL +#define NSEC_PER_SEC 1000000000ULL +#define NSEC_PER_MSEC 1000000ULL +#define NSEC_PER_USEC 1000ULL + +#define USEC_PER_MINUTE (60ULL*USEC_PER_SEC) +#define USEC_PER_HOUR (60ULL*USEC_PER_MINUTE) +#define USEC_PER_DAY (24ULL*USEC_PER_HOUR) +#define USEC_PER_WEEK (7ULL*USEC_PER_DAY) +#define USEC_PER_MONTH (2629800ULL*USEC_PER_SEC) +#define USEC_PER_YEAR (31557600ULL*USEC_PER_SEC) + +/* What is interpreted as whitespace? */ +#define WHITESPACE " \t\n\r" +#define NEWLINE "\n\r" +#define QUOTES "\"\'" +#define COMMENTS "#;\n" + +#define FORMAT_TIMESTAMP_MAX 64 +#define FORMAT_TIMESTAMP_PRETTY_MAX 256 +#define FORMAT_TIMESPAN_MAX 64 +#define FORMAT_BYTES_MAX 8 + +#define ANSI_HIGHLIGHT_ON "\x1B[1;39m" +#define ANSI_HIGHLIGHT_RED_ON "\x1B[1;31m" +#define ANSI_HIGHLIGHT_GREEN_ON "\x1B[1;32m" +#define ANSI_HIGHLIGHT_OFF "\x1B[0m" + +usec_t now(clockid_t clock); + +dual_timestamp* dual_timestamp_get(dual_timestamp *ts); +dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u); + +#define dual_timestamp_is_set(ts) ((ts)->realtime > 0) + +usec_t timespec_load(const struct timespec *ts); +struct timespec *timespec_store(struct timespec *ts, usec_t u); + +usec_t timeval_load(const struct timeval *tv); +struct timeval *timeval_store(struct timeval *tv, usec_t u); + +size_t page_size(void); +#define PAGE_ALIGN(l) ALIGN_TO((l), page_size()) + +#define streq(a,b) (strcmp((a),(b)) == 0) +#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) + +bool streq_ptr(const char *a, const char *b); + +#define new(t, n) ((t*) malloc(sizeof(t)*(n))) + +#define new0(t, n) ((t*) calloc((n), sizeof(t))) + +#define malloc0(n) (calloc((n), 1)) + +static inline const char* yes_no(bool b) { + return b ? "yes" : "no"; +} + +static inline const char* strempty(const char *s) { + return s ? s : ""; +} + +static inline const char* strnull(const char *s) { + return s ? s : "(null)"; +} + +static inline const char *strna(const char *s) { + return s ? s : "n/a"; +} + +static inline bool is_path_absolute(const char *p) { + return *p == '/'; +} + +static inline bool isempty(const char *p) { + return !p || !p[0]; +} + +bool endswith(const char *s, const char *postfix); +bool startswith(const char *s, const char *prefix); +bool startswith_no_case(const char *s, const char *prefix); + +bool first_word(const char *s, const char *word); + +int close_nointr(int fd); +void close_nointr_nofail(int fd); +void close_many(const int fds[], unsigned n_fd); + +int parse_boolean(const char *v); +int parse_usec(const char *t, usec_t *usec); +int parse_bytes(const char *t, off_t *bytes); +int parse_pid(const char *s, pid_t* ret_pid); +int parse_uid(const char *s, uid_t* ret_uid); +#define parse_gid(s, ret_uid) parse_uid(s, ret_uid) + +int safe_atou(const char *s, unsigned *ret_u); +int safe_atoi(const char *s, int *ret_i); + +int safe_atollu(const char *s, unsigned long long *ret_u); +int safe_atolli(const char *s, long long int *ret_i); + +#if __WORDSIZE == 32 +static inline int safe_atolu(const char *s, unsigned long *ret_u) { + assert_cc(sizeof(unsigned long) == sizeof(unsigned)); + return safe_atou(s, (unsigned*) ret_u); +} +static inline int safe_atoli(const char *s, long int *ret_u) { + assert_cc(sizeof(long int) == sizeof(int)); + return safe_atoi(s, (int*) ret_u); +} +#else +static inline int safe_atolu(const char *s, unsigned long *ret_u) { + assert_cc(sizeof(unsigned long) == sizeof(unsigned long long)); + return safe_atollu(s, (unsigned long long*) ret_u); +} +static inline int safe_atoli(const char *s, long int *ret_u) { + assert_cc(sizeof(long int) == sizeof(long long int)); + return safe_atolli(s, (long long int*) ret_u); +} +#endif + +static inline int safe_atou32(const char *s, uint32_t *ret_u) { + assert_cc(sizeof(uint32_t) == sizeof(unsigned)); + return safe_atou(s, (unsigned*) ret_u); +} + +static inline int safe_atoi32(const char *s, int32_t *ret_i) { + assert_cc(sizeof(int32_t) == sizeof(int)); + return safe_atoi(s, (int*) ret_i); +} + +static inline int safe_atou64(const char *s, uint64_t *ret_u) { + assert_cc(sizeof(uint64_t) == sizeof(unsigned long long)); + return safe_atollu(s, (unsigned long long*) ret_u); +} + +static inline int safe_atoi64(const char *s, int64_t *ret_i) { + assert_cc(sizeof(int64_t) == sizeof(long long int)); + return safe_atolli(s, (long long int*) ret_i); +} + +char *split(const char *c, size_t *l, const char *separator, char **state); +char *split_quoted(const char *c, size_t *l, char **state); + +#define FOREACH_WORD(word, length, s, state) \ + for ((state) = NULL, (word) = split((s), &(length), WHITESPACE, &(state)); (word); (word) = split((s), &(length), WHITESPACE, &(state))) + +#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \ + for ((state) = NULL, (word) = split((s), &(length), (separator), &(state)); (word); (word) = split((s), &(length), (separator), &(state))) + +#define FOREACH_WORD_QUOTED(word, length, s, state) \ + for ((state) = NULL, (word) = split_quoted((s), &(length), &(state)); (word); (word) = split_quoted((s), &(length), &(state))) + +char **split_path_and_make_absolute(const char *p); + +pid_t get_parent_of_pid(pid_t pid, pid_t *ppid); +int get_starttime_of_pid(pid_t pid, unsigned long long *st); + +int write_one_line_file(const char *fn, const char *line); +int write_one_line_file_atomic(const char *fn, const char *line); +int read_one_line_file(const char *fn, char **line); +int read_full_file(const char *fn, char **contents, size_t *size); + +int parse_env_file(const char *fname, const char *separator, ...) _sentinel_; +int load_env_file(const char *fname, char ***l); +int write_env_file(const char *fname, char **l); + +char *strappend(const char *s, const char *suffix); +char *strnappend(const char *s, const char *suffix, size_t length); + +char *replace_env(const char *format, char **env); +char **replace_env_argv(char **argv, char **env); + +int readlink_malloc(const char *p, char **r); +int readlink_and_make_absolute(const char *p, char **r); +int readlink_and_canonicalize(const char *p, char **r); + +char *file_name_from_path(const char *p); +bool is_path(const char *p); + +bool path_is_absolute(const char *p); +char *path_make_absolute(const char *p, const char *prefix); +char *path_make_absolute_cwd(const char *p); + +char **strv_path_make_absolute_cwd(char **l); +char **strv_path_canonicalize(char **l); +char **strv_path_remove_empty(char **l); + +int reset_all_signal_handlers(void); + +char *strstrip(char *s); +char *delete_chars(char *s, const char *bad); +char *truncate_nl(char *s); + +char *file_in_same_dir(const char *path, const char *filename); +int safe_mkdir(const char *path, mode_t mode, uid_t uid, gid_t gid); +int mkdir_parents(const char *path, mode_t mode); +int mkdir_p(const char *path, mode_t mode); + +int parent_of_path(const char *path, char **parent); + +int rmdir_parents(const char *path, const char *stop); + +int get_process_comm(pid_t pid, char **name); +int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line); +int get_process_exe(pid_t pid, char **name); +int get_process_uid(pid_t pid, uid_t *uid); + +char hexchar(int x); +int unhexchar(char c); +char octchar(int x); +int unoctchar(char c); +char decchar(int x); +int undecchar(char c); + +char *cescape(const char *s); +char *cunescape(const char *s); +char *cunescape_length(const char *s, size_t length); + +char *xescape(const char *s, const char *bad); + +char *bus_path_escape(const char *s); +char *bus_path_unescape(const char *s); + +char *path_kill_slashes(char *path); + +bool path_startswith(const char *path, const char *prefix); +bool path_equal(const char *a, const char *b); + +char *ascii_strlower(char *path); + +bool dirent_is_file(const struct dirent *de); +bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix); + +bool ignore_file(const char *filename); + +bool chars_intersect(const char *a, const char *b); + +char *format_timestamp(char *buf, size_t l, usec_t t); +char *format_timestamp_pretty(char *buf, size_t l, usec_t t); +char *format_timespan(char *buf, size_t l, usec_t t); + +int make_stdio(int fd); +int make_null_stdio(void); + +unsigned long long random_ull(void); + +#define __DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \ + scope const char *name##_to_string(type i) { \ + if (i < 0 || i >= (type) ELEMENTSOF(name##_table)) \ + return NULL; \ + return name##_table[i]; \ + } \ + scope type name##_from_string(const char *s) { \ + type i; \ + unsigned u = 0; \ + assert(s); \ + for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \ + if (name##_table[i] && \ + streq(name##_table[i], s)) \ + return i; \ + if (safe_atou(s, &u) >= 0 && \ + u < ELEMENTSOF(name##_table)) \ + return (type) u; \ + return (type) -1; \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + +#define DEFINE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,) +#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,static) + +int fd_nonblock(int fd, bool nonblock); +int fd_cloexec(int fd, bool cloexec); + +int close_all_fds(const int except[], unsigned n_except); + +bool fstype_is_network(const char *fstype); + +int chvt(int vt); + +int read_one_char(FILE *f, char *ret, usec_t timeout, bool *need_nl); +int ask(char *ret, const char *replies, const char *text, ...); + +int reset_terminal_fd(int fd, bool switch_to_text); +int reset_terminal(const char *name); + +int open_terminal(const char *name, int mode); +int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocstty_eperm); +int release_terminal(void); + +int flush_fd(int fd); + +int ignore_signals(int sig, ...); +int default_signals(int sig, ...); +int sigaction_many(const struct sigaction *sa, ...); + +int close_pipe(int p[]); +int fopen_temporary(const char *path, FILE **_f, char **_temp_path); + +ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll); +ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll); + +int path_is_mount_point(const char *path, bool allow_symlink); + +bool is_device_path(const char *path); + +int dir_is_empty(const char *path); + +void rename_process(const char name[8]); + +void sigset_add_many(sigset_t *ss, ...); + +char* gethostname_malloc(void); +char* getlogname_malloc(void); + +int getttyname_malloc(int fd, char **r); +int getttyname_harder(int fd, char **r); + +int get_ctty_devnr(pid_t pid, dev_t *d); +int get_ctty(pid_t, dev_t *_devnr, char **r); + +int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid); +int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid); + +int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky); + +int pipe_eof(int fd); + +cpu_set_t* cpu_set_malloc(unsigned *ncpus); + +void status_vprintf(const char *status, bool ellipse, const char *format, va_list ap); +void status_printf(const char *status, bool ellipse, const char *format, ...); +void status_welcome(void); + +int fd_columns(int fd); +unsigned columns(void); + +int fd_lines(int fd); +unsigned lines(void); + +int running_in_chroot(void); + +char *ellipsize(const char *s, size_t length, unsigned percent); +char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent); + +int touch(const char *path); + +char *unquote(const char *s, const char *quotes); +char *normalize_env_assignment(const char *s); + +int wait_for_terminate(pid_t pid, siginfo_t *status); +int wait_for_terminate_and_warn(const char *name, pid_t pid); + +_noreturn_ void freeze(void); + +bool null_or_empty(struct stat *st); +int null_or_empty_path(const char *fn); + +DIR *xopendirat(int dirfd, const char *name, int flags); + +void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t); +void dual_timestamp_deserialize(const char *value, dual_timestamp *t); + +char *fstab_node_to_udev_node(const char *p); + +void filter_environ(const char *prefix); + +bool tty_is_vc(const char *tty); +bool tty_is_vc_resolve(const char *tty); +int vtnr_from_tty(const char *tty); +const char *default_term_for_tty(const char *tty); + +void execute_directory(const char *directory, DIR *_d, char *argv[]); + +int kill_and_sigcont(pid_t pid, int sig); + +bool nulstr_contains(const char*nulstr, const char *needle); + +bool plymouth_running(void); + +void parse_syslog_priority(char **p, int *priority); +void skip_syslog_pid(char **buf); +void skip_syslog_date(char **buf); + +int have_effective_cap(int value); + +bool hostname_is_valid(const char *s); +char* hostname_cleanup(char *s); + +char* strshorten(char *s, size_t l); + +int terminal_vhangup_fd(int fd); +int terminal_vhangup(const char *name); + +int vt_disallocate(const char *name); + +int copy_file(const char *from, const char *to); +int symlink_or_copy(const char *from, const char *to); +int symlink_or_copy_atomic(const char *from, const char *to); + +int fchmod_umask(int fd, mode_t mode); + +int conf_files_list(char ***strv, const char *suffix, const char *dir, ...); + +int hwclock_is_localtime(void); +int hwclock_apply_localtime_delta(int *min); +int hwclock_reset_localtime_delta(void); +int hwclock_get_time(struct tm *tm); +int hwclock_set_time(const struct tm *tm); + +int audit_session_from_pid(pid_t pid, uint32_t *id); +int audit_loginuid_from_pid(pid_t pid, uid_t *uid); + +bool display_is_local(const char *display); +int socket_from_display(const char *display, char **path); + +int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home); +int get_group_creds(const char **groupname, gid_t *gid); + +int glob_exists(const char *path); + +int dirent_ensure_type(DIR *d, struct dirent *de); + +int in_search_path(const char *path, char **search); +int get_files_in_directory(const char *path, char ***list); + +char *join(const char *x, ...) _sentinel_; + +bool is_main_thread(void); + +bool in_charset(const char *s, const char* charset); + +int block_get_whole_disk(dev_t d, dev_t *ret); + +int file_is_priv_sticky(const char *p); + +int strdup_or_null(const char *a, char **b); + +#define NULSTR_FOREACH(i, l) \ + for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) + +#define NULSTR_FOREACH_PAIR(i, j, l) \ + for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i)) + +const char *ioprio_class_to_string(int i); +int ioprio_class_from_string(const char *s); + +const char *sigchld_code_to_string(int i); +int sigchld_code_from_string(const char *s); + +const char *log_facility_unshifted_to_string(int i); +int log_facility_unshifted_from_string(const char *s); + +const char *log_level_to_string(int i); +int log_level_from_string(const char *s); + +const char *sched_policy_to_string(int i); +int sched_policy_from_string(const char *s); + +const char *rlimit_to_string(int i); +int rlimit_from_string(const char *s); + +const char *ip_tos_to_string(int i); +int ip_tos_from_string(const char *s); + +const char *signal_to_string(int i); +int signal_from_string(const char *s); + +int signal_from_string_try_harder(const char *s); + +extern int saved_argc; +extern char **saved_argv; + +bool kexec_loaded(void); + +int prot_from_flags(int flags); + +unsigned long cap_last_cap(void); + +char *format_bytes(char *buf, size_t l, off_t t); + +int fd_wait_for_event(int fd, int event, usec_t timeout); + +void* memdup(const void *p, size_t l); + +int rtc_open(int flags); + +int is_kernel_thread(pid_t pid); + +int fd_inc_sndbuf(int fd, size_t n); +int fd_inc_rcvbuf(int fd, size_t n); + +#endif diff --git a/src/utmp-wtmp.c b/src/utmp-wtmp.c new file mode 100644 index 0000000..217ae1e --- /dev/null +++ b/src/utmp-wtmp.c @@ -0,0 +1,430 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "macro.h" +#include "utmp-wtmp.h" + +int utmp_get_runlevel(int *runlevel, int *previous) { + struct utmpx lookup, *found; + int r; + const char *e; + + assert(runlevel); + + /* If these values are set in the environment this takes + * precedence. Presumably, sysvinit does this to work around a + * race condition that would otherwise exist where we'd always + * go to disk and hence might read runlevel data that might be + * very new and does not apply to the current script being + * executed. */ + + if ((e = getenv("RUNLEVEL")) && e[0] > 0) { + *runlevel = e[0]; + + if (previous) { + /* $PREVLEVEL seems to be an Upstart thing */ + + if ((e = getenv("PREVLEVEL")) && e[0] > 0) + *previous = e[0]; + else + *previous = 0; + } + + return 0; + } + + if (utmpxname(_PATH_UTMPX) < 0) + return -errno; + + setutxent(); + + zero(lookup); + lookup.ut_type = RUN_LVL; + + if (!(found = getutxid(&lookup))) + r = -errno; + else { + int a, b; + + a = found->ut_pid & 0xFF; + b = (found->ut_pid >> 8) & 0xFF; + + if (a < 0 || b < 0) + r = -EIO; + else { + *runlevel = a; + + if (previous) + *previous = b; + r = 0; + } + } + + endutxent(); + + return r; +} + +static void init_timestamp(struct utmpx *store, usec_t t) { + assert(store); + + zero(*store); + + if (t <= 0) + t = now(CLOCK_REALTIME); + + store->ut_tv.tv_sec = t / USEC_PER_SEC; + store->ut_tv.tv_usec = t % USEC_PER_SEC; +} + +static void init_entry(struct utmpx *store, usec_t t) { + struct utsname uts; + + assert(store); + + init_timestamp(store, t); + + zero(uts); + + if (uname(&uts) >= 0) + strncpy(store->ut_host, uts.release, sizeof(store->ut_host)); + + strncpy(store->ut_line, "~", sizeof(store->ut_line)); /* or ~~ ? */ + strncpy(store->ut_id, "~~", sizeof(store->ut_id)); +} + +static int write_entry_utmp(const struct utmpx *store) { + int r; + + assert(store); + + /* utmp is similar to wtmp, but there is only one entry for + * each entry type resp. user; i.e. basically a key/value + * table. */ + + if (utmpxname(_PATH_UTMPX) < 0) + return -errno; + + setutxent(); + + if (!pututxline(store)) + r = -errno; + else + r = 0; + + endutxent(); + + return r; +} + +static int write_entry_wtmp(const struct utmpx *store) { + assert(store); + + /* wtmp is a simple append-only file where each entry is + simply appended to * the end; i.e. basically a log. */ + + errno = 0; + updwtmpx(_PATH_WTMPX, store); + return -errno; +} + +static int write_utmp_wtmp(const struct utmpx *store_utmp, const struct utmpx *store_wtmp) { + int r, s; + + r = write_entry_utmp(store_utmp); + s = write_entry_wtmp(store_wtmp); + + if (r >= 0) + r = s; + + /* If utmp/wtmp have been disabled, that's a good thing, hence + * ignore the errors */ + if (r == -ENOENT) + r = 0; + + return r; +} + +static int write_entry_both(const struct utmpx *store) { + return write_utmp_wtmp(store, store); +} + +int utmp_put_shutdown(void) { + struct utmpx store; + + init_entry(&store, 0); + + store.ut_type = RUN_LVL; + strncpy(store.ut_user, "shutdown", sizeof(store.ut_user)); + + return write_entry_both(&store); +} + +int utmp_put_reboot(usec_t t) { + struct utmpx store; + + init_entry(&store, t); + + store.ut_type = BOOT_TIME; + strncpy(store.ut_user, "reboot", sizeof(store.ut_user)); + + return write_entry_both(&store); +} + +static const char *sanitize_id(const char *id) { + size_t l; + + assert(id); + l = strlen(id); + + if (l <= sizeof(((struct utmpx*) NULL)->ut_id)) + return id; + + return id + l - sizeof(((struct utmpx*) NULL)->ut_id); +} + +int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line) { + struct utmpx store; + + assert(id); + + init_timestamp(&store, 0); + + store.ut_type = INIT_PROCESS; + store.ut_pid = pid; + store.ut_session = sid; + + strncpy(store.ut_id, sanitize_id(id), sizeof(store.ut_id)); + + if (line) + strncpy(store.ut_line, file_name_from_path(line), sizeof(store.ut_line)); + + return write_entry_both(&store); +} + +int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) { + struct utmpx lookup, store, store_wtmp, *found; + + assert(id); + + setutxent(); + + zero(lookup); + lookup.ut_type = INIT_PROCESS; /* looks for DEAD_PROCESS, LOGIN_PROCESS, USER_PROCESS, too */ + strncpy(lookup.ut_id, sanitize_id(id), sizeof(lookup.ut_id)); + + if (!(found = getutxid(&lookup))) + return 0; + + if (found->ut_pid != pid) + return 0; + + memcpy(&store, found, sizeof(store)); + store.ut_type = DEAD_PROCESS; + store.ut_exit.e_termination = code; + store.ut_exit.e_exit = status; + + zero(store.ut_user); + zero(store.ut_host); + zero(store.ut_tv); + + memcpy(&store_wtmp, &store, sizeof(store_wtmp)); + /* wtmp wants the current time */ + init_timestamp(&store_wtmp, 0); + + return write_utmp_wtmp(&store, &store_wtmp); +} + + +int utmp_put_runlevel(int runlevel, int previous) { + struct utmpx store; + int r; + + assert(runlevel > 0); + + if (previous <= 0) { + /* Find the old runlevel automatically */ + + if ((r = utmp_get_runlevel(&previous, NULL)) < 0) { + if (r != -ESRCH) + return r; + + previous = 0; + } + } + + if (previous == runlevel) + return 0; + + init_entry(&store, 0); + + store.ut_type = RUN_LVL; + store.ut_pid = (runlevel & 0xFF) | ((previous & 0xFF) << 8); + strncpy(store.ut_user, "runlevel", sizeof(store.ut_user)); + + return write_entry_both(&store); +} + +#define TIMEOUT_MSEC 50 + +static int write_to_terminal(const char *tty, const char *message) { + int fd, r; + const char *p; + size_t left; + usec_t end; + + assert(tty); + assert(message); + + if ((fd = open(tty, O_WRONLY|O_NDELAY|O_NOCTTY|O_CLOEXEC)) < 0) + return -errno; + + if (!isatty(fd)) { + r = -errno; + goto finish; + } + + p = message; + left = strlen(message); + + end = now(CLOCK_MONOTONIC) + TIMEOUT_MSEC*USEC_PER_MSEC; + + while (left > 0) { + ssize_t n; + struct pollfd pollfd; + usec_t t; + int k; + + t = now(CLOCK_MONOTONIC); + + if (t >= end) { + r = -ETIME; + goto finish; + } + + zero(pollfd); + pollfd.fd = fd; + pollfd.events = POLLOUT; + + if ((k = poll(&pollfd, 1, (end - t) / USEC_PER_MSEC)) < 0) + return -errno; + + if (k <= 0) { + r = -ETIME; + goto finish; + } + + if ((n = write(fd, p, left)) < 0) { + + if (errno == EAGAIN) + continue; + + r = -errno; + goto finish; + } + + assert((size_t) n <= left); + + p += n; + left -= n; + } + + r = 0; + +finish: + close_nointr_nofail(fd); + + return r; +} + +int utmp_wall(const char *message, bool (*match_tty)(const char *tty)) { + struct utmpx *u; + char date[FORMAT_TIMESTAMP_MAX]; + char *text = NULL, *hn = NULL, *un = NULL, *tty = NULL; + int r; + + if (!(hn = gethostname_malloc()) || + !(un = getlogname_malloc())) { + r = -ENOMEM; + goto finish; + } + + getttyname_harder(STDIN_FILENO, &tty); + + if (asprintf(&text, + "\a\r\n" + "Broadcast message from %s@%s%s%s (%s):\r\n\r\n" + "%s\r\n\r\n", + un, hn, + tty ? " on " : "", strempty(tty), + format_timestamp(date, sizeof(date), now(CLOCK_REALTIME)), + message) < 0) { + r = -ENOMEM; + goto finish; + } + + setutxent(); + + r = 0; + + while ((u = getutxent())) { + int q; + const char *path; + char *buf = NULL; + + if (u->ut_type != USER_PROCESS || u->ut_user[0] == 0) + continue; + + if (path_startswith(u->ut_line, "/dev/")) + path = u->ut_line; + else { + if (asprintf(&buf, "/dev/%s", u->ut_line) < 0) { + r = -ENOMEM; + goto finish; + } + + path = buf; + } + + if (!match_tty || match_tty(path)) + if ((q = write_to_terminal(path, text)) < 0) + r = q; + + free(buf); + } + +finish: + free(hn); + free(un); + free(tty); + free(text); + + return r; +} diff --git a/src/utmp-wtmp.h b/src/utmp-wtmp.h new file mode 100644 index 0000000..a5998eb --- /dev/null +++ b/src/utmp-wtmp.h @@ -0,0 +1,38 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooutmpwtmphfoo +#define fooutmpwtmphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include "util.h" + +int utmp_get_runlevel(int *runlevel, int *previous); + +int utmp_put_shutdown(void); +int utmp_put_reboot(usec_t timestamp); +int utmp_put_runlevel(int runlevel, int previous); + +int utmp_put_dead_process(const char *id, pid_t pid, int code, int status); +int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line); + +int utmp_wall(const char *message, bool (*match_tty)(const char *tty)); + +#endif diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c new file mode 100644 index 0000000..9196789 --- /dev/null +++ b/src/vconsole/vconsole-setup.c @@ -0,0 +1,459 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Kay Sievers + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "log.h" +#include "macro.h" +#include "virt.h" + +static bool is_vconsole(int fd) { + unsigned char data[1]; + + data[0] = TIOCL_GETFGCONSOLE; + return ioctl(fd, TIOCLINUX, data) >= 0; +} + +static bool is_locale_utf8(void) { + const char *set; + + if (!setlocale(LC_ALL, "")) + return true; + + set = nl_langinfo(CODESET); + if (!set) + return true; + + return streq(set, "UTF-8"); +} + +static int disable_utf8(int fd) { + int r = 0, k; + + if (ioctl(fd, KDSKBMODE, K_XLATE) < 0) + r = -errno; + + if (loop_write(fd, "\033%@", 3, false) < 0) + r = -errno; + + if ((k = write_one_line_file("/sys/module/vt/parameters/default_utf8", "0")) < 0) + r = k; + + if (r < 0) + log_warning("Failed to disable UTF-8: %s", strerror(errno)); + + return r; +} + +static int load_keymap(const char *vc, const char *map, const char *map_toggle, bool utf8, pid_t *_pid) { + const char *args[8]; + int i = 0; + pid_t pid; + + if (isempty(map)) { + /* An empty map means kernel map */ + *_pid = 0; + return 0; + } + + args[i++] = KBD_LOADKEYS; + args[i++] = "-q"; + args[i++] = "-C"; + args[i++] = vc; + if (utf8) + args[i++] = "-u"; + args[i++] = map; + if (map_toggle) + args[i++] = map_toggle; + args[i++] = NULL; + + if ((pid = fork()) < 0) { + log_error("Failed to fork: %m"); + return -errno; + } else if (pid == 0) { + execv(args[0], (char **) args); + _exit(EXIT_FAILURE); + } + + *_pid = pid; + return 0; +} + +static int load_font(const char *vc, const char *font, const char *map, const char *unimap, pid_t *_pid) { + const char *args[9]; + int i = 0; + pid_t pid; + + if (isempty(font)) { + /* An empty font means kernel font */ + *_pid = 0; + return 0; + } + + args[i++] = KBD_SETFONT; + args[i++] = "-C"; + args[i++] = vc; + args[i++] = font; + if (map) { + args[i++] = "-m"; + args[i++] = map; + } + if (unimap) { + args[i++] = "-u"; + args[i++] = unimap; + } + args[i++] = NULL; + + if ((pid = fork()) < 0) { + log_error("Failed to fork: %m"); + return -errno; + } else if (pid == 0) { + execv(args[0], (char **) args); + _exit(EXIT_FAILURE); + } + + *_pid = pid; + return 0; +} + +int main(int argc, char **argv) { + const char *vc; + char *vc_keymap = NULL; + char *vc_keymap_toggle = NULL; + char *vc_font = NULL; + char *vc_font_map = NULL; + char *vc_font_unimap = NULL; +#ifdef TARGET_GENTOO + char *vc_unicode = NULL; +#endif +#if defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA) + char *vc_keytable = NULL; +#endif + int fd = -1; + bool utf8; + int r = EXIT_FAILURE; + pid_t font_pid = 0, keymap_pid = 0; + + log_set_target(LOG_TARGET_AUTO); + log_parse_environment(); + log_open(); + + umask(0022); + + if (argv[1]) + vc = argv[1]; + else + vc = "/dev/tty0"; + + if ((fd = open_terminal(vc, O_RDWR|O_CLOEXEC)) < 0) { + log_error("Failed to open %s: %m", vc); + goto finish; + } + + if (!is_vconsole(fd)) { + log_error("Device %s is not a virtual console.", vc); + goto finish; + } + + utf8 = is_locale_utf8(); + + vc_keymap = strdup("us"); + vc_font = strdup(DEFAULT_FONT); + + if (!vc_keymap || !vc_font) { + log_error("Failed to allocate strings."); + goto finish; + } + + r = 0; + + if (detect_container(NULL) <= 0) + if ((r = parse_env_file("/proc/cmdline", WHITESPACE, + "vconsole.keymap", &vc_keymap, + "vconsole.keymap.toggle", &vc_keymap_toggle, + "vconsole.font", &vc_font, + "vconsole.font.map", &vc_font_map, + "vconsole.font.unimap", &vc_font_unimap, + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /proc/cmdline: %s", strerror(-r)); + } + + /* Hmm, nothing set on the kernel cmd line? Then let's + * try /etc/vconsole.conf */ + if (r <= 0 && + (r = parse_env_file("/etc/vconsole.conf", NEWLINE, + "KEYMAP", &vc_keymap, + "KEYMAP_TOGGLE", &vc_keymap_toggle, + "FONT", &vc_font, + "FONT_MAP", &vc_font_map, + "FONT_UNIMAP", &vc_font_unimap, + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/vconsole.conf: %s", strerror(-r)); + } + + if (r <= 0) { +#if defined(TARGET_FEDORA) || defined(TARGET_MEEGO) + if ((r = parse_env_file("/etc/sysconfig/i18n", NEWLINE, + "SYSFONT", &vc_font, + "SYSFONTACM", &vc_font_map, + "UNIMAP", &vc_font_unimap, + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r)); + } + + if ((r = parse_env_file("/etc/sysconfig/keyboard", NEWLINE, + "KEYTABLE", &vc_keymap, + "KEYMAP", &vc_keymap, + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r)); + } + + if (access("/etc/sysconfig/console/default.kmap", F_OK) >= 0) { + char *t; + + if (!(t = strdup("/etc/sysconfig/console/default.kmap"))) { + log_error("Out of memory."); + goto finish; + } + + free(vc_keymap); + vc_keymap = t; + } + +#elif defined(TARGET_SUSE) + if ((r = parse_env_file("/etc/sysconfig/keyboard", NEWLINE, + "KEYTABLE", &vc_keymap, + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/keyboard: %s", strerror(-r)); + } + + if ((r = parse_env_file("/etc/sysconfig/console", NEWLINE, + "CONSOLE_FONT", &vc_font, + "CONSOLE_SCREENMAP", &vc_font_map, + "CONSOLE_UNICODEMAP", &vc_font_unimap, + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/console: %s", strerror(-r)); + } + +#elif defined(TARGET_ARCH) + if ((r = parse_env_file("/etc/rc.conf", NEWLINE, + "KEYMAP", &vc_keymap, + "CONSOLEFONT", &vc_font, + "CONSOLEMAP", &vc_font_map, + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/rc.conf: %s", strerror(-r)); + } + +#elif defined(TARGET_FRUGALWARE) + if ((r = parse_env_file("/etc/sysconfig/keymap", NEWLINE, + "keymap", &vc_keymap, + NULL)) < 0) { + if (r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/keymap: %s", strerror(-r)); + } + if ((r = parse_env_file("/etc/sysconfig/font", NEWLINE, + "font", &vc_font, + NULL)) < 0) { + if (r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/font: %s", strerror(-r)); + } + +#elif defined(TARGET_ALTLINUX) + if ((r = parse_env_file("/etc/sysconfig/keyboard", NEWLINE, + "KEYTABLE", &vc_keymap, + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/keyboard: %s", strerror(-r)); + } + + if ((r = parse_env_file("/etc/sysconfig/consolefont", NEWLINE, + "SYSFONT", &vc_font, + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/console: %s", strerror(-r)); + } + +#elif defined(TARGET_GENTOO) + if ((r = parse_env_file("/etc/rc.conf", NEWLINE, + "unicode", &vc_unicode, + NULL)) < 0) { + if (r != -ENOENT) + log_warning("Failed to read /etc/rc.conf: %s", strerror(-r)); + } + + if (vc_unicode) { + int rc_unicode; + + if ((rc_unicode = parse_boolean(vc_unicode)) < 0) + log_error("Unknown value for /etc/rc.conf unicode=%s", vc_unicode); + else { + if (rc_unicode && !utf8) + log_warning("/etc/rc.conf wants unicode, but current locale is not UTF-8 capable!"); + else if (!rc_unicode && utf8) { + log_debug("/etc/rc.conf does not want unicode, leave it on in kernel but does not apply to vconsole."); + utf8 = false; + } + } + } + + /* /etc/conf.d/consolefont comments and gentoo + * documentation mention uppercase, but the actual + * contents are lowercase. the existing + * /etc/init.d/consolefont tries both + */ + if ((r = parse_env_file("/etc/conf.d/consolefont", NEWLINE, + "CONSOLEFONT", &vc_font, + "consolefont", &vc_font, + "consoletranslation", &vc_font_map, + "CONSOLETRANSLATION", &vc_font_map, + "unicodemap", &vc_font_unimap, + "UNICODEMAP", &vc_font_unimap, + NULL)) < 0) { + if (r != -ENOENT) + log_warning("Failed to read /etc/conf.d/consolefont: %s", strerror(-r)); + } + + if ((r = parse_env_file("/etc/conf.d/keymaps", NEWLINE, + "keymap", &vc_keymap, + "KEYMAP", &vc_keymap, + NULL)) < 0) { + if (r != -ENOENT) + log_warning("Failed to read /etc/conf.d/keymaps: %s", strerror(-r)); + } + +#elif defined(TARGET_MANDRIVA) || defined (TARGET_MAGEIA) + + if ((r = parse_env_file("/etc/sysconfig/i18n", NEWLINE, + "SYSFONT", &vc_font, + "SYSFONTACM", &vc_font_map, + "UNIMAP", &vc_font_unimap, + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r)); + } + + if ((r = parse_env_file("/etc/sysconfig/keyboard", NEWLINE, + "KEYTABLE", &vc_keytable, + "KEYMAP", &vc_keymap, + "UNIKEYTABLE", &vc_keymap, + "GRP_TOGGLE", &vc_keymap_toggle, + NULL)) < 0) { + + if (r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/i18n: %s", strerror(-r)); + } + + if (vc_keytable) { + if (vc_keymap) + free(vc_keymap); + if (utf8) { + if (endswith(vc_keytable, ".uni") || strstr(vc_keytable, ".uni.")) + vc_keymap = strdup(vc_keytable); + else { + char *s; + if ((s = strstr(vc_keytable, ".map"))) + vc_keytable[s-vc_keytable+1] = '\0'; + vc_keymap = strappend(vc_keytable, ".uni"); + } + } else + vc_keymap = strdup(vc_keytable); + + free(vc_keytable); + + if (!vc_keymap) { + log_error("Out of memory."); + goto finish; + } + } + + if (access("/etc/sysconfig/console/default.kmap", F_OK) >= 0) { + char *t; + + if (!(t = strdup("/etc/sysconfig/console/default.kmap"))) { + log_error("Out of memory."); + goto finish; + } + + free(vc_keymap); + vc_keymap = t; + } +#endif + } + + r = EXIT_FAILURE; + + if (!utf8) + disable_utf8(fd); + + if (load_keymap(vc, vc_keymap, vc_keymap_toggle, utf8, &keymap_pid) >= 0 && + load_font(vc, vc_font, vc_font_map, vc_font_unimap, &font_pid) >= 0) + r = EXIT_SUCCESS; + +finish: + if (keymap_pid > 0) + wait_for_terminate_and_warn(KBD_LOADKEYS, keymap_pid); + + if (font_pid > 0) + wait_for_terminate_and_warn(KBD_SETFONT, font_pid); + + free(vc_keymap); + free(vc_font); + free(vc_font_map); + free(vc_font_unimap); + + if (fd >= 0) + close_nointr_nofail(fd); + + return r; +} diff --git a/src/virt.c b/src/virt.c new file mode 100644 index 0000000..3f0912a --- /dev/null +++ b/src/virt.c @@ -0,0 +1,321 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +#include +#include +#include + +#include "util.h" +#include "virt.h" + +/* Returns a short identifier for the various VM implementations */ +int detect_vm(const char **id) { + +#if defined(__i386__) || defined(__x86_64__) + + /* Both CPUID and DMI are x86 specific interfaces... */ + + static const char *const dmi_vendors[] = { + "/sys/class/dmi/id/sys_vendor", + "/sys/class/dmi/id/board_vendor", + "/sys/class/dmi/id/bios_vendor" + }; + + static const char dmi_vendor_table[] = + "QEMU\0" "qemu\0" + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + "VMware\0" "vmware\0" + "VMW\0" "vmware\0" + "Microsoft Corporation\0" "microsoft\0" + "innotek GmbH\0" "oracle\0" + "Xen\0" "xen\0" + "Bochs\0" "bochs\0"; + + static const char cpuid_vendor_table[] = + "XenVMMXenVMM\0" "xen\0" + "KVMKVMKVM\0" "kvm\0" + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + "VMwareVMware\0" "vmware\0" + /* http://msdn.microsoft.com/en-us/library/ff542428.aspx */ + "Microsoft Hv\0" "microsoft\0"; + + uint32_t eax, ecx; + union { + uint32_t sig32[3]; + char text[13]; + } sig; + unsigned i; + const char *j, *k; + bool hypervisor; + + /* http://lwn.net/Articles/301888/ */ + zero(sig); + +#if defined (__i386__) +#define REG_a "eax" +#define REG_b "ebx" +#elif defined (__amd64__) +#define REG_a "rax" +#define REG_b "rbx" +#endif + + /* First detect whether there is a hypervisor */ + eax = 1; + __asm__ __volatile__ ( + /* ebx/rbx is being used for PIC! */ + " push %%"REG_b" \n\t" + " cpuid \n\t" + " pop %%"REG_b" \n\t" + + : "=a" (eax), "=c" (ecx) + : "0" (eax) + ); + + hypervisor = !!(ecx & 0x80000000U); + + if (hypervisor) { + + /* There is a hypervisor, see what it is */ + eax = 0x40000000U; + __asm__ __volatile__ ( + /* ebx/rbx is being used for PIC! */ + " push %%"REG_b" \n\t" + " cpuid \n\t" + " mov %%ebx, %1 \n\t" + " pop %%"REG_b" \n\t" + + : "=a" (eax), "=r" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2]) + : "0" (eax) + ); + + NULSTR_FOREACH_PAIR(j, k, cpuid_vendor_table) + if (streq(sig.text, j)) { + + if (id) + *id = k; + + return 1; + } + } + + for (i = 0; i < ELEMENTSOF(dmi_vendors); i++) { + char *s; + int r; + const char *found = NULL; + + if ((r = read_one_line_file(dmi_vendors[i], &s)) < 0) { + if (r != -ENOENT) + return r; + + continue; + } + + NULSTR_FOREACH_PAIR(j, k, dmi_vendor_table) + if (startswith(s, j)) + found = k; + free(s); + + if (found) { + if (id) + *id = found; + + return 1; + } + } + + if (hypervisor) { + if (id) + *id = "other"; + + return 1; + } + +#endif + return 0; +} + +int detect_container(const char **id) { + FILE *f; + + /* Unfortunately many of these operations require root access + * in one way or another */ + + if (geteuid() != 0) + return -EPERM; + + if (running_in_chroot() > 0) { + + if (id) + *id = "chroot"; + + return 1; + } + + /* /proc/vz exists in container and outside of the container, + * /proc/bc only outside of the container. */ + if (access("/proc/vz", F_OK) >= 0 && + access("/proc/bc", F_OK) < 0) { + + if (id) + *id = "openvz"; + + return 1; + } + + f = fopen("/proc/1/environ", "re"); + if (f) { + bool done = false; + + do { + char line[LINE_MAX]; + unsigned i; + + for (i = 0; i < sizeof(line)-1; i++) { + int c; + + c = getc(f); + if (_unlikely_(c == EOF)) { + done = true; + break; + } else if (c == 0) + break; + + line[i] = c; + } + line[i] = 0; + + if (streq(line, "container=lxc")) { + fclose(f); + + if (id) + *id = "lxc"; + return 1; + + } else if (streq(line, "container=lxc-libvirt")) { + fclose(f); + + if (id) + *id = "lxc-libvirt"; + return 1; + + } else if (streq(line, "container=systemd-nspawn")) { + fclose(f); + + if (id) + *id = "systemd-nspawn"; + return 1; + + } else if (startswith(line, "container=")) { + fclose(f); + + if (id) + *id = "other"; + return 1; + } + + } while (!done); + + fclose(f); + } + + f = fopen("/proc/self/cgroup", "re"); + if (f) { + + for (;;) { + char line[LINE_MAX], *p; + + if (!fgets(line, sizeof(line), f)) + break; + + p = strchr(strstrip(line), ':'); + if (!p) + continue; + + if (strncmp(p, ":ns:", 4)) + continue; + + if (!streq(p, ":ns:/")) { + fclose(f); + + if (id) + *id = "pidns"; + + return 1; + } + } + + fclose(f); + } + + return 0; +} + +/* Returns a short identifier for the various VM/container implementations */ +Virtualization detect_virtualization(const char **id) { + + static __thread Virtualization cached_virt = _VIRTUALIZATION_INVALID; + static __thread const char *cached_id = NULL; + + const char *_id; + int r; + Virtualization v; + + if (_likely_(cached_virt >= 0)) { + + if (id && cached_virt > 0) + *id = cached_id; + + return cached_virt; + } + + r = detect_container(&_id); + if (r < 0) { + v = r; + goto finish; + } else if (r > 0) { + v = VIRTUALIZATION_CONTAINER; + goto finish; + } + + r = detect_vm(&_id); + if (r < 0) { + v = r; + goto finish; + } else if (r > 0) { + v = VIRTUALIZATION_VM; + goto finish; + } + + v = VIRTUALIZATION_NONE; + +finish: + if (v > 0) { + cached_id = _id; + + if (id) + *id = _id; + } + + if (v >= 0) + cached_virt = v; + + return v; +} diff --git a/src/virt.h b/src/virt.h new file mode 100644 index 0000000..f55c9a6 --- /dev/null +++ b/src/virt.h @@ -0,0 +1,38 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef foovirthfoo +#define foovirthfoo + +/*** + This file is part of systemd. + + Copyright 2011 Lennart Poettering + + systemd 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. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see . +***/ + +int detect_vm(const char **id); +int detect_container(const char **id); + +typedef enum Virtualization { + VIRTUALIZATION_NONE = 0, + VIRTUALIZATION_VM, + VIRTUALIZATION_CONTAINER, + _VIRTUALIZATION_MAX, + _VIRTUALIZATION_INVALID = -1 +} Virtualization; + +Virtualization detect_virtualization(const char **id); + +#endif diff --git a/src/wraplabel.c b/src/wraplabel.c new file mode 100644 index 0000000..6af8be4 --- /dev/null +++ b/src/wraplabel.c @@ -0,0 +1,335 @@ +/* wraplabel.c generated by valac 0.15.1, the Vala compiler + * generated from wraplabel.vala, do not modify */ + +/* Copyright (c) 2005 VMware, Inc.*/ +/* This is a translation of http://git.gnome.org/browse/meld/tree/meld/ui/wraplabel.py,*/ +/* which in turn is a translation of WrapLabel from libview.*/ +/* Permission is hereby granted, free of charge, to any person obtaining a copy*/ +/* of this software and associated documentation files (the "Software"), to deal*/ +/* in the Software without restriction, including without limitation the rights*/ +/* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell*/ +/* copies of the Software, and to permit persons to whom the Software is*/ +/* furnished to do so, subject to the following conditions:*/ +/**/ +/* The above copyright notice and this permission notice shall be included in*/ +/* all copies or substantial portions of the Software.*/ +/**/ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*/ +/* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,*/ +/* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE*/ +/* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*/ +/* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,*/ +/* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE*/ +/* SOFTWARE.*/ +/* Python translation from wrapLabel.{cc|h} by Gian Mario Tagliaretti*/ +/* Vala translation from wraplabel.py by Zbigniew Jędrzejewski-Szmek*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define TYPE_WRAP_LABEL (wrap_label_get_type ()) +#define WRAP_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_WRAP_LABEL, WrapLabel)) +#define WRAP_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_WRAP_LABEL, WrapLabelClass)) +#define IS_WRAP_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_WRAP_LABEL)) +#define IS_WRAP_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_WRAP_LABEL)) +#define WRAP_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_WRAP_LABEL, WrapLabelClass)) + +typedef struct _WrapLabel WrapLabel; +typedef struct _WrapLabelClass WrapLabelClass; +typedef struct _WrapLabelPrivate WrapLabelPrivate; +#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) + +struct _WrapLabel { + GtkLabel parent_instance; + WrapLabelPrivate * priv; +}; + +struct _WrapLabelClass { + GtkLabelClass parent_class; +}; + +struct _WrapLabelPrivate { + gint _wrap_width; +}; + + +static gpointer wrap_label_parent_class = NULL; + +GType wrap_label_get_type (void) G_GNUC_CONST; +#define WRAP_LABEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_WRAP_LABEL, WrapLabelPrivate)) +enum { + WRAP_LABEL_DUMMY_PROPERTY +}; +WrapLabel* wrap_label_new (const gchar* text); +WrapLabel* wrap_label_construct (GType object_type, const gchar* text); +void wrap_label_set_text (WrapLabel* self, const gchar* str); +static void wrap_label_real_size_request (GtkWidget* base, GtkRequisition* requisition); +static void wrap_label_real_size_allocate (GtkWidget* base, GdkRectangle* allocation); +static void _wrap_label_set_wrap_width (WrapLabel* self, gint width); +void wrap_label_set_markup (WrapLabel* self, const gchar* str); +static void wrap_label_finalize (GObject* obj); + + +static gpointer _g_object_ref0 (gpointer self) { +#line 32 "/home/lennart/projects/systemd/src/wraplabel.vala" + return self ? g_object_ref (self) : NULL; +#line 85 "wraplabel.c" +} + + +WrapLabel* wrap_label_construct (GType object_type, const gchar* text) { + WrapLabel * self = NULL; + PangoLayout* _tmp0_ = NULL; + PangoLayout* _tmp1_; + PangoLayout* layout; + PangoLayout* _tmp2_; + const gchar* _tmp3_; +#line 30 "/home/lennart/projects/systemd/src/wraplabel.vala" + self = (WrapLabel*) g_object_new (object_type, NULL); +#line 31 "/home/lennart/projects/systemd/src/wraplabel.vala" + self->priv->_wrap_width = 0; +#line 32 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp0_ = gtk_label_get_layout ((GtkLabel*) self); +#line 32 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp1_ = _g_object_ref0 (_tmp0_); +#line 32 "/home/lennart/projects/systemd/src/wraplabel.vala" + layout = _tmp1_; +#line 33 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp2_ = layout; +#line 33 "/home/lennart/projects/systemd/src/wraplabel.vala" + pango_layout_set_wrap (_tmp2_, PANGO_WRAP_WORD_CHAR); +#line 34 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp3_ = text; +#line 34 "/home/lennart/projects/systemd/src/wraplabel.vala" + if (_tmp3_ != NULL) { +#line 114 "wraplabel.c" + const gchar* _tmp4_; +#line 35 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp4_ = text; +#line 35 "/home/lennart/projects/systemd/src/wraplabel.vala" + wrap_label_set_text (self, _tmp4_); +#line 120 "wraplabel.c" + } +#line 36 "/home/lennart/projects/systemd/src/wraplabel.vala" + gtk_misc_set_alignment ((GtkMisc*) self, (gfloat) 0, (gfloat) 0); +#line 30 "/home/lennart/projects/systemd/src/wraplabel.vala" + _g_object_unref0 (layout); +#line 30 "/home/lennart/projects/systemd/src/wraplabel.vala" + return self; +#line 128 "wraplabel.c" +} + + +WrapLabel* wrap_label_new (const gchar* text) { +#line 30 "/home/lennart/projects/systemd/src/wraplabel.vala" + return wrap_label_construct (TYPE_WRAP_LABEL, text); +#line 135 "wraplabel.c" +} + + +static void wrap_label_real_size_request (GtkWidget* base, GtkRequisition* requisition) { + WrapLabel * self; + GtkRequisition _vala_requisition = {0}; + gint width = 0; + gint height = 0; + PangoLayout* _tmp0_ = NULL; + PangoLayout* _tmp1_; + PangoLayout* layout; + gint _tmp2_ = 0; + gint _tmp3_ = 0; +#line 39 "/home/lennart/projects/systemd/src/wraplabel.vala" + self = (WrapLabel*) base; +#line 41 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp0_ = gtk_label_get_layout ((GtkLabel*) self); +#line 41 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp1_ = _g_object_ref0 (_tmp0_); +#line 41 "/home/lennart/projects/systemd/src/wraplabel.vala" + layout = _tmp1_; +#line 42 "/home/lennart/projects/systemd/src/wraplabel.vala" + pango_layout_get_pixel_size (layout, &_tmp2_, &_tmp3_); +#line 42 "/home/lennart/projects/systemd/src/wraplabel.vala" + width = _tmp2_; +#line 42 "/home/lennart/projects/systemd/src/wraplabel.vala" + height = _tmp3_; +#line 43 "/home/lennart/projects/systemd/src/wraplabel.vala" + _vala_requisition.width = 0; +#line 44 "/home/lennart/projects/systemd/src/wraplabel.vala" + _vala_requisition.height = height; +#line 39 "/home/lennart/projects/systemd/src/wraplabel.vala" + _g_object_unref0 (layout); +#line 39 "/home/lennart/projects/systemd/src/wraplabel.vala" + if (requisition) { +#line 39 "/home/lennart/projects/systemd/src/wraplabel.vala" + *requisition = _vala_requisition; +#line 173 "wraplabel.c" + } +} + + +static void wrap_label_real_size_allocate (GtkWidget* base, GdkRectangle* allocation) { + WrapLabel * self; + GdkRectangle _tmp0_; + GdkRectangle _tmp1_; + gint _tmp2_; +#line 47 "/home/lennart/projects/systemd/src/wraplabel.vala" + self = (WrapLabel*) base; +#line 47 "/home/lennart/projects/systemd/src/wraplabel.vala" + g_return_if_fail (allocation != NULL); +#line 48 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp0_ = *allocation; +#line 48 "/home/lennart/projects/systemd/src/wraplabel.vala" + GTK_WIDGET_CLASS (wrap_label_parent_class)->size_allocate ((GtkWidget*) GTK_LABEL (self), &_tmp0_); +#line 49 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp1_ = *allocation; +#line 49 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp2_ = _tmp1_.width; +#line 49 "/home/lennart/projects/systemd/src/wraplabel.vala" + _wrap_label_set_wrap_width (self, _tmp2_); +#line 197 "wraplabel.c" +} + + +void wrap_label_set_text (WrapLabel* self, const gchar* str) { + const gchar* _tmp0_; + gint _tmp1_; +#line 52 "/home/lennart/projects/systemd/src/wraplabel.vala" + g_return_if_fail (self != NULL); +#line 52 "/home/lennart/projects/systemd/src/wraplabel.vala" + g_return_if_fail (str != NULL); +#line 53 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp0_ = str; +#line 53 "/home/lennart/projects/systemd/src/wraplabel.vala" + gtk_label_set_text (GTK_LABEL (self), _tmp0_); +#line 54 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp1_ = self->priv->_wrap_width; +#line 54 "/home/lennart/projects/systemd/src/wraplabel.vala" + _wrap_label_set_wrap_width (self, _tmp1_); +#line 216 "wraplabel.c" +} + + +void wrap_label_set_markup (WrapLabel* self, const gchar* str) { + const gchar* _tmp0_; + gint _tmp1_; +#line 57 "/home/lennart/projects/systemd/src/wraplabel.vala" + g_return_if_fail (self != NULL); +#line 57 "/home/lennart/projects/systemd/src/wraplabel.vala" + g_return_if_fail (str != NULL); +#line 58 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp0_ = str; +#line 58 "/home/lennart/projects/systemd/src/wraplabel.vala" + gtk_label_set_markup (GTK_LABEL (self), _tmp0_); +#line 59 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp1_ = self->priv->_wrap_width; +#line 59 "/home/lennart/projects/systemd/src/wraplabel.vala" + _wrap_label_set_wrap_width (self, _tmp1_); +#line 235 "wraplabel.c" +} + + +static void _wrap_label_set_wrap_width (WrapLabel* self, gint width) { + gint _tmp0_; + PangoLayout* _tmp1_ = NULL; + PangoLayout* _tmp2_; + PangoLayout* layout; + PangoLayout* _tmp3_; + gint _tmp4_; + gint _tmp5_; + gint _tmp6_; +#line 62 "/home/lennart/projects/systemd/src/wraplabel.vala" + g_return_if_fail (self != NULL); +#line 63 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp0_ = width; +#line 63 "/home/lennart/projects/systemd/src/wraplabel.vala" + if (_tmp0_ == 0) { +#line 64 "/home/lennart/projects/systemd/src/wraplabel.vala" + return; +#line 256 "wraplabel.c" + } +#line 66 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp1_ = gtk_label_get_layout ((GtkLabel*) self); +#line 66 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp2_ = _g_object_ref0 (_tmp1_); +#line 66 "/home/lennart/projects/systemd/src/wraplabel.vala" + layout = _tmp2_; +#line 67 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp3_ = layout; +#line 67 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp4_ = width; +#line 67 "/home/lennart/projects/systemd/src/wraplabel.vala" + pango_layout_set_width (_tmp3_, _tmp4_ * PANGO_SCALE); +#line 68 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp5_ = self->priv->_wrap_width; +#line 68 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp6_ = width; +#line 68 "/home/lennart/projects/systemd/src/wraplabel.vala" + if (_tmp5_ != _tmp6_) { +#line 276 "wraplabel.c" + gint _tmp7_; +#line 69 "/home/lennart/projects/systemd/src/wraplabel.vala" + _tmp7_ = width; +#line 69 "/home/lennart/projects/systemd/src/wraplabel.vala" + self->priv->_wrap_width = _tmp7_; +#line 70 "/home/lennart/projects/systemd/src/wraplabel.vala" + gtk_widget_queue_resize ((GtkWidget*) self); +#line 284 "wraplabel.c" + } +#line 62 "/home/lennart/projects/systemd/src/wraplabel.vala" + _g_object_unref0 (layout); +#line 288 "wraplabel.c" +} + + +static void wrap_label_class_init (WrapLabelClass * klass) { +#line 27 "/home/lennart/projects/systemd/src/wraplabel.vala" + wrap_label_parent_class = g_type_class_peek_parent (klass); +#line 27 "/home/lennart/projects/systemd/src/wraplabel.vala" + g_type_class_add_private (klass, sizeof (WrapLabelPrivate)); +#line 27 "/home/lennart/projects/systemd/src/wraplabel.vala" + GTK_WIDGET_CLASS (klass)->size_request = wrap_label_real_size_request; +#line 27 "/home/lennart/projects/systemd/src/wraplabel.vala" + GTK_WIDGET_CLASS (klass)->size_allocate = wrap_label_real_size_allocate; +#line 27 "/home/lennart/projects/systemd/src/wraplabel.vala" + G_OBJECT_CLASS (klass)->finalize = wrap_label_finalize; +#line 303 "wraplabel.c" +} + + +static void wrap_label_instance_init (WrapLabel * self) { +#line 27 "/home/lennart/projects/systemd/src/wraplabel.vala" + self->priv = WRAP_LABEL_GET_PRIVATE (self); +#line 310 "wraplabel.c" +} + + +static void wrap_label_finalize (GObject* obj) { + WrapLabel * self; +#line 27 "/home/lennart/projects/systemd/src/wraplabel.vala" + self = WRAP_LABEL (obj); +#line 27 "/home/lennart/projects/systemd/src/wraplabel.vala" + G_OBJECT_CLASS (wrap_label_parent_class)->finalize (obj); +#line 320 "wraplabel.c" +} + + +GType wrap_label_get_type (void) { + static volatile gsize wrap_label_type_id__volatile = 0; + if (g_once_init_enter (&wrap_label_type_id__volatile)) { + static const GTypeInfo g_define_type_info = { sizeof (WrapLabelClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) wrap_label_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (WrapLabel), 0, (GInstanceInitFunc) wrap_label_instance_init, NULL }; + GType wrap_label_type_id; + wrap_label_type_id = g_type_register_static (GTK_TYPE_LABEL, "WrapLabel", &g_define_type_info, 0); + g_once_init_leave (&wrap_label_type_id__volatile, wrap_label_type_id); + } + return wrap_label_type_id__volatile; +} + + + diff --git a/src/wraplabel.vala b/src/wraplabel.vala new file mode 100644 index 0000000..49858c3 --- /dev/null +++ b/src/wraplabel.vala @@ -0,0 +1,73 @@ +// Copyright (c) 2005 VMware, Inc. + +// This is a translation of http://git.gnome.org/browse/meld/tree/meld/ui/wraplabel.py, +// which in turn is a translation of WrapLabel from libview. + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +// Python translation from wrapLabel.{cc|h} by Gian Mario Tagliaretti +// Vala translation from wraplabel.py by Zbigniew Jędrzejewski-Szmek + +public class WrapLabel : Gtk.Label { + private int _wrap_width; + + public WrapLabel(string? text = null) { + this._wrap_width = 0; + var layout = get_layout(); + layout.set_wrap(Pango.WrapMode.WORD_CHAR); + if (text != null) + this.set_text(text); + this.set_alignment(0, 0); + } + + public override void size_request(out Gtk.Requisition requisition) { + int width, height; + var layout = get_layout(); + layout.get_pixel_size(out width, out height); + requisition.width = 0; + requisition.height = height; + } + + public override void size_allocate(Gdk.Rectangle allocation) { + base.size_allocate (allocation); + this._set_wrap_width(allocation.width); + } + + public new void set_text(string str) { + base.set_text(str); + this._set_wrap_width(this._wrap_width); + } + + public new void set_markup(string str) { + base.set_markup(str); + this._set_wrap_width(this._wrap_width); + } + + private void _set_wrap_width(int width) { + if (width == 0) + return; + + var layout = get_layout(); + layout.set_width(width * Pango.SCALE); + if (_wrap_width != width) { + this._wrap_width = width; + this.queue_resize(); + } + } +} diff --git a/sysctl.d/coredump.conf.in b/sysctl.d/coredump.conf.in new file mode 100644 index 0000000..ab19b1e --- /dev/null +++ b/sysctl.d/coredump.conf.in @@ -0,0 +1,10 @@ +# This file is part of systemd. +# +# systemd 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. + +# See sysctl.d(5) for details + +kernel.core_pattern=|@rootlibexecdir@/systemd-coredump %p %u %g %s %t %e diff --git a/systemadm_vala.stamp b/systemadm_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemadm_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemctl_vala.stamp b/systemctl_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemctl_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemd_ac_power_vala.stamp b/systemd_ac_power_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_ask_password_vala.stamp b/systemd_ask_password_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_binfmt_vala.stamp b/systemd_binfmt_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_cat_vala.stamp b/systemd_cat_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_cgls_vala.stamp b/systemd_cgls_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_cgroups_agent_vala.stamp b/systemd_cgroups_agent_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemd_cgroups_agent_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemd_cgtop_vala.stamp b/systemd_cgtop_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_coredump_vala.stamp b/systemd_coredump_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_cryptsetup_generator_vala.stamp b/systemd_cryptsetup_generator_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_cryptsetup_vala.stamp b/systemd_cryptsetup_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_detect_virt_vala.stamp b/systemd_detect_virt_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_fsck_vala.stamp b/systemd_fsck_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemd_fsck_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemd_getty_generator_vala.stamp b/systemd_getty_generator_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_gnome_ask_password_agent_vala.stamp b/systemd_gnome_ask_password_agent_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_hostnamed_vala.stamp b/systemd_hostnamed_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemd_hostnamed_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemd_initctl_vala.stamp b/systemd_initctl_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemd_initctl_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemd_journalctl_vala.stamp b/systemd_journalctl_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_journald_vala.stamp b/systemd_journald_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_localed_vala.stamp b/systemd_localed_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemd_localed_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemd_loginctl_vala.stamp b/systemd_loginctl_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemd_loginctl_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemd_logind_vala.stamp b/systemd_logind_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemd_logind_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemd_machine_id_setup_vala.stamp b/systemd_machine_id_setup_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_modules_load_vala.stamp b/systemd_modules_load_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemd_modules_load_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemd_multi_seat_x_vala.stamp b/systemd_multi_seat_x_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_notify_vala.stamp b/systemd_notify_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_nspawn_vala.stamp b/systemd_nspawn_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemd_nspawn_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemd_quotacheck_vala.stamp b/systemd_quotacheck_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_random_seed_vala.stamp b/systemd_random_seed_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_rc_local_generator_vala.stamp b/systemd_rc_local_generator_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_readahead_collect_vala.stamp b/systemd_readahead_collect_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_readahead_replay_vala.stamp b/systemd_readahead_replay_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_remount_api_vfs_vala.stamp b/systemd_remount_api_vfs_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_reply_password_vala.stamp b/systemd_reply_password_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_shutdown_vala.stamp b/systemd_shutdown_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_shutdownd_vala.stamp b/systemd_shutdownd_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_stdio_bridge_vala.stamp b/systemd_stdio_bridge_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_sysctl_vala.stamp b/systemd_sysctl_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_timedated_vala.stamp b/systemd_timedated_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemd_timedated_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemd_timestamp_vala.stamp b/systemd_timestamp_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemd_timestamp_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemd_tmpfiles_vala.stamp b/systemd_tmpfiles_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_tty_ask_password_agent_vala.stamp b/systemd_tty_ask_password_agent_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_uaccess_vala.stamp b/systemd_uaccess_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_update_utmp_vala.stamp b/systemd_update_utmp_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemd_update_utmp_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemd_user_sessions_vala.stamp b/systemd_user_sessions_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/systemd_vala.stamp b/systemd_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/systemd_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/systemd_vconsole_setup_vala.stamp b/systemd_vconsole_setup_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/test_cgroup_vala.stamp b/test_cgroup_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/test_daemon_vala.stamp b/test_daemon_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/test_engine_vala.stamp b/test_engine_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/test_env_replace_vala.stamp b/test_env_replace_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/test_hostname_vala.stamp b/test_hostname_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/test_id128_vala.stamp b/test_id128_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/test_install_vala.stamp b/test_install_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/test_install_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/test_job_type_vala.stamp b/test_job_type_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/test_journal_vala.stamp b/test_journal_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/test_login_vala.stamp b/test_login_vala.stamp new file mode 100644 index 0000000..859afb1 --- /dev/null +++ b/test_login_vala.stamp @@ -0,0 +1 @@ +stamp diff --git a/test_loopback_vala.stamp b/test_loopback_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/test_ns_vala.stamp b/test_ns_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/test_strv_vala.stamp b/test_strv_vala.stamp new file mode 100644 index 0000000..e69de29 diff --git a/tmpfiles.d/legacy.conf b/tmpfiles.d/legacy.conf new file mode 100644 index 0000000..9198e89 --- /dev/null +++ b/tmpfiles.d/legacy.conf @@ -0,0 +1,22 @@ +# This file is part of systemd. +# +# systemd 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. + +# See tmpfiles.d(5) for details + +# These files are considered legacy and are unnecessary on legacy-free +# systems. /run/lock/subsys is used for serializing SysV service +# execution, and hence without use on SysV-less systems. +# +# /run/lock/lockdev is used to serialize access to tty devices via +# LCK..xxx style lock files, For more information see: +# http://lists.freedesktop.org/archives/systemd-devel/2011-March/001823.html +# On modern systems a BSD file lock is a better choice if +# serialization is needed on those devices. + +d /run/lock 0755 root root - +d /run/lock/subsys 0755 root root - +d /run/lock/lockdev 0775 root lock - diff --git a/tmpfiles.d/systemd.conf b/tmpfiles.d/systemd.conf new file mode 100644 index 0000000..be29c06 --- /dev/null +++ b/tmpfiles.d/systemd.conf @@ -0,0 +1,25 @@ +# This file is part of systemd. +# +# systemd 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. + +# See tmpfiles.d(5) for details + +d /run/user 0755 root root 10d +F /run/utmp 0664 root utmp - + +f /var/log/wtmp 0664 root utmp - +f /var/log/btmp 0600 root utmp - + +d /var/cache/man - - - 30d + +r /forcefsck +r /forcequotacheck +r /fastboot + +d /run/systemd/ask-password 0755 root root - +d /run/systemd/seats 0755 root root - +d /run/systemd/sessions 0755 root root - +d /run/systemd/users 0755 root root - diff --git a/tmpfiles.d/tmp.conf b/tmpfiles.d/tmp.conf new file mode 100644 index 0000000..8915b82 --- /dev/null +++ b/tmpfiles.d/tmp.conf @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# systemd 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. + +# See tmpfiles.d(5) for details + +# Clear tmp directories separately, to make them easier to override +d /tmp 1777 root root 10d +d /var/tmp 1777 root root 30d diff --git a/tmpfiles.d/x11.conf b/tmpfiles.d/x11.conf new file mode 100644 index 0000000..7f81af6 --- /dev/null +++ b/tmpfiles.d/x11.conf @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +# See tmpfiles.d(5) for details + +# Make sure these are created by default so that nobody else can +d /tmp/.X11-unix 1777 root root 10d +d /tmp/.ICE-unix 1777 root root 10d +d /tmp/.XIM-unix 1777 root root 10d +d /tmp/.font-unix 1777 root root 10d +d /tmp/.Test-unix 1777 root root 10d + +# Unlink the X11 lock files +r /tmp/.X[0-9]*-lock diff --git a/units/basic.target b/units/basic.target new file mode 100644 index 0000000..0258ca0 --- /dev/null +++ b/units/basic.target @@ -0,0 +1,14 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Basic System +Requires=sysinit.target sockets.target +After=sysinit.target sockets.target +RefuseManualStart=yes diff --git a/units/bluetooth.target b/units/bluetooth.target new file mode 100644 index 0000000..c66718e --- /dev/null +++ b/units/bluetooth.target @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Bluetooth +StopWhenUnneeded=yes diff --git a/units/console-shell.service.m4 b/units/console-shell.service.m4 new file mode 100644 index 0000000..fef9e1b --- /dev/null +++ b/units/console-shell.service.m4 @@ -0,0 +1,47 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Console Shell +After=systemd-user-sessions.service plymouth-quit-wait.service +m4_ifdef(`TARGET_FEDORA', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_ARCH', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_FRUGALWARE', +After=local.service +)m4_dnl +m4_ifdef(`TARGET_ALTLINUX', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_MANDRIVA', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_MAGEIA', +After=rc-local.service +)m4_dnl +Before=getty.target + +[Service] +Environment=HOME=/root +WorkingDirectory=/root +ExecStart=-/sbin/sulogin +ExecStopPost=-/bin/systemctl poweroff +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process +IgnoreSIGPIPE=no + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP + +[Install] +WantedBy=getty.target diff --git a/units/cryptsetup.target b/units/cryptsetup.target new file mode 100644 index 0000000..64ee8c6 --- /dev/null +++ b/units/cryptsetup.target @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Encrypted Volumes diff --git a/units/dev-hugepages.mount b/units/dev-hugepages.mount new file mode 100644 index 0000000..72a522e --- /dev/null +++ b/units/dev-hugepages.mount @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Huge Pages File System +DefaultDependencies=no +Before=sysinit.target +ConditionPathExists=/sys/kernel/mm/hugepages + +[Mount] +What=hugetlbfs +Where=/dev/hugepages +Type=hugetlbfs diff --git a/units/dev-mqueue.mount b/units/dev-mqueue.mount new file mode 100644 index 0000000..cffdaf7 --- /dev/null +++ b/units/dev-mqueue.mount @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=POSIX Message Queue File System +DefaultDependencies=no +Before=sysinit.target +ConditionPathExists=/proc/sys/fs/mqueue + +[Mount] +What=mqueue +Where=/dev/mqueue +Type=mqueue diff --git a/units/emergency.service b/units/emergency.service new file mode 100644 index 0000000..234bafc --- /dev/null +++ b/units/emergency.service @@ -0,0 +1,31 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Emergency Shell +DefaultDependencies=no +Conflicts=shutdown.target +Before=shutdown.target + +[Service] +Environment=HOME=/root +WorkingDirectory=/root +ExecStartPre=-/bin/plymouth quit +ExecStartPre=-/bin/echo 'Welcome to emergency mode. Use "systemctl default" or ^D to activate default mode.' +ExecStart=-/sbin/sulogin +ExecStopPost=/bin/systemctl --fail --no-block default +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process +IgnoreSIGPIPE=no + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/units/emergency.target b/units/emergency.target new file mode 100644 index 0000000..6a99e05 --- /dev/null +++ b/units/emergency.target @@ -0,0 +1,14 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Emergency Mode +Requires=emergency.service +After=emergency.service +AllowIsolate=yes diff --git a/units/fedora/halt-local.service b/units/fedora/halt-local.service new file mode 100644 index 0000000..a9f6feb --- /dev/null +++ b/units/fedora/halt-local.service @@ -0,0 +1,20 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=/sbin/halt.local Compatibility +ConditionFileIsExecutable=/sbin/halt.local +DefaultDependencies=no +After=shutdown.target +Before=final.target + +[Service] +Type=oneshot +ExecStart=/sbin/halt.local +TimeoutSec=0 +StandardOutput=tty +RemainAfterExit=yes diff --git a/units/fedora/prefdm.service b/units/fedora/prefdm.service new file mode 100644 index 0000000..77a0e9a --- /dev/null +++ b/units/fedora/prefdm.service @@ -0,0 +1,21 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Display Manager +After=livesys-late.service rc-local.service systemd-user-sessions.service + +# On Fedora gdm/X11 is on tty1. We explicitly cancel the getty here to +# avoid any races around that. +Conflicts=getty@tty1.service plymouth-quit.service +After=getty@tty1.service plymouth-quit.service + +[Service] +ExecStart=/etc/X11/prefdm -nodaemon +Restart=always +RestartSec=0 +IgnoreSIGPIPE=no diff --git a/units/fedora/rc-local.service b/units/fedora/rc-local.service new file mode 100644 index 0000000..0bef5c7 --- /dev/null +++ b/units/fedora/rc-local.service @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd 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. + +# This unit gets pulled automatically into multi-user.target by +# systemd-rc-local-generator if /etc/rc.d/rc.local is executable. +[Unit] +Description=/etc/rc.d/rc.local Compatibility +After=network.target + +[Service] +Type=forking +ExecStart=/etc/rc.d/rc.local start +TimeoutSec=0 +RemainAfterExit=yes +SysVStartPriority=99 diff --git a/units/final.target b/units/final.target new file mode 100644 index 0000000..9cfda19 --- /dev/null +++ b/units/final.target @@ -0,0 +1,14 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Final Step +DefaultDependencies=no +RefuseManualStart=yes +After=shutdown.target umount.target diff --git a/units/frugalware/display-manager.service b/units/frugalware/display-manager.service new file mode 100644 index 0000000..2376e19 --- /dev/null +++ b/units/frugalware/display-manager.service @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Display Manager +After=local.service systemd-user-sessions.service + +[Service] +EnvironmentFile=/etc/sysconfig/desktop +ExecStart=/bin/bash -c "exec ${desktop}" +Restart=always +RestartSec=0 diff --git a/units/fsck-root.service.in b/units/fsck-root.service.in new file mode 100644 index 0000000..4086149 --- /dev/null +++ b/units/fsck-root.service.in @@ -0,0 +1,23 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=File System Check on Root Device +DefaultDependencies=no +After=systemd-readahead-collect.service systemd-readahead-replay.service +Before=local-fs.target shutdown.target + +# Dracut informs us with this flag file if the root fsck was already run +ConditionPathExists=!/run/initramfs/root-fsck + +[Service] +Type=oneshot +RemainAfterExit=no +ExecStart=@rootlibexecdir@/systemd-fsck +StandardOutput=journal+console +FsckPassNo=1 +TimeoutSec=0 diff --git a/units/fsck@.service.in b/units/fsck@.service.in new file mode 100644 index 0000000..c06684b --- /dev/null +++ b/units/fsck@.service.in @@ -0,0 +1,20 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=File System Check on %f +DefaultDependencies=no +BindTo=%i.device +After=systemd-readahead-collect.service systemd-readahead-replay.service %i.device +Before=shutdown.target + +[Service] +Type=oneshot +RemainAfterExit=no +ExecStart=@rootlibexecdir@/systemd-fsck %f +StandardOutput=journal+console +TimeoutSec=0 diff --git a/units/getty.target b/units/getty.target new file mode 100644 index 0000000..e4435dc --- /dev/null +++ b/units/getty.target @@ -0,0 +1,9 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Login Prompts diff --git a/units/getty@.service.m4 b/units/getty@.service.m4 new file mode 100644 index 0000000..a02838d --- /dev/null +++ b/units/getty@.service.m4 @@ -0,0 +1,58 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Getty on %I +BindTo=dev-%i.device +After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service +m4_ifdef(`TARGET_FEDORA', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_ARCH', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_FRUGALWARE', +After=local.service +)m4_dnl +m4_ifdef(`TARGET_ALTLINUX', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_MANDRIVA', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_MAGEIA', +After=rc-local.service +)m4_dnl + +# If additional gettys are spawned during boot then we should make +# sure that this is synchronized before getty.target, even though +# getty.target didn't actually pull it in. +Before=getty.target + +[Service] +Environment=TERM=linux +ExecStart=-/sbin/agetty %I 38400 +Restart=always +RestartSec=0 +UtmpIdentifier=%I +TTYPath=/dev/%I +TTYReset=yes +TTYVHangup=yes +TTYVTDisallocate=yes +KillMode=process +IgnoreSIGPIPE=no + +# Unset locale for the console getty since the console has problems +# displaying some internationalized messages. +Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= + +# Some login implementations ignore SIGTERM, so we send SIGHUP +# instead, to ensure that login terminates cleanly. +KillSignal=SIGHUP + +[Install] +Alias=getty.target.wants/getty@tty1.service diff --git a/units/graphical.target b/units/graphical.target new file mode 100644 index 0000000..f2e3034 --- /dev/null +++ b/units/graphical.target @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Graphical Interface +Requires=multi-user.target +After=multi-user.target +Conflicts=rescue.target +AllowIsolate=yes + +[Install] +Alias=default.target diff --git a/units/halt.service.in b/units/halt.service.in new file mode 100644 index 0000000..42e3470 --- /dev/null +++ b/units/halt.service.in @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Halt +DefaultDependencies=no +Requires=shutdown.target umount.target final.target +After=shutdown.target umount.target final.target + +[Service] +Type=oneshot +ExecStart=@SYSTEMCTL@ --force halt diff --git a/units/halt.target b/units/halt.target new file mode 100644 index 0000000..04b42cd --- /dev/null +++ b/units/halt.target @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Halt +DefaultDependencies=no +Requires=halt.service +After=halt.service +AllowIsolate=yes + +[Install] +Alias=ctrl-alt-del.target diff --git a/units/http-daemon.target b/units/http-daemon.target new file mode 100644 index 0000000..45f1018 --- /dev/null +++ b/units/http-daemon.target @@ -0,0 +1,14 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + +[Unit] +Description=Web Server diff --git a/units/kexec.service.in b/units/kexec.service.in new file mode 100644 index 0000000..cf6bd65 --- /dev/null +++ b/units/kexec.service.in @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Reboot via kexec +DefaultDependencies=no +Requires=shutdown.target umount.target final.target +After=shutdown.target umount.target final.target + +[Service] +Type=oneshot +ExecStart=@SYSTEMCTL@ --force kexec diff --git a/units/kexec.target b/units/kexec.target new file mode 100644 index 0000000..b77e6a4 --- /dev/null +++ b/units/kexec.target @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Reboot via kexec +DefaultDependencies=no +Requires=kexec.service +After=kexec.service +AllowIsolate=yes + +[Install] +Alias=ctrl-alt-del.target diff --git a/units/local-fs-pre.target b/units/local-fs-pre.target new file mode 100644 index 0000000..11e67ba --- /dev/null +++ b/units/local-fs-pre.target @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Local File Systems (Pre) diff --git a/units/local-fs.target b/units/local-fs.target new file mode 100644 index 0000000..1886f74 --- /dev/null +++ b/units/local-fs.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Local File Systems +OnFailure=emergency.target +OnFailureIsolate=yes diff --git a/units/mageia/prefdm.service b/units/mageia/prefdm.service new file mode 100644 index 0000000..4a896bf --- /dev/null +++ b/units/mageia/prefdm.service @@ -0,0 +1,21 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Display Manager +After=livesys-late.service rc-local.service systemd-user-sessions.service +After=network.target acpid.service fs.service haldaemon.service + +# Do not stop plymouth, it is done in prefdm if required +Conflicts=plymouth-quit.service +After=plymouth-quit.service + +[Service] +ExecStart=/etc/X11/prefdm +Type=forking +Restart=always +RestartSec=0 diff --git a/units/mail-transfer-agent.target b/units/mail-transfer-agent.target new file mode 100644 index 0000000..ebb1ea1 --- /dev/null +++ b/units/mail-transfer-agent.target @@ -0,0 +1,14 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + +[Unit] +Description=Mail Transfer Agent diff --git a/units/mandriva/prefdm.service b/units/mandriva/prefdm.service new file mode 100644 index 0000000..4a896bf --- /dev/null +++ b/units/mandriva/prefdm.service @@ -0,0 +1,21 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Display Manager +After=livesys-late.service rc-local.service systemd-user-sessions.service +After=network.target acpid.service fs.service haldaemon.service + +# Do not stop plymouth, it is done in prefdm if required +Conflicts=plymouth-quit.service +After=plymouth-quit.service + +[Service] +ExecStart=/etc/X11/prefdm +Type=forking +Restart=always +RestartSec=0 diff --git a/units/media.mount b/units/media.mount new file mode 100644 index 0000000..66a5a5c --- /dev/null +++ b/units/media.mount @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Media Directory +Before=local-fs.target + +[Mount] +What=tmpfs +Where=/media +Type=tmpfs +Options=mode=755,nosuid,nodev,noexec diff --git a/units/multi-user.target b/units/multi-user.target new file mode 100644 index 0000000..66f1a95 --- /dev/null +++ b/units/multi-user.target @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Multi-User +Requires=basic.target +Conflicts=rescue.service rescue.target +After=basic.target rescue.service rescue.target +AllowIsolate=yes + +[Install] +Alias=default.target diff --git a/units/network.target b/units/network.target new file mode 100644 index 0000000..d97f64f --- /dev/null +++ b/units/network.target @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Network diff --git a/units/nss-lookup.target b/units/nss-lookup.target new file mode 100644 index 0000000..bdca03c --- /dev/null +++ b/units/nss-lookup.target @@ -0,0 +1,15 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + +[Unit] +Description=Name Lookups +After=network.target diff --git a/units/plymouth-halt.service b/units/plymouth-halt.service new file mode 100644 index 0000000..2e194b3 --- /dev/null +++ b/units/plymouth-halt.service @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Show Plymouth Halt Screen +After=getty@tty1.service prefdm.service plymouth-start.service +Before=halt.service +DefaultDependencies=no +ConditionKernelCommandLine=!plymouth.enable=0 + +[Service] +ExecStart=/sbin/plymouthd --mode=shutdown +ExecStartPost=-/bin/plymouth --show-splash +Type=forking diff --git a/units/plymouth-kexec.service b/units/plymouth-kexec.service new file mode 100644 index 0000000..919c3f1 --- /dev/null +++ b/units/plymouth-kexec.service @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Show Plymouth Reboot with kexec Screen +After=getty@tty1.service prefdm.service plymouth-start.service +Before=kexec.service +DefaultDependencies=no +ConditionKernelCommandLine=!plymouth.enable=0 + +[Service] +ExecStart=/sbin/plymouthd --mode=shutdown +ExecStartPost=-/bin/plymouth --show-splash +Type=forking diff --git a/units/plymouth-poweroff.service b/units/plymouth-poweroff.service new file mode 100644 index 0000000..8fcff3b --- /dev/null +++ b/units/plymouth-poweroff.service @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Show Plymouth Power Off Screen +After=getty@tty1.service prefdm.service plymouth-start.service +Before=poweroff.service +DefaultDependencies=no +ConditionKernelCommandLine=!plymouth.enable=0 + +[Service] +ExecStart=/sbin/plymouthd --mode=shutdown +ExecStartPost=-/bin/plymouth --show-splash +Type=forking diff --git a/units/plymouth-quit-wait.service b/units/plymouth-quit-wait.service new file mode 100644 index 0000000..45c67bd --- /dev/null +++ b/units/plymouth-quit-wait.service @@ -0,0 +1,15 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Wait for Plymouth Boot Screen to Quit +After=rc-local.service plymouth-start.service + +[Service] +ExecStart=-/bin/plymouth --wait +Type=oneshot +TimeoutSec=20 diff --git a/units/plymouth-quit.service b/units/plymouth-quit.service new file mode 100644 index 0000000..164499a --- /dev/null +++ b/units/plymouth-quit.service @@ -0,0 +1,15 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Terminate Plymouth Boot Screen +After=rc-local.service plymouth-start.service + +[Service] +ExecStart=-/bin/plymouth quit +Type=oneshot +TimeoutSec=20 diff --git a/units/plymouth-read-write.service b/units/plymouth-read-write.service new file mode 100644 index 0000000..09fbf7d --- /dev/null +++ b/units/plymouth-read-write.service @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Tell Plymouth To Write Out Runtime Data +DefaultDependencies=no +After=local-fs.target +Before=sysinit.target + +[Service] +ExecStart=-/bin/plymouth update-root-fs --read-write +Type=oneshot diff --git a/units/plymouth-reboot.service b/units/plymouth-reboot.service new file mode 100644 index 0000000..fb65bcc --- /dev/null +++ b/units/plymouth-reboot.service @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Show Plymouth Reboot Screen +After=getty@tty1.service prefdm.service plymouth-start.service +Before=reboot.service +DefaultDependencies=no +ConditionKernelCommandLine=!plymouth.enable=0 + +[Service] +ExecStart=/sbin/plymouthd --mode=shutdown +ExecStartPost=-/bin/plymouth --show-splash +Type=forking diff --git a/units/plymouth-start.service b/units/plymouth-start.service new file mode 100644 index 0000000..f618257 --- /dev/null +++ b/units/plymouth-start.service @@ -0,0 +1,22 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Show Plymouth Boot Screen +DefaultDependencies=no +Wants=systemd-ask-password-plymouth.path +After=systemd-vconsole-setup.service udev-settle.service +Before=systemd-ask-password-plymouth.service + +# Dracut informs us with this flag file if plymouth is already running +ConditionPathExists=!/run/plymouth/pid +ConditionKernelCommandLine=!plymouth.enable=0 + +[Service] +ExecStart=/sbin/plymouthd --mode=boot --pid-file=/run/plymouth/pid +ExecStartPost=-/bin/plymouth --show-splash +Type=forking diff --git a/units/poweroff.service.in b/units/poweroff.service.in new file mode 100644 index 0000000..124a4c0 --- /dev/null +++ b/units/poweroff.service.in @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Power-Off +DefaultDependencies=no +Requires=shutdown.target umount.target final.target +After=shutdown.target umount.target final.target + +[Service] +Type=oneshot +ExecStart=@SYSTEMCTL@ --force poweroff diff --git a/units/poweroff.target b/units/poweroff.target new file mode 100644 index 0000000..d2ccf4b --- /dev/null +++ b/units/poweroff.target @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Power-Off +DefaultDependencies=no +Requires=poweroff.service +After=poweroff.service +AllowIsolate=yes + +[Install] +Alias=ctrl-alt-del.target diff --git a/units/printer.target b/units/printer.target new file mode 100644 index 0000000..14c90ff --- /dev/null +++ b/units/printer.target @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Printer +StopWhenUnneeded=yes diff --git a/units/proc-sys-fs-binfmt_misc.automount b/units/proc-sys-fs-binfmt_misc.automount new file mode 100644 index 0000000..acbbcbb --- /dev/null +++ b/units/proc-sys-fs-binfmt_misc.automount @@ -0,0 +1,15 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Arbitrary Executable File Formats File System Automount Point +DefaultDependencies=no +Before=sysinit.target +ConditionPathExists=/proc/sys/fs/binfmt_misc + +[Automount] +Where=/proc/sys/fs/binfmt_misc diff --git a/units/proc-sys-fs-binfmt_misc.mount b/units/proc-sys-fs-binfmt_misc.mount new file mode 100644 index 0000000..1829c21 --- /dev/null +++ b/units/proc-sys-fs-binfmt_misc.mount @@ -0,0 +1,15 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Arbitrary Executable File Formats File System +DefaultDependencies=no + +[Mount] +What=binfmt_misc +Where=/proc/sys/fs/binfmt_misc +Type=binfmt_misc diff --git a/units/quotacheck.service.in b/units/quotacheck.service.in new file mode 100644 index 0000000..c97b7a4 --- /dev/null +++ b/units/quotacheck.service.in @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=File System Quota Check +DefaultDependencies=no +After=systemd-readahead-collect.service systemd-readahead-replay.service remount-rootfs.service +Before=local-fs.target shutdown.target +ConditionPathExists=/sbin/quotacheck + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-quotacheck +TimeoutSec=0 diff --git a/units/quotaon.service b/units/quotaon.service new file mode 100644 index 0000000..ef2fc8c --- /dev/null +++ b/units/quotaon.service @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Enable File System Quotas +DefaultDependencies=no +After=systemd-readahead-collect.service systemd-readahead-replay.service quotacheck.service +Before=local-fs.target shutdown.target +ConditionPathExists=/sbin/quotaon + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/sbin/quotaon -aug diff --git a/units/reboot.service.in b/units/reboot.service.in new file mode 100644 index 0000000..f320fd8 --- /dev/null +++ b/units/reboot.service.in @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Reboot +DefaultDependencies=no +Requires=shutdown.target umount.target final.target +After=shutdown.target umount.target final.target + +[Service] +Type=oneshot +ExecStart=@SYSTEMCTL@ --force reboot diff --git a/units/reboot.target b/units/reboot.target new file mode 100644 index 0000000..41e133c --- /dev/null +++ b/units/reboot.target @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Reboot +DefaultDependencies=no +Requires=reboot.service +After=reboot.service +AllowIsolate=yes + +[Install] +Alias=ctrl-alt-del.target diff --git a/units/remote-fs-pre.target b/units/remote-fs-pre.target new file mode 100644 index 0000000..8aceb08 --- /dev/null +++ b/units/remote-fs-pre.target @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Remote File Systems (Pre) +After=network.target diff --git a/units/remote-fs.target b/units/remote-fs.target new file mode 100644 index 0000000..a48f87e --- /dev/null +++ b/units/remote-fs.target @@ -0,0 +1,14 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Remote File Systems + +[Install] +WantedBy=multi-user.target diff --git a/units/remount-rootfs.service b/units/remount-rootfs.service new file mode 100644 index 0000000..7b63752 --- /dev/null +++ b/units/remount-rootfs.service @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Remount Root FS +DefaultDependencies=no +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service fsck-root.service +Before=local-fs-pre.target local-fs.target shutdown.target +Wants=local-fs-pre.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/bin/mount / -o remount diff --git a/units/rescue.service.m4 b/units/rescue.service.m4 new file mode 100644 index 0000000..7dd8a22 --- /dev/null +++ b/units/rescue.service.m4 @@ -0,0 +1,43 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Rescue Shell +DefaultDependencies=no +Conflicts=shutdown.target +After=basic.target plymouth-start.service +Before=shutdown.target + +[Service] +Environment=HOME=/root +WorkingDirectory=/root +ExecStartPre=-/bin/plymouth quit +ExecStartPre=-/bin/echo 'Welcome to rescue mode. Use "systemctl default" or ^D to activate default mode.' +m4_ifdef(`TARGET_FEDORA', +`EnvironmentFile=/etc/sysconfig/init +ExecStart=-/bin/bash -c "exec ${SINGLE}"', +m4_ifdef(`TARGET_MANDRIVA', +`EnvironmentFile=/etc/sysconfig/init +ExecStart=-/bin/bash -c "exec ${SINGLE}"', +m4_ifdef(`TARGET_MAGEIA', +`EnvironmentFile=/etc/sysconfig/init +ExecStart=-/bin/bash -c "exec ${SINGLE}"', +m4_ifdef(`TARGET_MEEGO', +`EnvironmentFile=/etc/sysconfig/init +ExecStart=-/bin/bash -c "exec ${SINGLE}"', +`ExecStart=-/sbin/sulogin')))) +ExecStopPost=-/bin/systemctl --fail --no-block default +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/units/rescue.target b/units/rescue.target new file mode 100644 index 0000000..5bf3f8e --- /dev/null +++ b/units/rescue.target @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Rescue Mode +Requires=basic.target rescue.service +After=basic.target rescue.service +AllowIsolate=yes + +[Install] +Alias=kbrequest.target diff --git a/units/rpcbind.target b/units/rpcbind.target new file mode 100644 index 0000000..a5cea8c --- /dev/null +++ b/units/rpcbind.target @@ -0,0 +1,14 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + +[Unit] +Description=RPC Port Mapper diff --git a/units/serial-getty@.service.m4 b/units/serial-getty@.service.m4 new file mode 100644 index 0000000..fc8b57b --- /dev/null +++ b/units/serial-getty@.service.m4 @@ -0,0 +1,50 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Serial Getty on %I +BindTo=dev-%i.device +After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service +m4_ifdef(`TARGET_FEDORA', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_ARCH', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_FRUGALWARE', +After=local.service +)m4_dnl +m4_ifdef(`TARGET_ALTLINUX', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_MANDRIVA', +After=rc-local.service +)m4_dnl +m4_ifdef(`TARGET_MAGEIA', +After=rc-local.service +)m4_dnl + +# If additional gettys are spawned during boot then we should make +# sure that this is synchronized before getty.target, even though +# getty.target didn't actually pull it in. +Before=getty.target + +[Service] +Environment=TERM=vt100 +ExecStart=-/sbin/agetty -s %I 115200,38400,9600 +Restart=always +RestartSec=0 +UtmpIdentifier=%I +TTYPath=/dev/%I +TTYReset=yes +TTYVHangup=yes +KillMode=process +IgnoreSIGPIPE=no + +# Some login implementations ignore SIGTERM, so we send SIGHUP +# instead, to ensure that login terminates cleanly. +KillSignal=SIGHUP diff --git a/units/shutdown.target b/units/shutdown.target new file mode 100644 index 0000000..99a659e --- /dev/null +++ b/units/shutdown.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Shutdown +DefaultDependencies=no +RefuseManualStart=yes diff --git a/units/sigpwr.target b/units/sigpwr.target new file mode 100644 index 0000000..0ca502d --- /dev/null +++ b/units/sigpwr.target @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Power Failure diff --git a/units/smartcard.target b/units/smartcard.target new file mode 100644 index 0000000..28dd2bb --- /dev/null +++ b/units/smartcard.target @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Smart Card +StopWhenUnneeded=yes diff --git a/units/sockets.target b/units/sockets.target new file mode 100644 index 0000000..2296312 --- /dev/null +++ b/units/sockets.target @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Sockets diff --git a/units/sound.target b/units/sound.target new file mode 100644 index 0000000..e53221c --- /dev/null +++ b/units/sound.target @@ -0,0 +1,12 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Sound Card +StopWhenUnneeded=yes diff --git a/units/suse/halt-local.service b/units/suse/halt-local.service new file mode 100644 index 0000000..796012c --- /dev/null +++ b/units/suse/halt-local.service @@ -0,0 +1,20 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=/etc/init.d/halt.local Compatibility +ConditionFileIsExecutable=/etc/init.d/halt.local +DefaultDependencies=no +After=shutdown.target +Before=final.target + +[Service] +Type=oneshot +ExecStart=/etc/init.d/halt.local +TimeoutSec=0 +StandardOutput=tty +RemainAfterExit=yes diff --git a/units/suse/rc-local.service b/units/suse/rc-local.service new file mode 100644 index 0000000..2384a18 --- /dev/null +++ b/units/suse/rc-local.service @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd 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. + +# This unit gets pulled automatically into multi-user.target by +# systemd-rc-local-generator if /etc/init.d/boot.local is executable. +[Unit] +Description=/etc/init.d/boot.local Compatibility +After=network.target + +[Service] +Type=oneshot +ExecStart=/etc/init.d/boot.local +TimeoutSec=0 +RemainAfterExit=yes +SysVStartPriority=99 diff --git a/units/swap.target b/units/swap.target new file mode 100644 index 0000000..26dd261 --- /dev/null +++ b/units/swap.target @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Swap diff --git a/units/sys-fs-fuse-connections.mount b/units/sys-fs-fuse-connections.mount new file mode 100644 index 0000000..0374715 --- /dev/null +++ b/units/sys-fs-fuse-connections.mount @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=FUSE Control File System +DefaultDependencies=no +ConditionPathExists=/sys/fs/fuse/connections +After=systemd-modules-load.service +Before=sysinit.target + +[Mount] +What=fusectl +Where=/sys/fs/fuse/connections +Type=fusectl diff --git a/units/sys-kernel-config.mount b/units/sys-kernel-config.mount new file mode 100644 index 0000000..d6862bf --- /dev/null +++ b/units/sys-kernel-config.mount @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Configuration File System +DefaultDependencies=no +ConditionPathExists=/sys/kernel/config +After=systemd-modules-load.service +Before=sysinit.target + +[Mount] +What=configfs +Where=/sys/kernel/config +Type=configfs diff --git a/units/sys-kernel-debug.mount b/units/sys-kernel-debug.mount new file mode 100644 index 0000000..d9fca1f --- /dev/null +++ b/units/sys-kernel-debug.mount @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Debug File System +DefaultDependencies=no +ConditionPathExists=/sys/kernel/debug +Before=sysinit.target + +[Mount] +What=debugfs +Where=/sys/kernel/debug +Type=debugfs diff --git a/units/sys-kernel-security.mount b/units/sys-kernel-security.mount new file mode 100644 index 0000000..80cd761 --- /dev/null +++ b/units/sys-kernel-security.mount @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Security File System +DefaultDependencies=no +ConditionPathExists=/sys/kernel/security +Before=sysinit.target + +[Mount] +What=securityfs +Where=/sys/kernel/security +Type=securityfs diff --git a/units/sysinit.target b/units/sysinit.target new file mode 100644 index 0000000..eb9a1c7 --- /dev/null +++ b/units/sysinit.target @@ -0,0 +1,15 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=System Initialization +Conflicts=emergency.service emergency.target +Wants=local-fs.target swap.target +After=local-fs.target swap.target emergency.service emergency.target +RefuseManualStart=yes diff --git a/units/syslog.socket b/units/syslog.socket new file mode 100644 index 0000000..1c54857 --- /dev/null +++ b/units/syslog.socket @@ -0,0 +1,39 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Syslog Socket +DefaultDependencies=no +Before=sockets.target syslog.target +Conflicts=shutdown.target +Before=shutdown.target + +# Pull in syslog.target to tell people that /dev/log is now accessible +Wants=syslog.target + +[Socket] +ListenDatagram=/run/systemd/journal/syslog +SocketMode=0666 +PassCredentials=yes +ReceiveBuffer=8M + +# The default syslog implementation should make syslog.service a +# symlink to itself, so that this socket activates the right actual +# syslog service. +# +# Examples: +# +# /etc/systemd/system/syslog.service -> /lib/systemd/system/rsyslog.service +# /etc/systemd/system/syslog.service -> /lib/systemd/system/syslog-ng.service +# +# Best way to achieve that is by adding this to your unit file +# (i.e. to rsyslog.service or syslog-ng.service): +# +# [Install] +# Alias=syslog.service diff --git a/units/syslog.target b/units/syslog.target new file mode 100644 index 0000000..825b26e --- /dev/null +++ b/units/syslog.target @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + +[Unit] +Description=Syslog + +# Avoid that we conflict with shutdown.target, so that we can stay +# until the very end and do not cancel shutdown.target if we should +# hapen to be activated very late. +DefaultDependencies=no diff --git a/units/systemd-ask-password-console.path b/units/systemd-ask-password-console.path new file mode 100644 index 0000000..c3143d1 --- /dev/null +++ b/units/systemd-ask-password-console.path @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Dispatch Password Requests to Console Directory Watch +DefaultDependencies=no +Conflicts=shutdown.target +After=plymouth-start.service +Before=basic.target shutdown.target +ConditionPathExists=!/run/plymouth/pid + +[Path] +DirectoryNotEmpty=/run/systemd/ask-password +MakeDirectory=yes diff --git a/units/systemd-ask-password-console.service.in b/units/systemd-ask-password-console.service.in new file mode 100644 index 0000000..5ff3ed5 --- /dev/null +++ b/units/systemd-ask-password-console.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Dispatch Password Requests to Console +DefaultDependencies=no +Conflicts=shutdown.target +After=plymouth-start.service +Before=shutdown.target +ConditionPathExists=!/run/plymouth/pid + +[Service] +ExecStart=@rootbindir@/systemd-tty-ask-password-agent --watch --console diff --git a/units/systemd-ask-password-plymouth.path b/units/systemd-ask-password-plymouth.path new file mode 100644 index 0000000..06a5876 --- /dev/null +++ b/units/systemd-ask-password-plymouth.path @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Forward Password Requests to Plymouth Directory Watch +DefaultDependencies=no +Conflicts=shutdown.target +After=plymouth-start.service +Before=basic.target shutdown.target +ConditionKernelCommandLine=!plymouth.enable=0 +ConditionPathExists=/run/plymouth/pid + +[Path] +DirectoryNotEmpty=/run/systemd/ask-password +MakeDirectory=yes diff --git a/units/systemd-ask-password-plymouth.service.in b/units/systemd-ask-password-plymouth.service.in new file mode 100644 index 0000000..92cbfdb --- /dev/null +++ b/units/systemd-ask-password-plymouth.service.in @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Forward Password Requests to Plymouth +DefaultDependencies=no +Conflicts=shutdown.target +After=plymouth-start.service +Before=shutdown.target +ConditionKernelCommandLine=!plymouth.enable=0 +ConditionPathExists=/run/plymouth/pid + +[Service] +ExecStart=@rootbindir@/systemd-tty-ask-password-agent --watch --plymouth diff --git a/units/systemd-ask-password-wall.path b/units/systemd-ask-password-wall.path new file mode 100644 index 0000000..050b73b --- /dev/null +++ b/units/systemd-ask-password-wall.path @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Forward Password Requests to Wall Directory Watch +DefaultDependencies=no +Conflicts=shutdown.target +Before=basic.target shutdown.target + +[Path] +DirectoryNotEmpty=/run/systemd/ask-password +MakeDirectory=yes diff --git a/units/systemd-ask-password-wall.service.in b/units/systemd-ask-password-wall.service.in new file mode 100644 index 0000000..71ec1d6 --- /dev/null +++ b/units/systemd-ask-password-wall.service.in @@ -0,0 +1,15 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Forward Password Requests to Wall +After=systemd-user-sessions.service + +[Service] +ExecStartPre=-@rootbindir@/systemctl stop systemd-ask-password-console.path systemd-ask-password-console.service +ExecStartPre=-@rootbindir@/systemctl stop systemd-ask-password-plymouth.path systemd-ask-password-plymouth.service +ExecStart=@rootbindir@/systemd-tty-ask-password-agent --wall diff --git a/units/systemd-binfmt.service.in b/units/systemd-binfmt.service.in new file mode 100644 index 0000000..d43497c --- /dev/null +++ b/units/systemd-binfmt.service.in @@ -0,0 +1,22 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Set Up Additional Binary Formats +DefaultDependencies=no +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service proc-sys-fs-binfmt_misc.automount +Before=sysinit.target shutdown.target +ConditionDirectoryNotEmpty=|/usr/lib/binfmt.d +ConditionDirectoryNotEmpty=|/usr/local/lib/binfmt.d +ConditionDirectoryNotEmpty=|/etc/binfmt.d +ConditionDirectoryNotEmpty=|/run/binfmt.d + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-binfmt diff --git a/units/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in new file mode 100644 index 0000000..6efab1e --- /dev/null +++ b/units/systemd-hostnamed.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Hostname Service + +[Service] +ExecStart=@rootlibexecdir@/systemd-hostnamed +Type=dbus +BusName=org.freedesktop.hostname1 +CapabilityBoundingSet=CAP_SYS_ADMIN diff --git a/units/systemd-initctl.service.in b/units/systemd-initctl.service.in new file mode 100644 index 0000000..7df3aa6 --- /dev/null +++ b/units/systemd-initctl.service.in @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=/dev/initctl Compatibility Daemon +DefaultDependencies=no + +[Service] +ExecStart=@rootlibexecdir@/systemd-initctl +NotifyAccess=all diff --git a/units/systemd-initctl.socket b/units/systemd-initctl.socket new file mode 100644 index 0000000..7a3a023 --- /dev/null +++ b/units/systemd-initctl.socket @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=/dev/initctl Compatibility Named Pipe +DefaultDependencies=no +Before=sockets.target + +[Socket] +ListenFIFO=/dev/initctl +SocketMode=0600 diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in new file mode 100644 index 0000000..92606b0 --- /dev/null +++ b/units/systemd-journald.service.in @@ -0,0 +1,25 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Journal Service +DefaultDependencies=no +Requires=systemd-journald.socket +After=systemd-journald.socket +After=syslog.socket + +[Service] +ExecStart=@rootlibexecdir@/systemd-journald +NotifyAccess=all +StandardOutput=null +CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID + +# Increase the default a bit in order to allow many simultaneous +# services being run since we keep one fd open per service. +LimitNOFILE=16384 diff --git a/units/systemd-journald.socket b/units/systemd-journald.socket new file mode 100644 index 0000000..c752505 --- /dev/null +++ b/units/systemd-journald.socket @@ -0,0 +1,26 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Journal Socket +DefaultDependencies=no +Before=sockets.target syslog.target + +# Mount and swap units need this. If this socket unit is removed by an +# isolate request the mount and and swap units would be removed too, +# hence let's exclude this from isolate requests. +IgnoreOnIsolate=yes + +[Socket] +ListenStream=/run/systemd/journal/stdout +ListenDatagram=/run/systemd/journal/socket +ListenDatagram=/dev/log +SocketMode=0666 +PassCredentials=yes +ReceiveBuffer=8M diff --git a/units/systemd-localed.service.in b/units/systemd-localed.service.in new file mode 100644 index 0000000..4be65df --- /dev/null +++ b/units/systemd-localed.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Locale Service + +[Service] +ExecStart=@rootlibexecdir@/systemd-localed +Type=dbus +BusName=org.freedesktop.locale1 +CapabilityBoundingSet= diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in new file mode 100644 index 0000000..531b8f7 --- /dev/null +++ b/units/systemd-logind.service.in @@ -0,0 +1,21 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Login Service + +[Service] +ExecStart=@rootlibexecdir@/systemd-logind +Type=dbus +BusName=org.freedesktop.login1 +CapabilityBoundingSet=CAP_AUDIT_CONTROL CAP_CHOWN CAP_KILL CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_FOWNER CAP_SYS_TTY_CONFIG + +# Increase the default a bit in order to allow many simultaneous +# logins since we keep one fd open per session. +LimitNOFILE=16384 diff --git a/units/systemd-modules-load.service.in b/units/systemd-modules-load.service.in new file mode 100644 index 0000000..5dc373d --- /dev/null +++ b/units/systemd-modules-load.service.in @@ -0,0 +1,23 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Load Kernel Modules +DefaultDependencies=no +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service +Before=sysinit.target shutdown.target +ConditionDirectoryNotEmpty=|/lib/modules-load.d +ConditionDirectoryNotEmpty=|/usr/lib/modules-load.d +ConditionDirectoryNotEmpty=|/usr/local/lib/modules-load.d +ConditionDirectoryNotEmpty=|/etc/modules-load.d +ConditionDirectoryNotEmpty=|/run/modules-load.d + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-modules-load diff --git a/units/systemd-random-seed-load.service.in b/units/systemd-random-seed-load.service.in new file mode 100644 index 0000000..a2b6a55 --- /dev/null +++ b/units/systemd-random-seed-load.service.in @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Load Random Seed +DefaultDependencies=no +Wants=local-fs.target +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target +Before=sysinit.target shutdown.target + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-random-seed load diff --git a/units/systemd-random-seed-save.service.in b/units/systemd-random-seed-save.service.in new file mode 100644 index 0000000..9a074cf --- /dev/null +++ b/units/systemd-random-seed-save.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Save Random Seed +DefaultDependencies=no +After=systemd-random-seed-load.service +Before=shutdown.target +Conflicts=systemd-random-seed-load.service + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-random-seed save diff --git a/units/systemd-readahead-collect.service.in b/units/systemd-readahead-collect.service.in new file mode 100644 index 0000000..56ba54f --- /dev/null +++ b/units/systemd-readahead-collect.service.in @@ -0,0 +1,22 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Collect Read-Ahead Data +DefaultDependencies=no +Wants=systemd-readahead-done.timer +Conflicts=shutdown.target +Before=sysinit.target shutdown.target + +[Service] +Type=notify +ExecStart=@rootlibexecdir@/systemd-readahead-collect +RemainAfterExit=yes +StandardOutput=null + +[Install] +WantedBy=default.target diff --git a/units/systemd-readahead-done.service.in b/units/systemd-readahead-done.service.in new file mode 100644 index 0000000..d665e45 --- /dev/null +++ b/units/systemd-readahead-done.service.in @@ -0,0 +1,20 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Stop Read-Ahead Data Collection +DefaultDependencies=no +Conflicts=shutdown.target +After=default.target +Before=shutdown.target + +[Service] +Type=oneshot +ExecStart=@SYSTEMD_NOTIFY@ --readahead=done + +[Install] +Also=systemd-readahead-collect.service diff --git a/units/systemd-readahead-done.timer b/units/systemd-readahead-done.timer new file mode 100644 index 0000000..d144bfa --- /dev/null +++ b/units/systemd-readahead-done.timer @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Stop Read-Ahead Data Collection 10s After Completed Startup +DefaultDependencies=no +Conflicts=shutdown.target +After=default.target +Before=shutdown.target + +[Timer] +OnActiveSec=10s + +[Install] +Also=systemd-readahead-collect.service diff --git a/units/systemd-readahead-replay.service.in b/units/systemd-readahead-replay.service.in new file mode 100644 index 0000000..7c82e40 --- /dev/null +++ b/units/systemd-readahead-replay.service.in @@ -0,0 +1,22 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Replay Read-Ahead Data +DefaultDependencies=no +Conflicts=shutdown.target +Before=sysinit.target shutdown.target +ConditionPathExists=/.readahead + +[Service] +Type=notify +ExecStart=@rootlibexecdir@/systemd-readahead-replay +RemainAfterExit=yes +StandardOutput=null + +[Install] +WantedBy=default.target diff --git a/units/systemd-remount-api-vfs.service.in b/units/systemd-remount-api-vfs.service.in new file mode 100644 index 0000000..f4df0ca --- /dev/null +++ b/units/systemd-remount-api-vfs.service.in @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Remount API VFS +DefaultDependencies=no +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service +Before=local-fs-pre.target local-fs.target shutdown.target +Wants=local-fs-pre.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-remount-api-vfs diff --git a/units/systemd-shutdownd.service.in b/units/systemd-shutdownd.service.in new file mode 100644 index 0000000..657365a --- /dev/null +++ b/units/systemd-shutdownd.service.in @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Delayed Shutdown Service +DefaultDependencies=no + +[Service] +ExecStart=@rootlibexecdir@/systemd-shutdownd +NotifyAccess=all diff --git a/units/systemd-shutdownd.socket b/units/systemd-shutdownd.socket new file mode 100644 index 0000000..532a6f0 --- /dev/null +++ b/units/systemd-shutdownd.socket @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Delayed Shutdown Socket +DefaultDependencies=no +Before=sockets.target + +[Socket] +ListenDatagram=/run/systemd/shutdownd +SocketMode=0600 +PassCredentials=yes diff --git a/units/systemd-sysctl.service.in b/units/systemd-sysctl.service.in new file mode 100644 index 0000000..6d53422 --- /dev/null +++ b/units/systemd-sysctl.service.in @@ -0,0 +1,24 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Apply Kernel Variables +DefaultDependencies=no +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service +Before=sysinit.target shutdown.target +ConditionPathExists=|/etc/sysctl.conf +ConditionDirectoryNotEmpty=|/lib/sysctl.d +ConditionDirectoryNotEmpty=|/usr/lib/sysctl.d +ConditionDirectoryNotEmpty=|/usr/local/lib/sysctl.d +ConditionDirectoryNotEmpty=|/etc/sysctl.d +ConditionDirectoryNotEmpty=|/run/sysctl.d + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-sysctl diff --git a/units/systemd-timedated.service.in b/units/systemd-timedated.service.in new file mode 100644 index 0000000..90ff443 --- /dev/null +++ b/units/systemd-timedated.service.in @@ -0,0 +1,17 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Time & Date Service + +[Service] +ExecStart=@rootlibexecdir@/systemd-timedated +Type=dbus +BusName=org.freedesktop.timedate1 +CapabilityBoundingSet=CAP_SYS_TIME diff --git a/units/systemd-tmpfiles-clean.service.in b/units/systemd-tmpfiles-clean.service.in new file mode 100644 index 0000000..3c8e72e --- /dev/null +++ b/units/systemd-tmpfiles-clean.service.in @@ -0,0 +1,22 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Cleanup of Temporary Directories +DefaultDependencies=no +Wants=local-fs.target +After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target +Before=sysinit.target shutdown.target +ConditionDirectoryNotEmpty=|/usr/lib/tmpfiles.d +ConditionDirectoryNotEmpty=|/usr/local/lib/tmpfiles.d +ConditionDirectoryNotEmpty=|/etc/tmpfiles.d +ConditionDirectoryNotEmpty=|/run/tmpfiles.d + +[Service] +Type=oneshot +ExecStart=@rootbindir@/systemd-tmpfiles --clean +IOSchedulingClass=idle diff --git a/units/systemd-tmpfiles-clean.timer b/units/systemd-tmpfiles-clean.timer new file mode 100644 index 0000000..d8529a8 --- /dev/null +++ b/units/systemd-tmpfiles-clean.timer @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Daily Cleanup of Temporary Directories + +[Timer] +OnBootSec=15min +OnUnitActiveSec=1d diff --git a/units/systemd-tmpfiles-setup.service.in b/units/systemd-tmpfiles-setup.service.in new file mode 100644 index 0000000..f90121e --- /dev/null +++ b/units/systemd-tmpfiles-setup.service.in @@ -0,0 +1,22 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Recreate Volatile Files and Directories +DefaultDependencies=no +Wants=local-fs.target +After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target +Before=sysinit.target shutdown.target +ConditionDirectoryNotEmpty=|/usr/lib/tmpfiles.d +ConditionDirectoryNotEmpty=|/usr/local/lib/tmpfiles.d +ConditionDirectoryNotEmpty=|/etc/tmpfiles.d +ConditionDirectoryNotEmpty=|/run/tmpfiles.d + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootbindir@/systemd-tmpfiles --create --remove diff --git a/units/systemd-update-utmp-runlevel.service.in b/units/systemd-update-utmp-runlevel.service.in new file mode 100644 index 0000000..614c759 --- /dev/null +++ b/units/systemd-update-utmp-runlevel.service.in @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Notify Audit System and Update UTMP about System Runlevel Changes +DefaultDependencies=no +After=local-fs.target sysinit.target auditd.service runlevel1.target runlevel2.target runlevel3.target runlevel4.target runlevel5.target systemd-tmpfiles-setup.service +Before=poweroff.service reboot.service halt.service + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-update-utmp runlevel diff --git a/units/systemd-update-utmp-shutdown.service.in b/units/systemd-update-utmp-shutdown.service.in new file mode 100644 index 0000000..e7c3c04 --- /dev/null +++ b/units/systemd-update-utmp-shutdown.service.in @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Notify Audit System and Update UTMP about System Shutdown +DefaultDependencies=no +After=local-fs.target sysinit.target auditd.service systemd-update-utmp-runlevel.service +Before=poweroff.service reboot.service halt.service + +[Service] +Type=oneshot +ExecStart=@rootlibexecdir@/systemd-update-utmp shutdown diff --git a/units/systemd-user-sessions.service.in b/units/systemd-user-sessions.service.in new file mode 100644 index 0000000..a93d586 --- /dev/null +++ b/units/systemd-user-sessions.service.in @@ -0,0 +1,16 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Permit User Sessions +After=local-fs.target remote-fs.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-user-sessions start +ExecStop=@rootlibexecdir@/systemd-user-sessions stop diff --git a/units/systemd-vconsole-setup.service.in b/units/systemd-vconsole-setup.service.in new file mode 100644 index 0000000..673fb6c --- /dev/null +++ b/units/systemd-vconsole-setup.service.in @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Setup Virtual Console +DefaultDependencies=no +Conflicts=shutdown.target +After=systemd-readahead-collect.service systemd-readahead-replay.service +Before=sysinit.target shutdown.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@rootlibexecdir@/systemd-vconsole-setup diff --git a/units/time-sync.target b/units/time-sync.target new file mode 100644 index 0000000..aa34ecb --- /dev/null +++ b/units/time-sync.target @@ -0,0 +1,14 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +# This exists mostly for compatibility with SysV/LSB units, and +# implementations lacking socket/bus activation. + +[Unit] +Description=System Time Synchronized diff --git a/units/umount.target b/units/umount.target new file mode 100644 index 0000000..b9ecca6 --- /dev/null +++ b/units/umount.target @@ -0,0 +1,13 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Unmount All Filesystems +DefaultDependencies=no +RefuseManualStart=yes diff --git a/units/user/default.target b/units/user/default.target new file mode 100644 index 0000000..deb310c --- /dev/null +++ b/units/user/default.target @@ -0,0 +1,11 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Default diff --git a/units/user/exit.service.in b/units/user/exit.service.in new file mode 100644 index 0000000..a20b089 --- /dev/null +++ b/units/user/exit.service.in @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Exit the Session +DefaultDependencies=no +Requires=shutdown.target +After=shutdown.target + +[Service] +Type=oneshot +ExecStart=@SYSTEMCTL@ --user --force exit diff --git a/units/user/exit.target b/units/user/exit.target new file mode 100644 index 0000000..f34844c --- /dev/null +++ b/units/user/exit.target @@ -0,0 +1,18 @@ +# This file is part of systemd. +# +# systemd 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. + +# See systemd.special(7) for details + +[Unit] +Description=Exit the Session +DefaultDependencies=no +Requires=exit.service +After=exit.service +AllowIsolate=yes + +[Install] +Alias=ctrl-alt-del.target diff --git a/units/user@.service.in b/units/user@.service.in new file mode 100644 index 0000000..91e3b25 --- /dev/null +++ b/units/user@.service.in @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=User Manager for %I +After=systemd-user-sessions.service + +[Service] +User=%I +PAMName=systemd-shared +ControlGroup=%R/user/%I/shared cpu:/ +ControlGroupModify=yes +Type=notify +ExecStart=-@rootlibexecdir@/systemd --user +Environment=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%I/dbus/user_bus_socket diff --git a/units/var-lock.mount b/units/var-lock.mount new file mode 100644 index 0000000..07277ad --- /dev/null +++ b/units/var-lock.mount @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Lock Directory +Before=local-fs.target +# skip mounting if the directory does not exist or is a symlink +ConditionPathIsDirectory=/var/lock +ConditionPathIsSymbolicLink=!/var/lock + +[Mount] +What=/run/lock +Where=/var/lock +Type=bind +Options=bind diff --git a/units/var-run.mount b/units/var-run.mount new file mode 100644 index 0000000..ab4da42 --- /dev/null +++ b/units/var-run.mount @@ -0,0 +1,19 @@ +# This file is part of systemd. +# +# systemd 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. + +[Unit] +Description=Runtime Directory +Before=local-fs.target +# skip mounting if the directory does not exist or is a symlink +ConditionPathIsDirectory=/var/run +ConditionPathIsSymbolicLink=!/var/run + +[Mount] +What=/run +Where=/var/run +Type=bind +Options=bind