diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..f27f198
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+github: thodg
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..0535628
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,591 @@
+# Adams license information
+
+Adams - UNIX system administration tool written in Common Lisp
+Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
+
+
+## Adams dependencies license information
+
+### SBCL
+
+Steel Bank Common Lisp (SBCL) is free software, and comes with
+absolutely no warranty.
+
+SBCL is derived from CMU CL, which was released into the public
+domain, subject only to the BSD-style "free, but credit must be given
+and copyright notices must be retained" licenses in the LOOP macro
+(from MIT and Symbolics) and in the PCL implementation of CLOS (from
+Xerox).
+
+After CMU CL was released into the public domain, it was maintained by
+volunteers, who continued the tradition of releasing their work into
+the public domain.
+
+All changes to SBCL since the fork from CMU CL have been released into
+the public domain in jurisdictions where this is possible, or under
+the FreeBSD licence where not.
+
+The CityHash mix function as adapted in hopscotch.c has an MIT license.
+
+Thus, there are no known obstacles to copying, using, and modifying
+SBCL freely, as long as copyright notices of MIT, Symbolics, Xerox and
+Gerd Moellmann are retained.
+
+Portions of LOOP are Copyright (c) 1986 by the Massachusetts Institute
+of Technology. All Rights Reserved.
+
+Permission to use, copy, modify and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the M.I.T. copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. The names "M.I.T." and "Massachusetts
+Institute of Technology" may not be used in advertising or publicity
+pertaining to distribution of the software without specific, written
+prior permission. Notice must be given in supporting documentation that
+copying distribution is by permission of M.I.T. M.I.T. makes no
+representations about the suitability of this software for any purpose.
+It is provided "as is" without express or implied warranty.
+
+ Massachusetts Institute of Technology
+ 77 Massachusetts Avenue
+ Cambridge, Massachusetts 02139
+
+Portions of LOOP are Copyright (c) 1989, 1990, 1991, 1992 by Symbolics,
+Inc. All Rights Reserved.
+
+Permission to use, copy, modify and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the Symbolics copyright notice appear in all copies and
+that both that copyright notice and this permission notice appear in
+supporting documentation. The name "Symbolics" may not be used in
+advertising or publicity pertaining to distribution of the software
+without specific, written prior permission. Notice must be given in
+supporting documentation that copying distribution is by permission of
+Symbolics. Symbolics makes no representations about the suitability of
+this software for any purpose. It is provided "as is" without express
+or implied warranty.
+
+Symbolics, CLOE Runtime, and Minima are trademarks, and CLOE, Genera,
+and Zetalisp are registered trademarks of Symbolics, Inc.
+
+ Symbolics, Inc.
+ 8 New England Executive Park, East
+ Burlington, Massachusetts 01803
+
+copyright information from original PCL sources:
+
+Copyright (c) 1985, 1986, 1987, 1988, 1989, 1990 Xerox Corporation.
+All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export
+control laws.
+
+This software is made available AS IS, and Xerox Corporation makes no
+warranty about the software, its performance or its conformity to any
+specification.
+
+Copyright (C) 2002 Gerd Moellmann <gerd.moellmann@t-online.de>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+
+### Alexandria
+
+Alexandria software and associated documentation are in the public
+domain:
+
+ Authors dedicate this work to public domain, for the benefit of the
+ public at large and to the detriment of the authors' heirs and
+ successors. Authors intends this dedication to be an overt act of
+ relinquishment in perpetuity of all present and future rights under
+ copyright law, whether vested or contingent, in the work. Authors
+ understands that such relinquishment of all rights includes the
+ relinquishment of all rights to enforce (by lawsuit or otherwise)
+ those copyrights in the work.
+
+ Authors recognize that, once placed in the public domain, the work
+ may be freely reproduced, distributed, transmitted, used, modified,
+ built upon, or otherwise exploited by anyone for any purpose,
+ commercial or non-commercial, and in any way, including by methods
+ that have not yet been invented or conceived.
+
+In those legislations where public domain dedications are not
+recognized or possible, Alexandria is distributed under the following
+terms and conditions:
+
+ 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 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.
+
+
+### cl-ppcre
+
+Copyright (c) 2002-2009, Dr. Edmund Weitz. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+### cl-unicode
+
+Copyright (c) 2008-2012, Dr. Edmund Weitz. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+### named-readtables
+
+Copyright (c) 2007 - 2009 Tobias C. Rittweiler <tcr@freebits.de>
+Copyright (c) 2007, Robert P. Goldman <rpgoldman@sift.info> and SIFT, LLC
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+ * Neither the names of Tobias C. Rittweiler, Robert P. Goldman,
+ SIFT, LLC nor the names of its contributors may be used to
+ endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY Tobias C. Rittweiler, Robert
+P. Goldman and SIFT, LLC ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL Tobias C. Rittweiler, Robert
+P. Goldman or SIFT, LLC BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+### cl-interpol
+
+Copyright (c) 2003-2008, Dr. Edmund Weitz. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+### bordeaux-threads
+
+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.
+
+
+### cl-fad
+
+Copyright (c) 2004, Peter Seibel. All rights reserved.
+Copyright (c) 2004-2010, Dr. Edmund Weitz. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS 'AS IS' AND ANY EXPRESSED
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+### local-time
+
+local-time Copyright (c) 2005-2012 by Daniel Lowe
+
+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.
+
+
+### parse-number
+
+Author: Matthew Danish -- mrd.debian.org
+
+Copyright 2002 Matthew Danish.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of the author nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+
+### chronicity
+
+Copyright (c) 2009-2016 Chaitanya Gupta
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+### cl-base64
+
+Copyright (c) 2002-2003 by Kevin Rosenberg
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the Authors may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+### cl-debug
+
+Copyright 2014 LowH <code@lowh.net>
+
+Permission to use, copy, modify, and distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+### closer-mop
+
+Copyright (c) 2005 - 2016 Pascal Costanza
+
+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.
+
+
+### nibbles
+
+Copyright (c) 2010, Nathan Froyd
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* Neither the name of the copyright holders nor the names of
+ contributors to this software may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
+IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+### ironclad
+
+Copyright (c) 2004-2008, Nathan Froyd
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* Neither the name of the copyright holders nor the names of
+ contributors to this software may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
+IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+### trivial-utf-8
+
+Copyright (c) Marijn Haverbeke
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+ distribution.
diff --git a/Makefile b/Makefile
index 81d592b..4f8385d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,18 +1,46 @@
+## Adams - UNIX system administration tool written in Common Lisp
+## Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
+PACKAGE = adams
+VERSION = 0.3.2
+RELEASE_DIR = ${PACKAGE}-${VERSION}
+RELEASE_TARBALL = ${PACKAGE}-${VERSION}.tar.gz
+RELEASE_DEPS_TARBALL = ${PACKAGE}-${VERSION}.deps.tar.gz
PROGRAM = build/adams
PREFIX = /usr/local
-LISP = sbcl
+LISP = sbcl --dynamic-space-size 2048
LISP_LOAD = ${LISP} --load
+CLEANFILES = build/*
+DISTCLEANFILES = ${RELEASE_DIR} ${RELEASE_TARBALL} ${RELEASE_DEPS_TARBALL}
all: ${PROGRAM}
-${PROGRAM}: build.lisp
- LANG=C.UTF-8 ${LISP_LOAD} build.lisp
+deps:
+ LANG=C.UTF-8 ${LISP_LOAD} prepare-build.lisp --quit
-clean:
- rm -rf build/*
+build/systems.lisp: prepare-build.lisp adams.asd
+ LANG=C.UTF-8 ${LISP_LOAD} prepare-build.lisp --quit
+
+${PROGRAM}: build.lisp config.lisp build/systems.lisp toplevel.lisp
+ LANG=C.UTF-8 ${LISP_LOAD} build.lisp --quit
-install: ${PROGRAM}
+install:
install -m 0755 ${PROGRAM} ${PREFIX}/bin
-.PHONY: all clean install ${PROGRAM}
+release: ${RELEASE_TARBALL} ${RELEASE_DEPS_TARBALL}
+
+${RELEASE_TARBALL}:
+ mkdir ${RELEASE_DIR}
+ find . -name build -prune -or -name '*.lisp' -or -name '*.asd' -or -name '*.md' | cpio -pd ${RELEASE_DIR}
+ tar czf ${RELEASE_TARBALL} ${RELEASE_DIR}
+
+${RELEASE_DEPS_TARBALL}:
+ tar czf ${RELEASE_DEPS_TARBALL} build/*.lisp
+
+clean:
+ rm -rf ${CLEANFILES}
+
+distclean:
+ rm -rf ${DISTCLEANFILES}
+
+.PHONY: all clean deps install ${PROGRAM} release
diff --git a/README.md b/README.md
index 28fc81b..3408ef9 100644
--- a/README.md
+++ b/README.md
@@ -1,28 +1,39 @@
-Adams
-=====
+Adams 0.3.2
+===========
-Adams is our new cybernetic DevOps. Please welcome him and make him feel
-at home, I hope he will find a nice place to work amongst us. So far he's
-been a brilliant student though a bit dumb and formal, I hope he will find
-a warm and welcoming place in our hearts.
-For the next months he will remain in formation so if you would please
-consider handing him any rookie task you might have he shall gladly take
-them upon him and will probably crash the system and need your help to fix it
-but, hey, that's what unpaid interns are for, right ?
+Adams is a UNIX system administration tool written in Common Lisp.
+
+You describe your systems (hosts) using resources having properties.
+
+The properties are then probed and synchronized by Adams using only
+`/bin/sh` on the remote host, and `/usr/bin/ssh` on the control host.
+
+
+Configuration example
+---------------------
+
+Check out
+<https://github.com/kmx-io/kmx-io/>
+for a detailed example of Adams usage.
Current status
--------------
-Adams is currently able to use a local shell or connect to remote hosts via
-ssh.
-He is quite the hardcore hacker wannabe using only /bin/sh though ksh and
-bash suit him fine too.
-He's still green but he can already gather basic information about users,
-groups and files.
+Adams is currently able to use a local shell or connect to remote hosts
+via ssh.
-We are currently teaching him about new kinds of resources and how to read
-resource specification manifests.
+Adams is this hardcore hacker using only `/bin/sh` commands.
+This makes `ksh` and `bash` suitable shells for adams as they are
+compatible with `/bin/sh`.
+
+Supported resource types :
+ - Host (hostname)
+ - User (useradd, usermod, userdel)
+ - Group (groupadd, groupmod, groupdel)
+ - File (owner, group, permissions, content)
+ - Directory (owner, group, permissions)
+ - Package (Debian, OpenBSD)
Security design
@@ -47,16 +58,16 @@ Usage
### 1. Install [repo](https://github.com/common-lisp-repo/repo).
-### 2. Install adams
+### 2. Fetch adams sources.
-```
+``` shell
$ sbcl --eval '(repo:install :adams)'
```
-### 3. Build and install adams binary
+### 3. Build and install the `adams` binary
-```
+``` shell
$ cd ~/common-lisp/cl-adams/adams
$ make
$ sudo cp build/adams /usr/local/bin/adams
@@ -66,7 +77,7 @@ Usage
### 4. Configure emacs (optional)
In your `~/.emacs` file :
-```
+``` emacs-lisp
;; Adams
(add-to-list 'auto-mode-alist '("\\.adams\\'" . lisp-mode))
```
@@ -75,7 +86,7 @@ In your `~/.emacs` file :
### 5. Write some resources in a `.adams` script
In the `tutorial.adams` file :
-```
+``` common-lisp
#!/usr/local/bin/adams --script
(resource 'host "adams.kmx.io"
@@ -91,7 +102,7 @@ In the `tutorial.adams` file :
### 6. Profit.
-```
+``` shell
$ chmod 755 tutorial.adams
$ ./tutorial.adams
```
@@ -103,7 +114,7 @@ according to the resource specifications given in the file.
### 7. DRY up your scripts using `#.(include "file")`
In the `user/dx.adams` file :
-```
+``` common-lisp
;; Thomas de Grivel (kmx.io)
(resource 'group "dx"
:gid 19256
@@ -129,3 +140,13 @@ In your main script :
(with-host "adams.kmx.io"
(sync *host*))
```
+
+
+[License](LICENSE.md)
+---------------------
+
+
+Authors
+-------
+
+Thomas de Grivel <thodg@kmx.io>
diff --git a/adams.asd b/adams.asd
index d6590f8..00eab78 100644
--- a/adams.asd
+++ b/adams.asd
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(defpackage :adams.system
(:use :cl :asdf))
@@ -67,6 +52,7 @@
(:file "linux" :depends-on ("commands" "defs"))
(:file "openbsd" :depends-on ("commands" "defs"))
(:file "freebsd" :depends-on ("commands" "defs"))
+ (:file "darwin" :depends-on ("commands" "defs"))
(:file "operations" :depends-on ("commands" "defs"))
(:file "probes" :depends-on ("commands" "defs"
"stat" "syntaxes"))
diff --git a/build.lisp b/build.lisp
index 36e8848..5f38baf 100644
--- a/build.lisp
+++ b/build.lisp
@@ -1,182 +1,29 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :common-lisp-user)
-(defgeneric collect-sources (x))
-
-(defmethod collect-sources ((x symbol))
- (collect-sources (asdf:find-system x)))
-
-(defmethod collect-sources ((x string))
- (collect-sources (asdf:find-system x)))
-
-(defun sort-components (list)
- (declare (type list list))
- (let (components roots)
- (declare (type list components roots))
- (labels ((map-dependencies (comp fn)
- (declare (type asdf:component comp))
- (dolist (id (asdf:component-sideway-dependencies comp))
- (let ((dep (find id list :test #'string=
- :key #'asdf:component-name)))
- (when dep
- (funcall (the function fn) dep)))))
- (dfs (comp)
- (declare (type asdf:component comp))
- (map-dependencies comp #'dfs)
- (pushnew comp components)))
- (dolist (comp list)
- (declare (type asdf:component comp))
- (pushnew comp roots))
- (dolist (comp list)
- (declare (type asdf:component comp))
- (map-dependencies comp (lambda (dep)
- (setf roots (delete dep roots)))))
- (dolist (comp roots)
- (dfs comp)))
- (nreverse components)))
-
-(defmethod collect-sources ((x asdf:parent-component))
- (let ((children (sort-components (asdf:component-children x))))
- (mapcan #'collect-sources children)))
-
-(defmethod collect-sources ((req asdf:require-system))
- (list `(require ,(string-upcase (asdf:component-name req)))))
-
-(defmethod collect-sources ((x asdf:cl-source-file))
- (list `(compile-lisp ,(asdf:component-pathname x))))
-
-(defmethod collect-sources ((x asdf:file-component))
- (list `(quote ,(asdf:component-pathname x))))
-
-(defmethod collect-sources :around ((x asdf:component))
- (let ((if-feature (asdf::component-if-feature x)))
- (if if-feature
- (when (find (the symbol if-feature) *features*)
- (call-next-method))
- (call-next-method))))
-
-#+nil (collect-sources :adams)
-
-(defvar *system-directory*
- (make-hash-table))
-
-(defun system-directory (system)
- (or #1=(gethash system *system-directory*)
- (let* ((sys (typecase system (asdf:system system)
- (t (asdf:find-system system))))
- (asd (asdf:system-source-file sys)))
- (setf #1#
- (make-pathname :name nil :type nil :defaults asd)))))
-
-(defun system-file (system &rest parts)
- (let ((str (apply #'concatenate 'string parts)))
- (merge-pathnames str (system-directory system))))
-
-(defun namestring* (x)
- (etypecase x
- (null "")
- (pathname (namestring x))
- (string x)))
-
-(defparameter *dir* (namestring* (system-file :adams "")))
+(declaim (optimize (speed 1)
+ (space 1)
+ (safety 3)
+ (debug 3)
+ (compilation-speed 0)))
(defun compile-lisp (path)
- (let* ((adams-dir *dir*)
- (dir (pathname-directory path))
- (name (pathname-name path))
- (fasl (with-output-to-string (out)
- (write-string adams-dir out)
- (write-string "build/" out)
- (dolist (d (rest dir))
- (write-string d out)
- (write-char #\- out))
- (write-string name out)
- (write-string ".fasl" out))))
- (print fasl)
- (unless (and (probe-file fasl)
- (<= (file-write-date path)
- (file-write-date fasl)))
- (print path)
- (ensure-directories-exist fasl)
- (compile-file path :output-file fasl))
- (load fasl)))
-
-(defun write-system-build-file (system sbf)
- (format t "~&~A~%" sbf) (force-output)
- (with-open-file (out sbf :direction :output
- :element-type 'character
- :if-exists :supersede
- :if-does-not-exist :create
- :external-format :utf-8)
- (declare (type stream out))
- (format out "~&;; ~A" (asdf:component-name system))
- (dolist (src (collect-sources system))
- (print src out))))
-
-(defun system-build-file (system)
- (let* ((adams-dir *dir*)
- (asd (asdf:system-source-file system))
- (name (substitute #\- #\/ (asdf:component-name system)))
- (sbf (concatenate 'string adams-dir "build/" name ".lisp")))
- (unless (and (probe-file sbf)
- (<= (file-write-date asd)
- (file-write-date sbf)))
- (write-system-build-file system sbf))
- sbf))
-
-(defun system-and-dependencies (name)
- (let (dependencies)
- (labels ((dfs (name)
- (let ((sys (asdf:find-system name)))
- (when sys
- (locally (declare (type asdf:system sys))
- (map 'nil #'dfs (asdf:system-depends-on sys))
- (pushnew sys dependencies))))))
- (dfs name)
- (nreverse dependencies))))
-
-(defun write-build-systems-file (system)
- (unless (typep system 'asdf:system)
- (setq system (asdf:find-system system)))
- (let* ((path (system-file system "build/systems.lisp")))
- (print path) (force-output)
- (ensure-directories-exist path)
- (with-open-file (out path :direction :output
- :element-type 'character
- :external-format :utf-8
- :if-exists :supersede
- :if-does-not-exist :create)
- (declare (type stream out))
- (dolist (sys (system-and-dependencies system))
- (let* ((build-file (system-build-file sys))
- (load-form `(load ,build-file)))
- (format t "~& ~A~%" sys) (force-output)
- (print load-form out)))
- (fresh-line out))))
-
-(write-build-systems-file :adams)
+ (let* ((fasl (make-pathname :type "fasl" :defaults path))
+ (fasl (merge-pathnames fasl)))
+ (print fasl)
+ (unless (and (probe-file fasl)
+ (<= (file-write-date path)
+ (file-write-date fasl)))
+ (print path)
+ (compile-file path :output-file fasl))
+ (load fasl)))
(defun load* (path)
(format t "~&Loading ~S" path)
(load path))
-(load* (system-file :adams "config.lisp"))
-(load* (system-file :adams "build/systems.lisp"))
-(load* (system-file :adams "toplevel.lisp"))
+(load* "config.lisp")
+(load* "build/systems.lisp")
+(load* "toplevel.lisp")
diff --git a/config.lisp b/config.lisp
index 207c5fe..c039f50 100644
--- a/config.lisp
+++ b/config.lisp
@@ -1,2 +1,4 @@
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(declaim (optimize (debug 3) (safety 3) (speed 3)))
diff --git a/core/defs.lisp b/core/defs.lisp
index 064f98f..d2123a1 100644
--- a/core/defs.lisp
+++ b/core/defs.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
@@ -195,6 +180,7 @@
(probe-host-locale :properties (:locale))
(probe-host-packages :properties (:packages))
(probe-boot-time :properties (:boot-time))
+ (probe-host-homedir :properties (:homedir))
(probe-host-user :properties (:user))
(probe-hostname :properties (:hostname)))
((op-host-locale :properties (:locale))
@@ -261,3 +247,7 @@
`(loop
(unless (remf ,place ,indicator)
(return))))
+
+;; Shebang
+
+(set-dispatch-macro-character #\# #\! #'read-line)
diff --git a/core/helpers.lisp b/core/helpers.lisp
index d4f6527..8955517 100644
--- a/core/helpers.lisp
+++ b/core/helpers.lisp
@@ -1,29 +1,32 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2020 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
-(defun read-file (path)
- (with-output-to-string (out)
- (with-open-file (stream path :element-type 'character)
- (let ((buf (make-string 4096)))
- (loop
- (let ((size (read-sequence buf stream)))
- (when (zerop size)
- (return))
- (write-sequence buf out :end size)))))))
+(defun read-file (&rest path-parts)
+ (let ((path (str path-parts)))
+ (with-output-to-string (out)
+ (with-open-file (stream path :element-type 'character)
+ (let ((buf (make-string 4096)))
+ (loop
+ (let ((size (read-sequence buf stream)))
+ (when (zerop size)
+ (return))
+ (write-sequence buf out :end size))))))))
+
+(defun static-file (path &rest plist)
+ (resource 'file path
+ :content (read-file (hostname *host*) path)
+ plist))
+
+(defun static-directory (directory &rest plist)
+ (let* ((host-dir (truename (pathname (the string
+ (str (hostname) #\/)))))
+ (dir-path (str host-dir directory)))
+ (print dir-path)
+ (mapcar (lambda (path)
+ (let ((name (enough-namestring path host-dir)))
+ (resource 'file (str "/" name)
+ :content (read-file path)
+ plist)))
+ (directory dir-path))))
diff --git a/core/host.lisp b/core/host.lisp
index 415184a..5a17214 100644
--- a/core/host.lisp
+++ b/core/host.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
@@ -71,9 +56,26 @@
;; Host
-(defun hostname (host)
+(defun hostname (&optional (host (current-host)))
(resource-id (the host host)))
+(defun homedir (user &optional (host (current-host)))
+ (str (etypecase (host-os host)
+ (os-darwin "/Users")
+ (os "/home"))
+ "/"
+ (etypecase user
+ (user (resource-id user))
+ (string user))))
+
+(defgeneric probe-host-homedir (host os))
+
+(defmethod probe-host-homedir (host (os os-unix))
+ '(:homedir "/home"))
+
+(defmethod probe-host-homedir (host (os os-darwin))
+ '(:homedir "/Users"))
+
;; Host shell
(defmethod host-shell ((host host))
diff --git a/core/include.lisp b/core/include.lisp
index 0b1ae78..da6142a 100644
--- a/core/include.lisp
+++ b/core/include.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2020 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
@@ -23,15 +8,20 @@
(let ((path (str parts)))
(when (probe-file path)
(return-from include/resolve-filename path)))))
- (try spec)
- (try spec ".adams")))
+ (try spec ".adams")
+ (try spec)))
+
+(defun include/resolve-filename! (spec)
+ (or (include/resolve-filename spec)
+ (error "(include ~S) => file not found.~%
+Current directory : ~S" spec *default-pathname-defaults*)))
(defun include (&rest sources)
(let* ((head (cons 'list nil))
(tail head)
(eof (gensym "EOF")))
(dolist (source sources)
- (let ((path (include/resolve-filename source)))
+ (let ((path (include/resolve-filename! source)))
(with-open-file (in path
:element-type 'character
:external-format :utf-8)
diff --git a/core/operation.lisp b/core/operation.lisp
index cd34c7f..76e4ead 100644
--- a/core/operation.lisp
+++ b/core/operation.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
@@ -170,14 +155,13 @@
(defun print-diff (stream diff)
(dolist (item diff)
(destructuring-bind (property expected probed) item
- (declare (type symbol property)
- (type list expected probed))
+ (declare (type symbol property))
(write-str stream property #\Newline
" expected ")
- (print-list expected stream)
+ (prin1 expected stream)
(write-str stream #\Newline
" probed ")
- (print-list probed stream)
+ (prin1 probed stream)
(write-str stream #\Newline))))
(defmethod print-object ((c resource-operation-failed) stream)
diff --git a/core/os.lisp b/core/os.lisp
index 54e2a2f..0ffdace 100644
--- a/core/os.lisp
+++ b/core/os.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
diff --git a/core/probe.lisp b/core/probe.lisp
index 2fc2e8f..c9fc2be 100644
--- a/core/probe.lisp
+++ b/core/probe.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
diff --git a/core/properties.lisp b/core/properties.lisp
index a232b4b..d97f345 100644
--- a/core/properties.lisp
+++ b/core/properties.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
diff --git a/core/resource-container.lisp b/core/resource-container.lisp
index b102d5c..43636f4 100644
--- a/core/resource-container.lisp
+++ b/core/resource-container.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
diff --git a/core/resource.lisp b/core/resource.lisp
index d5ea4e5..a07c641 100644
--- a/core/resource.lisp
+++ b/core/resource.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
diff --git a/core/spec.lisp b/core/spec.lisp
index 891eef9..13a2853 100644
--- a/core/spec.lisp
+++ b/core/spec.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
@@ -58,14 +43,13 @@
(loop
(when (endp spec)
(return))
- (if (consp (first spec))
- (progn
- (parse-specification res (first spec))
- (setq spec (rest spec)))
- (let ((next-spec (parse-next-specification res spec)))
- (when (eq spec next-spec)
- (error "Invalid specification : ~S" spec))
- (setq spec next-spec))))
+ (typecase (first spec)
+ (cons (parse-specification res (first spec))
+ (setq spec (rest spec)))
+ (t (let ((next-spec (parse-next-specification res spec)))
+ (when (eq spec next-spec)
+ (error "Invalid specification : ~S" spec))
+ (setq spec next-spec)))))
res)
#+nil
@@ -123,14 +107,33 @@ First value lists properties out of specification in the following format :
Second value lists properties in line with spec. Format is
(PROPERTY-NAME VALUE)"))
-(defmethod resource-diff ((res resource))
- (let ((specified-properties (specified-properties res))
- diff)
+(defvar *virtual-properties*
+ '(:after
+ :before)
+ "Special properties that will not be synchronized.")
+
+(declaim (type list *virtual-properties*))
+
+(defun diffable-properties (specified-properties)
+ (let ((properties))
(loop
(when (endp specified-properties)
- (return))
+ (return (nreverse properties)))
(let* ((property (pop specified-properties))
- (specified (pop specified-properties))
+ (specified (pop specified-properties)))
+ (unless (find property *virtual-properties* :test #'eq)
+ (push property properties)
+ (push specified properties))))))
+
+(defmethod resource-diff ((res resource))
+ (let* ((specified-properties (specified-properties res))
+ (properties (diffable-properties specified-properties))
+ diff)
+ (loop
+ (when (endp properties)
+ (return))
+ (let* ((property (pop properties))
+ (specified (pop properties))
(probed (get-probed res property))
(desc (describe-probed-property-value res property probed)))
(unless (match-specified-value res property specified desc (host-os *host*))
diff --git a/core/syntaxes.lisp b/core/syntaxes.lisp
index 60638a9..8b8d6b4 100644
--- a/core/syntaxes.lisp
+++ b/core/syntaxes.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
diff --git a/package.lisp b/package.lisp
index 5c61e4a..efca103 100644
--- a/package.lisp
+++ b/package.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :cl-user)
@@ -115,6 +100,7 @@
#:resource-diff
;; Host
#:current-host
+ #:homedir
#:host
#:host-connect
#:host-disconnect
@@ -123,6 +109,8 @@
#:host-run
#:localhost
#:run
+ #:run-as-root
+ #:run-as-root-command
#:ssh-host
#:with-connected-host
#:with-host
@@ -143,6 +131,7 @@
#:ssh-authorized-key
#:stat
#:stat<1>
+ #:symlink
#:+timestamp-offset+
#:timestamp-to-universal-time
#:universal-time-to-timestamp
@@ -153,6 +142,9 @@
;; helpers
#:include
#:read-file
+ #:static-file
+ #:static-directory
+ #:str
))
(defpackage :adams-user
diff --git a/prepare-build.lisp b/prepare-build.lisp
new file mode 100644
index 0000000..3c8234a
--- /dev/null
+++ b/prepare-build.lisp
@@ -0,0 +1,179 @@
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
+
+(in-package :common-lisp-user)
+
+(defvar *system-directory*
+ (make-hash-table))
+
+(defun system-directory (system)
+ (or #1=(gethash system *system-directory*)
+ (let* ((sys (typecase system (asdf:system system)
+ (t (asdf:find-system system))))
+ (asd (asdf:system-source-file sys)))
+ (setf #1#
+ (make-pathname :name nil :type nil :defaults asd)))))
+
+(defun system-file (system &rest parts)
+ (let ((str (apply #'concatenate 'string parts)))
+ (merge-pathnames str (system-directory system))))
+
+(asdf:load-system :alexandria)
+
+(defun namestring* (x)
+ (etypecase x
+ (null "")
+ (pathname (namestring x))
+ (string x)))
+
+(defparameter *dir* (namestring* (system-file :adams "")))
+
+(defgeneric collect-sources (x))
+
+(defmethod collect-sources ((x symbol))
+ (collect-sources (asdf:find-system x)))
+
+(defmethod collect-sources ((x string))
+ (collect-sources (asdf:find-system x)))
+
+(defun sort-components (list)
+ (declare (type list list))
+ (let (components roots)
+ (declare (type list components roots))
+ (labels ((map-dependencies (comp fn)
+ (declare (type asdf:component comp))
+ (dolist (id (asdf:component-sideway-dependencies comp))
+ (let ((dep (find id list :test #'string=
+ :key #'asdf:component-name)))
+ (when dep
+ (funcall (the function fn) dep)))))
+ (dfs (comp)
+ (declare (type asdf:component comp))
+ (map-dependencies comp #'dfs)
+ (pushnew comp components)))
+ (dolist (comp list)
+ (declare (type asdf:component comp))
+ (pushnew comp roots))
+ (dolist (comp list)
+ (declare (type asdf:component comp))
+ (map-dependencies comp (lambda (dep)
+ (setf roots (delete dep roots)))))
+ (dolist (comp roots)
+ (dfs comp)))
+ (nreverse components)))
+
+(defmethod collect-sources ((x asdf:parent-component))
+ (let ((children (sort-components (asdf:component-children x))))
+ (mapcan #'collect-sources children)))
+
+(defmethod collect-sources ((req asdf:require-system))
+ (list `(require ,(string-upcase (asdf:component-name req)))))
+
+(defun strip-common-lisp-directory (dir)
+ (declare (type list dir))
+ (let ((pos (position "common-lisp" dir :test #'string=)))
+ (if pos
+ (nthcdr pos dir)
+ dir)))
+
+(defun dependency-path (src)
+ (let* ((adams-dir *dir*)
+ (path (pathname src))
+ (dir (pathname-directory path))
+ (name (pathname-name path))
+ (type (pathname-type path)))
+ (with-output-to-string (out)
+ (write-string adams-dir out)
+ (write-string "build/" out)
+ (let ((dir (strip-common-lisp-directory dir)))
+ (dolist (d (rest dir))
+ (write-string d out)
+ (write-char #\- out)))
+ (write-string name out)
+ (write-char #\. out)
+ (write-string type out))))
+
+(defun copy-dependency (src)
+ (let ((dep (dependency-path src)))
+ (alexandria:copy-file src dep)
+ (enough-namestring dep *dir*)))
+
+(defmethod collect-sources ((x asdf:cl-source-file))
+ (let* ((src (asdf:component-pathname x))
+ (dep (copy-dependency src)))
+ (list `(compile-lisp ,dep))))
+
+(defmethod collect-sources ((x asdf:file-component))
+ (list `(quote ,(asdf:component-pathname x))))
+
+(defmethod collect-sources :around ((x asdf:component))
+ (let ((if-feature (asdf::component-if-feature x)))
+ (etypecase if-feature
+ (null
+ (call-next-method))
+ (symbol
+ (when (find (the symbol if-feature) *features*)
+ (call-next-method)))
+ (cons
+ (cond ((string-equal 'not (first if-feature))
+ (unless (find (the symbol (second if-feature)) *features*)
+ (call-next-method)))
+ (t (error "Bad if-feature")))))))
+
+#+nil (collect-sources :adams)
+
+(defun write-system-build-file (system sbf)
+ (format t "~&~A~%" sbf) (force-output)
+ (with-open-file (out sbf :direction :output
+ :element-type 'character
+ :if-exists :supersede
+ :if-does-not-exist :create
+ :external-format :utf-8)
+ (declare (type stream out))
+ (format out "~&;; ~A" (asdf:component-name system))
+ (dolist (src (collect-sources system))
+ (print src out))))
+
+(defun system-build-file (system)
+ (let* ((asd (asdf:system-source-file system))
+ (name (substitute #\- #\/ (asdf:component-name system)))
+ (sbf (concatenate 'string "build/" name ".lisp")))
+ (unless (and (probe-file sbf)
+ (<= (file-write-date asd)
+ (file-write-date sbf)))
+ (write-system-build-file system sbf))
+ sbf))
+
+(defun system-and-dependencies (name)
+ (let (dependencies)
+ (labels ((dfs (name)
+ (let ((sys (asdf:find-system name)))
+ (when (and sys (not (find sys dependencies)))
+ (locally (declare (type asdf:system sys))
+ (format t "~& ~A" sys) (force-output)
+ (map 'nil #'dfs (asdf:system-depends-on sys))
+ (push sys dependencies))))))
+ (dfs name)
+ (nreverse dependencies))))
+
+(defun write-build-systems-file (system)
+ (unless (typep system 'asdf:system)
+ (setq system (asdf:find-system system)))
+ (let* ((path (system-file system "build/systems.lisp")))
+ (print path) (force-output)
+ (ensure-directories-exist path)
+ (with-open-file (out path :direction :output
+ :element-type 'character
+ :external-format :utf-8
+ :if-exists :supersede
+ :if-does-not-exist :create)
+ (declare (type stream out))
+ (dolist (sys (system-and-dependencies system))
+ (let* ((build-file (system-build-file sys))
+ (load-form `(load ,build-file)))
+ (format t "~& ~A~%" sys) (force-output)
+ (print load-form out)))
+ (fresh-line out)
+ (force-output out))))
+
+(write-build-systems-file :adams)
diff --git a/shell/sb-shell.lisp b/shell/sb-shell.lisp
index 9abbbee..e7627f9 100644
--- a/shell/sb-shell.lisp
+++ b/shell/sb-shell.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
diff --git a/shell/shell.lisp b/shell/shell.lisp
index 3f3e1cc..c4aa608 100644
--- a/shell/shell.lisp
+++ b/shell/shell.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
@@ -137,7 +122,7 @@ Error: ~S"
(shell-in (format nil " ; echo \"~%~A $?\"~%" delim) shell)
(let* ((prev nil)
(status
- (loop (let ((line (the string (shell-out/line shell))))
+ (loop (let ((line (shell-out/line shell)))
(when (or (null line)
(and (< len (length line))
(string= delim line :end2 len)))
@@ -160,7 +145,7 @@ Error: ~S"
(shell-log shell "| ~A~%" line))
(dolist (line err)
(shell-log shell "# ~A~&" line))
- (unless (= 0 status)
+ (unless (and status (= 0 status))
(shell-log shell " ⇒ ~D~%" status)))
(values status out err))))
diff --git a/test.lisp b/test.lisp
index 7da15f0..e57cce3 100644
--- a/test.lisp
+++ b/test.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :cl-user)
@@ -32,6 +17,11 @@
(adams:clear-resources)
(adams:clear-probed)
+(resource 'symlink "/home/dx/test-symlink"
+ :owner "dx"
+ :group "dx"
+ :target "../test")
+
(resource 'host "ams.kmx.io"
:user "root"
:hostname "ams"
diff --git a/toplevel.lisp b/toplevel.lisp
index 3396cc6..576873b 100644
--- a/toplevel.lisp
+++ b/toplevel.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
diff --git a/unix/commands.lisp b/unix/commands.lisp
index b5018a9..90868f2 100644
--- a/unix/commands.lisp
+++ b/unix/commands.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
@@ -54,3 +39,9 @@
(defun sudo (&rest command)
(run (apply #'sudo_ command)))
+
+(defun doas_ (&rest command)
+ (join-str " " "doas" command))
+
+(defun doas (&rest command)
+ (run (apply #'doas_ command)))
diff --git a/unix/darwin.lisp b/unix/darwin.lisp
new file mode 100644
index 0000000..0e48d54
--- /dev/null
+++ b/unix/darwin.lisp
@@ -0,0 +1,192 @@
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
+
+(in-package :adams)
+
+(in-re-readtable)
+
+(defmethod echo-command ((host t) (os os-darwin))
+ "printf %s ")
+
+(defmethod probe-hostname ((host host) (os os-darwin))
+ (list :hostname (run-1 "hostname -s")))
+
+(define-resource-class brew-pkg (pkg)
+ ()
+ ((probe-brew-pkg :properties (:ensure :flavor :version)))
+ ((op-brew-pkg :properties (:ensure :version))))
+
+(defgeneric probe-brew-pkg (resource os))
+
+(defgeneric op-brew-pkg (pkg os &key ensure version))
+
+(defmethod probe-host-packages ((host host) (os os-darwin))
+ (list :packages ()))
+
+(defmethod op-host-packages ((host host) (os os-darwin) &key packages)
+ nil)
+
+(defmethod op-hostname ((host host) (os os-unix) &key hostname)
+ (run-as-root "hostname -s " (sh-quote hostname)))
+
+(defmethod probe-group ((group group) (os os-darwin))
+ (let ((id (resource-id group))
+ (ensure :absent)
+ (gid nil))
+ (multiple-value-bind (out status)
+ (run "dscl . -read /Groups/" (sh-quote id))
+ (when (= 0 status)
+ (setq ensure :present)
+ (dolist (line out)
+ (re-bind "PrimaryGroupID: ([0-9]+)" (n) line
+ (setq gid (parse-number n)))))
+ (properties* ensure gid))))
+
+#+nil
+(probe (resource 'group "dx") :gid)
+
+(defmethod probe-user ((user user) (os os-darwin))
+ (let* ((id (resource-id user))
+ (sh-id (sh-quote id))
+ (ensure :absent)
+ uid
+ gid
+ shell
+ home)
+ (multiple-value-bind (out status)
+ (run "dscl . -read /Users/" sh-id)
+ (when (= 0 status)
+ (setq ensure :present)
+ (dolist (line out)
+ (re-bind #~|^UniqueID: ([0-9]+)| (n) line
+ (setq uid (parse-number n)))
+ (re-bind #~|^PrimaryGroupID: ([0-9]+)| (n) line
+ (setq gid (parse-number n)))
+ (re-bind #~|^UserShell: (/[^ \n]+)| (s) line
+ (setq shell s))
+ (re-bind #~|^NFSHomeDirectory: (/[^ \n]+)| (h) line
+ (setq home h)))))
+ (let ((realname (string-trim
+ '(#\Space #\Newline)
+ (second (run "dscl . -read /Users/" sh-id
+ " RealName")))))
+ (properties* ensure uid gid shell home realname))))
+
+#+nil
+(probe (resource 'user "root") :gid)
+
+(define-syntax id<1>-tr ((#'parse-integer gid) name)
+ #~|([0-9]+)[(]([^)]+)|)
+
+(defmethod probe-user-groups ((user user) (os os-darwin))
+ (let ((id (resource-id user))
+ (groups nil))
+ (unless (eq :absent (get-probed user :ensure))
+ (let ((user-gid (get-probed user :gid))
+ (user-group nil))
+ (with-id<1>-tr (gid name) (run "id " (sh-quote id)
+ " | tr ' ,=' '\\n'")
+ (when gid
+ (when (= user-gid gid)
+ (setq user-group (resource 'group name)))
+ (push (resource 'group name) groups)))
+ (setq groups (sort groups #'string< :key #'resource-id)
+ groups (if user-group
+ (cons user-group
+ (remove (resource-id user-group)
+ groups :key #'resource-id
+ :test #'string=))
+ groups)
+ groups (remove-if (lambda (x)
+ (find (resource-id x)
+ '("_lpoperator"
+ "com.apple.access_ssh"
+ "com.apple.sharepoint.group.1"
+ "com.apple.sharepoint.group.2"
+ "everyone"
+ "localaccounts")
+ :test #'string=))
+ groups))))
+ (properties* groups)))
+
+#+nil
+(probe (resource 'user "root") :groups)
+
+(defmethod op-update-group ((group group) (os os-darwin) &key ensure gid)
+ (let ((id (resource-id group)))
+ (run-as-root
+ (join-str
+ " "
+ "dscl ."
+ (ecase ensure
+ ((:absent) "-delete")
+ ((:present) "-create")
+ ((nil) "-change"))
+ (str "/Groups/" (sh-quote id))
+ (when gid
+ `("PrimaryGroupID"
+ ,(unless ensure
+ (sh-quote (get-probed group :gid)))
+ ,(sh-quote gid)))))))
+
+(defmethod op-update-user ((user user) (os os-darwin)
+ &key ensure uid gid realname home shell
+ login-class groups)
+ (declare (ignore login-class))
+ (sync-groups)
+ (let* ((id (resource-id user))
+ (sh-id (sh-quote id)))
+ (when ensure
+ (run-as-root
+ "dscl . "
+ (ecase ensure
+ ((:absent) "-delete ")
+ ((:present) "-create "))
+ (str "/Users/" sh-id)))
+ (when uid
+ (run-as-root
+ "dscl . -create /Users/" sh-id
+ " UniqueID "
+ (sh-quote uid)))
+ (when gid
+ (run-as-root
+ "dscl . -create /Users/" sh-id
+ " PrimaryGroupID "
+ (sh-quote gid)))
+ (when home
+ (run-as-root
+ "dscl . -create /Users/" sh-id
+ " NFSHomeDirectory "
+ (sh-quote home)))
+ (when shell
+ (run-as-root
+ "dscl . -create /Users/" sh-id
+ " UserShell "
+ (sh-quote shell)))
+ (dolist (group (get-probed user :groups))
+ (unless (find (resource-id group) groups)
+ (run-as-root
+ "dscl . -delete /Groups/" (sh-quote (resource-id group))
+ " GroupMembership " sh-id)))
+ (dolist (group groups)
+ (run-as-root
+ "dscl . -append /Groups/" (sh-quote group)
+ " GroupMembership " sh-id))))
+
+#+nil
+(clear-resources)
+
+#+nil
+(describe-probed (resource 'openbsd-pkg "emacs"))
+
+#+nil
+(probe-host-packages *host* (host-os *host*))
+
+#+nil
+(probe *host* :packages)
+
+#+nil
+(map nil #'describe-probed (probe-installed-packages))
+
+#+nil
+(run "pkg_info -q | grep emacs-")
diff --git a/unix/debian.lisp b/unix/debian.lisp
index a9d3f54..734e4b9 100644
--- a/unix/debian.lisp
+++ b/unix/debian.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
diff --git a/unix/defs.lisp b/unix/defs.lisp
index fb32d1b..7bb5065 100644
--- a/unix/defs.lisp
+++ b/unix/defs.lisp
@@ -1,41 +1,26 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
;; Group
(define-resource-class group () ()
- ((probe-group-in-/etc/group :properties (:ensure :name :passwd :gid :members)))
+ ((probe-group :properties (:ensure :name :passwd :gid :members)))
((op-update-group :properties (:ensure :gid))))
-(defgeneric probe-group-in-/etc/group (resource os))
+(defgeneric probe-group (resource os))
(defgeneric op-update-group (resource os &key ensure gid))
;; User
(define-resource-class user (resource-container)
()
- ((probe-user-in-/etc/passwd :properties (:ensure :login :uid :gid :realname
- :home :shell))
- (probe-user-groups-in-/etc/group :properties (:groups)))
+ ((probe-user :properties (:ensure :login :uid :gid :realname
+ :home :shell))
+ (probe-user-groups :properties (:groups)))
((op-update-user :properties (:ensure :uid :gid :realname :home :shell
- :login-class :groups))))
+ :login-class :groups))))
(defgeneric probe-user-in-/etc/passwd (resource os))
(defgeneric probe-user-groups-in-/etc/group (resource os))
@@ -94,6 +79,19 @@
(defgeneric op-file-ensure (resource os &key ensure))
(defgeneric op-file-content (resource os &key content))
+;; Symbolic link
+
+(define-resource-class symlink (vnode)
+ ()
+ ((probe-symlink-target :properties (:target)))
+ ((op-symlink-ensure :properties (:ensure))
+ (op-symlink-target :properties (:target)))
+ ((:op-properties (:ensure :target))))
+
+(defgeneric probe-symlink-target (resource os))
+(defgeneric op-symlink-ensure (resource os &key ensure))
+(defgeneric op-symlink-target (resource os &key target))
+
;; Directory
(define-resource-class directory (vnode)
diff --git a/unix/freebsd.lisp b/unix/freebsd.lisp
index 7fb3042..9b34175 100644
--- a/unix/freebsd.lisp
+++ b/unix/freebsd.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
diff --git a/unix/linux.lisp b/unix/linux.lisp
index be4b6b3..4d2f441 100644
--- a/unix/linux.lisp
+++ b/unix/linux.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
diff --git a/unix/openbsd.lisp b/unix/openbsd.lisp
index 64908d3..6ba2960 100644
--- a/unix/openbsd.lisp
+++ b/unix/openbsd.lisp
@@ -1,32 +1,23 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
(in-re-readtable)
+(defmethod echo-command ((host t) (os os-openbsd))
+ "echo -E -n ")
+
+(defmethod run-as-root-command ((host t) (os os-openbsd))
+ "doas ")
+
(defmethod probe-hostname ((host host) (os os-openbsd))
(list :hostname (run-1 "hostname -s")))
(define-resource-class openbsd-pkg (pkg)
()
((probe-openbsd-pkg :properties (:ensure :flavor :version)))
- ((op-openbsd-pkg :properties (:ensure))))
+ ((op-openbsd-pkg :properties (:ensure :version))))
(define-syntax pkg_info<1> (name version flavor installed)
#~|\s*([^-\s]+(?:-[^-0-9\s][^-\s]+)*)-([0-9][^-\s]*)(?:-([^-\s]+))?( \(installed\))?|
@@ -43,11 +34,11 @@
(let ((id (resource-id pkg))
(ensure :absent))
(with-openbsd-pkg-id (id-name id-version id-flavor) (list id)
- ;(format t "~&id-name ~S id-flavor ~S~%" id-name id-flavor)
+ (format t "~&id-name ~S id-flavor ~S~%" id-name id-flavor)
(multiple-value-bind (version flavor)
(with-pkg_info<1> (name version flavor installed)
(run "pkg_info | egrep " (sh-quote (str "^" id-name)))
- ;(format t "~&name ~S version ~S flavor ~S installed ~S~%" name version flavor installed)
+ (format t "~&name ~S version ~S flavor ~S installed ~S~%" name version flavor installed)
(when (and (string= id-name name)
(or (and (null id-flavor) (null flavor))
(and id-flavor flavor
@@ -58,34 +49,26 @@
(return (values version flavor))))
(return (properties* ensure version flavor))))))
-(defmethod merge-property-values ((pkg openbsd-pkg)
- (property (eql :versions))
- (old list)
- (new list))
- (sort (remove-duplicates (append old new))
- #'string<))
-
(defmethod match-specified-value ((res host)
(property (eql :packages))
(specified list)
(probed list)
(os os-openbsd))
- (format t "~&match-specified-value specified ~S~%" specified)
- (format t "~&match-specified-value probed ~S~%" probed)
- (force-output)
- (with-openbsd-pkg-id (name version flavor) specified
- (unless (find name probed :test #'string=)
- (return nil)))
+ (dolist (pkg-id specified)
+ (unless (find pkg-id probed :test #'string=)
+ (return-from match-specified-value nil)))
t)
-(defmethod op-openbsd-pkg ((pkg openbsd-pkg) (os os-openbsd) &key ensure)
+(defmethod op-openbsd-pkg ((pkg openbsd-pkg) (os os-openbsd) &key ensure version)
(with-openbsd-pkg-id (id-name id-version id-flavor) (list (resource-id pkg))
- (when (and id-flavor (not id-version))
- (probe pkg :version))
+ (setq version
+ (or version
+ id-version
+ (progn (probe pkg :version)
+ (get-probed pkg :version))))
(let ((pkg-string (str id-name
- (when (or id-version id-flavor)
- `(#\- ,(or id-version
- (get-probed pkg :version))))
+ (when version
+ `(#\- ,version))
(when id-flavor
`(#\- ,id-flavor)))))
(cond
@@ -111,16 +94,17 @@
(defmethod op-host-packages ((host host) (os os-openbsd) &key packages)
(with-host host
- (with-openbsd-pkg-id (name version flavor) packages
- (let ((pkg (resource 'openbsd-pkg name
- :ensure :installed)))
- (when version
- (resource 'openbsd-pkg name
- :version version))
- (when flavor
- (resource 'openbsd-pkg name
- :flavor flavor))
- (sync pkg)))))
+ (dolist (pkg-id packages)
+ (with-openbsd-pkg-id (name version flavor) (list pkg-id)
+ (let ((pkg (resource 'openbsd-pkg pkg-id
+ :ensure :installed)))
+ (when version
+ (resource 'openbsd-pkg pkg-id
+ :version version))
+ (when flavor
+ (resource 'openbsd-pkg pkg-id
+ :flavor flavor))
+ (sync pkg))))))
#+nil
(clear-resources)
diff --git a/unix/operations.lisp b/unix/operations.lisp
index 735a8df..fdd219c 100644
--- a/unix/operations.lisp
+++ b/unix/operations.lisp
@@ -1,28 +1,35 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
+;; Echo
+
+(defgeneric echo-command (host os))
+
+(defmethod echo-command ((host t) (os t))
+ "echo -n ")
+
+(defun echo_ (&rest parts)
+ (let* ((host (current-host))
+ (cmd (echo-command host (host-os host))))
+ (str cmd (sh-quote parts))))
+
+(defun echo (&rest parts)
+ (run (echo_ parts)))
+
+;; Run as root
+
+(defgeneric run-as-root-command (host os))
+
+(defmethod run-as-root-command ((host t) (os os-unix))
+ "sudo ")
+
(defun run-as-root (&rest command)
- (apply #'run
- (unless (equal "root" (get-probed (current-host) :user))
- "sudo ")
- command))
+ (let* ((host (current-host))
+ (prefix (unless (equal "root" (get-probed host :user))
+ (run-as-root-command host (get-probed host :os)))))
+ (apply #'run prefix command)))
;; Host operations
@@ -56,13 +63,19 @@
(join-str " "
(ecase ensure
((:absent) "userdel")
- ((:present) "useradd -m")
+ ((:present) `("useradd"
+ ,(unless (eq :present
+ (get-probed
+ (resource 'directory (homedir
+ user))
+ :ensure))
+ "-m")))
((nil) "usermod"))
(when realname `("-c" ,(sh-quote realname)))
(when home `("-d" ,(sh-quote home)))
(when gid `("-g" ,(sh-quote gid)))
(when login-class `("-L" ,(sh-quote login-class)))
- (when groups `("-S" ,(join-str "," (mapcar #'sh-quote
+ (when groups `("-G" ,(join-str "," (mapcar #'sh-quote
groups))))
(when shell `("-s" ,(sh-quote shell)))
(when uid `("-u" ,(sh-quote uid)))
@@ -70,6 +83,30 @@
;; VNode
+(defgeneric vnode-owner (res))
+
+(defmethod vnode-owner ((res vnode))
+ (let ((owner-spec (get-specified res :owner)))
+ (when owner-spec
+ (resource 'user owner-spec))))
+
+(defgeneric vnode-group (res))
+
+(defmethod vnode-group ((res vnode))
+ (let ((group-spec (get-specified res :group)))
+ (when group-spec
+ (resource 'user group-spec))))
+
+(defgeneric sync-owner-and-group (res))
+
+(defmethod sync-owner-and-group ((res vnode))
+ (let ((owner (vnode-owner res))
+ (group (vnode-group res)))
+ (when group
+ (sync group))
+ (when owner
+ (sync owner))))
+
(defmethod op-chown ((res vnode) (os os-unix) &key uid gid owner group
&allow-other-keys)
(when (stringp owner)
@@ -80,10 +117,10 @@
(assert (= uid (get-probed owner :uid))))
(when (and gid group)
(assert (= gid (get-probed group :gid))))
- (when owner
- (sync owner))
(when group
(sync group))
+ (when owner
+ (sync owner))
(let ((u (or (when owner (resource-id owner))
uid))
(g (or (when group (resource-id group))
@@ -96,12 +133,32 @@
(defmethod op-chmod ((res vnode) (os os-unix) &key mode
&allow-other-keys)
+ (sync-owner-and-group res)
(run "chmod " (octal (mode-permissions mode)) " "
(sh-quote (resource-id res))))
;; File
+(defun path-parent-directory (&rest path-parts)
+ (let* ((path (the string (str path-parts)))
+ (sep (position #\/ path
+ :from-end t
+ :end (1- (length path))
+ :test #'char=)))
+ (if sep
+ (subseq path 0 sep)
+ "/")))
+
+(defgeneric parent-directory (x))
+
+(defmethod parent-directory ((res vnode))
+ (let* ((path (resource-id res))
+ (parent-path (path-parent-directory path)))
+ (resource 'directory parent-path)))
+
(defmethod op-file-ensure ((res file) (os os-unix) &key ensure)
+ (sync-owner-and-group res)
+ (sync (parent-directory res))
(let* ((id (resource-id res))
(sh-id (sh-quote id)))
(ecase ensure
@@ -110,14 +167,42 @@
((nil)))))
(defmethod op-file-content ((res file) (os os-unix) &key content)
+ (sync-owner-and-group res)
+ (sync (parent-directory res))
(let ((id (resource-id res)))
- (run "echo -n " (sh-quote content) " > " (sh-quote id))
+ (run (echo_ content) " > " (sh-quote id))
+ (when-let (after (get-specified res :after))
+ (funcall (the function after) res os))
(clear-probed res)))
+;; Symlink
+
+(defmethod op-symlink-ensure ((res symlink) (os os-unix)
+ &key ensure)
+ (sync-owner-and-group res)
+ (sync (parent-directory res))
+ (let* ((id (resource-id res))
+ (sh-id (sh-quote id))
+ (target (get-specified res :target))
+ (sh-target (sh-quote target)))
+ (ecase ensure
+ ((:absent) (run "rm " sh-id))
+ ((:present) (run "ln -s " sh-target " " sh-id))
+ ((nil)))))
+
+(defmethod op-symlink-target ((res symlink) (os os-unix)
+ &key target)
+ (let* ((id (resource-id res))
+ (sh-id (sh-quote id))
+ (sh-target (sh-quote target)))
+ (run "ln -sf " sh-target " " sh-id)))
+
;; Directory
(defmethod op-directory-ensure ((res directory) (os os-unix)
&key ensure)
+ (sync-owner-and-group res)
+ (sync (parent-directory res))
(let* ((id (resource-id res))
(sh-id (sh-quote id)))
(ecase ensure
diff --git a/unix/probes.lisp b/unix/probes.lisp
index bf30d72..4c62883 100644
--- a/unix/probes.lisp
+++ b/unix/probes.lisp
@@ -1,26 +1,11 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
;; Group
-(defmethod probe-group-in-/etc/group ((group group) (os os-unix))
+(defmethod probe-group ((group group) (os os-unix))
(let ((id (resource-id group))
(ensure :absent))
(multiple-value-bind #1=(name passwd gid members)
@@ -32,7 +17,7 @@
;; User
-(defmethod probe-user-in-/etc/passwd ((user user) (os os-unix))
+(defmethod probe-user ((user user) (os os-unix))
(let ((id (resource-id user))
(ensure :absent))
(multiple-value-bind #1=(login pass uid gid realname home shell)
@@ -46,7 +31,7 @@
(return (values* #1#))))
(properties* (ensure . #1#)))))
-(defmethod probe-user-groups-in-/etc/group ((user user) (os os-unix))
+(defmethod probe-user-groups ((user user) (os os-unix))
(let ((id (resource-id user))
groups)
(unless (eq :absent (get-probed user :ensure))
@@ -76,10 +61,10 @@
(defmethod probe-vnode-using-ls ((vnode vnode) (os os-unix))
(let ((id (resource-id vnode))
(ensure :absent))
- (multiple-value-bind #1=(mode links owner group size mtime)
+ (multiple-value-bind #1=(mode links owner group size mtime target)
(with-ls<1>-lT #.(cons 'name '#1#)
- (ls "-ldT" (sh-quote id))
- (when (string= id name)
+ (ls "-ldT" id)
+ (when (string= id (the string name))
(setq mode (mode (mode-permissions mode))
owner (resource 'user owner)
group (resource 'group group)
@@ -144,6 +129,14 @@
:file-too-large))))
(properties* content)))
+;; Symlink
+
+(defmethod probe-symlink-target ((symlink symlink) (os os-unix))
+ (let ((target (string-trim '(#\Newline)
+ (run-1 "readlink "
+ (sh-quote (resource-id symlink))))))
+ (properties* target)))
+
;; Directory
(defmethod probe-directory-content ((dir directory) (os os-unix))
diff --git a/unix/ssh.lisp b/unix/ssh.lisp
index f6c3c0a..0dda1af 100644
--- a/unix/ssh.lisp
+++ b/unix/ssh.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
diff --git a/unix/stat.lisp b/unix/stat.lisp
index 703ffea..28ec881 100644
--- a/unix/stat.lisp
+++ b/unix/stat.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
@@ -144,4 +129,7 @@
(defmethod match-specified-value ((resource vnode) (property (eql :mode))
specified probed os)
- (= (mode-fixnum specified) (mode-fixnum probed)))
+ (or (eq specified probed)
+ (and specified
+ probed
+ (= (mode-fixnum specified) (mode-fixnum probed)))))
diff --git a/unix/syntaxes.lisp b/unix/syntaxes.lisp
index 5cc482d..74b54aa 100644
--- a/unix/syntaxes.lisp
+++ b/unix/syntaxes.lisp
@@ -1,20 +1,5 @@
-;;
-;; adams - system administrator written in Common Lisp
-;;
-;; Copyright 2013,2014,2018 Thomas de Grivel <thoxdg@gmail.com>
-;;
-;; Permission to use, copy, modify, and distribute this software for any
-;; purpose with or without fee is hereby granted, provided that the above
-;; copyright notice and this permission notice appear in all copies.
-;;
-;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-;;
+;; Adams - UNIX system administration tool written in Common Lisp
+;; Copyright 2013-2022 Thomas de Grivel <thodg@kmx.io>
(in-package :adams)
@@ -25,7 +10,7 @@
(define-syntax group<5> (name passwd
(#'parse-integer gid)
((lambda (m) (cl-ppcre:split "," m)) members))
- #~|^([^:]*):([^:]*):([^:]*):([^:]*)$|
+ #~|^([^:]*):([^:]*):([^:]*):([^:\s]*)\s*$|
"Syntax of the group permissions file /etc/group. See group(5).")
(define-syntax passwd<5> (name pass
@@ -41,10 +26,11 @@
group
(#'sh-parse-integer size)
(#'chronicity:parse time)
- name)
- #~|^([-a-zA-Z]{10})\s+([0-9]+)\s+(\S+)\s+(\S+)\s+([0-9]+)\s+(\S+\s+\S+ \S+ \S+)\s+(.+)$|
+ name
+ target)
+ #~|^([-a-zA-Z]{10})\s+([0-9]+)\s+(\S+)\s+(\S+)\s+([0-9]+)\s+(\S+\s+\S+ \S+ \S+)\s+(.+?)(?: -> (.*))?$|
"Syntax for `ls -lT` output. See ls(1)."
- (values name mode links owner group size time))
+ (values name mode links owner group size time target))
(define-syntax stat<1>-r ((#'sh-parse-integer
dev ino mode links uid gid rdev size)