summaryrefslogtreecommitdiff
path: root/pkgng
diff options
context:
space:
mode:
authorWilliam Johansson <radar@radhuset.org>2015-04-24 20:22:51 +0200
committerJoey Hess <joeyh@joeyh.name>2015-06-10 15:43:11 -0400
commit1f21fbe26dfbc982492c8b7b90f3758a910f113d (patch)
tree80183a72bf5cd18387a89ddd368e762841c5f930 /pkgng
parent87bb4978dade6117f69799f435dad741eb741655 (diff)
Initial FreeBSD support with pkgng plugin
Add a basic pkgng plugin as a preparation to integrate etckeeper on FreeBSD. Currently not enabled to build automatically. To use on FreeBSD, install etckeeper manually and install the plugin with: $ cd pkgng $ make $ make install and add this line to /usr/local/etc/pkg.conf: PLUGINS [ etckeeper ]
Diffstat (limited to 'pkgng')
-rw-r--r--pkgng/Makefile17
-rw-r--r--pkgng/etckeeper.c132
2 files changed, 149 insertions, 0 deletions
diff --git a/pkgng/Makefile b/pkgng/Makefile
new file mode 100644
index 0000000..92d3c1d
--- /dev/null
+++ b/pkgng/Makefile
@@ -0,0 +1,17 @@
+.include <bsd.own.mk>
+
+PREFIX?= /usr/local
+LIBDIR= ${PREFIX}/lib/pkg/
+SHLIB_DIR?= ${LIBDIR}/
+SHLIB_NAME?= ${PLUGIN_NAME}.so
+
+PLUGIN_NAME= etckeeper
+SRCS= etckeeper.c
+
+PKGFLAGS!= pkgconf --cflags pkg
+CFLAGS+= ${PKGFLAGS}
+
+beforeinstall:
+ ${INSTALL} -d ${LIBDIR}
+
+.include <bsd.lib.mk>
diff --git a/pkgng/etckeeper.c b/pkgng/etckeeper.c
new file mode 100644
index 0000000..6c54388
--- /dev/null
+++ b/pkgng/etckeeper.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2015 William Johansson <radar@radhuset.org>
+ * 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
+ * in this position and unchanged.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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(S) 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.
+ *
+ * Based upon the pkg plugin zfssnap:
+ * Copyright (c) 2012 Marin Atanasov Nikolov <dnaeon@gmail.com>
+ */
+
+#include <stdio.h>
+#include <sys/wait.h>
+#include <err.h>
+#include <errno.h>
+#include <spawn.h>
+
+#include <pkg.h>
+#define PLUGIN_NAME "etckeeper"
+/* TODO: make configuration param? */
+#define ETCKEEPER_PATH "/usr/local/bin/etckeeper"
+
+extern char **environ;
+
+struct pkg_plugin *self;
+
+static int pre_install_hook(void *data, struct pkgdb *db);
+static int post_install_hook(void *data, struct pkgdb *db);
+
+int
+pkg_plugin_init(struct pkg_plugin *p)
+{
+ self = p;
+
+ pkg_plugin_set(p, PKG_PLUGIN_NAME, PLUGIN_NAME);
+ pkg_plugin_set(p, PKG_PLUGIN_DESC, "etckeeper plugin");
+ pkg_plugin_set(p, PKG_PLUGIN_VERSION, "1.0.0");
+
+ /* NOTE: upgrade/deinstall is regarded as install */
+
+ if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_PRE_INSTALL, &pre_install_hook) != EPKG_OK) {
+ pkg_plugin_error(self, "failed to hook into the library");
+ return (EPKG_FATAL);
+ }
+
+ if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_POST_INSTALL, &post_install_hook) != EPKG_OK) {
+ pkg_plugin_error(self, "failed to hook into the library");
+ return (EPKG_FATAL);
+ }
+
+ if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_PRE_DEINSTALL, &pre_install_hook) != EPKG_OK) {
+ pkg_plugin_error(self, "failed to hook into the library");
+ return (EPKG_FATAL);
+ }
+
+ if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_POST_DEINSTALL, &post_install_hook) != EPKG_OK) {
+ pkg_plugin_error(self, "failed to hook into the library");
+ return (EPKG_FATAL);
+ }
+
+ if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_PRE_UPGRADE, &pre_install_hook) != EPKG_OK) {
+ pkg_plugin_error(self, "failed to hook into the library");
+ return (EPKG_FATAL);
+ }
+
+ if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_POST_UPGRADE, &post_install_hook) != EPKG_OK) {
+ pkg_plugin_error(self, "failed to hook into the library");
+ return (EPKG_FATAL);
+ }
+
+ return (EPKG_OK);
+}
+
+static int
+call_etckeeper(char *arg)
+{
+ int error, pstat;
+ pid_t pid;
+ char *argv[] = {
+ "etckeeper",
+ arg,
+ NULL,
+ };
+
+ if ((error = posix_spawn(&pid, ETCKEEPER_PATH, NULL, NULL,
+ __DECONST(char **, argv), environ)) != 0) {
+ errno = error;
+ pkg_plugin_errno(self, "Failed to spawn process", arg);
+ return (EPKG_FATAL);
+ }
+ while (waitpid(pid, &pstat, 0) == -1) {
+ if (errno != EINTR)
+ return (EPKG_FATAL);
+ }
+
+ if ((error = WEXITSTATUS(pstat)) != 0) {
+ pkg_plugin_error(self, "etckeeper failed with exit code %d", error);
+ return (EPKG_FATAL);
+ }
+
+ return (EPKG_OK);
+}
+
+static int
+pre_install_hook(void *data, struct pkgdb *db)
+{
+ return call_etckeeper("pre-install");
+}
+
+static int
+post_install_hook(void *data, struct pkgdb *db)
+{
+ return call_etckeeper("post-install");
+}