summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac4
-rw-r--r--lib/system/system.c157
-rw-r--r--lib/system/system.h20
-rw-r--r--rules.mk5
4 files changed, 182 insertions, 4 deletions
diff --git a/configure.ac b/configure.ac
index 340cdbf..c67f0ed 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,7 +50,7 @@ AS_IF([test "x$with_twin" != xno],
fi],
[${twin_LIBS}])])
-mkdir -p discover lib/list lib/log lib/pb-protocol lib/talloc lib/waiter \
- test ui/common ui/ncurses ui/test ui/twin
+mkdir -p discover lib/list lib/log lib/pb-protocol lib/system lib/talloc \
+ lib/waiter test ui/common ui/ncurses ui/test ui/twin
AC_OUTPUT
diff --git a/lib/system/system.c b/lib/system/system.c
new file mode 100644
index 0000000..380dded
--- /dev/null
+++ b/lib/system/system.c
@@ -0,0 +1,157 @@
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "log/log.h"
+#include <talloc/talloc.h>
+#include "system.h"
+
+const struct pb_system_apps pb_system_apps = {
+ .cp = "/bin/cp",
+ .kexec = "/sbin/kexec",
+ .mount = "/bin/mount",
+ .sftp = "/usr/bin/sftp",
+ .tftp = "/usr/bin/tftp",
+ .umount = "/bin/umount",
+ .wget = "/usr/bin/wget",
+};
+
+int pb_mkdir_recursive(const char *dir)
+{
+ struct stat statbuf;
+ char *str, *sep;
+ int mode = 0755;
+
+ if (!*dir)
+ return 0;
+
+ if (!stat(dir, &statbuf)) {
+ if (!S_ISDIR(statbuf.st_mode)) {
+ pb_log("%s: %s exists, but isn't a directory\n",
+ __func__, dir);
+ return -1;
+ }
+ return 0;
+ }
+
+ str = talloc_strdup(NULL, dir);
+ sep = strchr(*str == '/' ? str + 1 : str, '/');
+
+ while (1) {
+
+ /* terminate the path at sep */
+ if (sep)
+ *sep = '\0';
+
+ if (mkdir(str, mode) && errno != EEXIST) {
+ pb_log("mkdir(%s): %s\n", str, strerror(errno));
+ return -1;
+ }
+
+ if (!sep)
+ break;
+
+ /* reset dir to the full path */
+ strcpy(str, dir);
+ sep = strchr(sep + 1, '/');
+ }
+
+ talloc_free(str);
+
+ return 0;
+}
+
+int pb_rmdir_recursive(const char *base, const char *dir)
+{
+ char *cur, *pos;
+
+ /* sanity check: make sure that dir is within base */
+ if (strncmp(base, dir, strlen(base)))
+ return -1;
+
+ cur = talloc_strdup(NULL, dir);
+
+ while (strcmp(base, dir)) {
+
+ rmdir(dir);
+
+ /* null-terminate at the last slash */
+ pos = strrchr(dir, '/');
+ if (!pos)
+ break;
+
+ *pos = '\0';
+ }
+
+ talloc_free(cur);
+
+ return 0;
+}
+
+/**
+ * pb_run_cmd - Run the supplied command.
+ * @cmd_argv: An argument list array for execv.
+ */
+
+int pb_run_cmd(const char *const *cmd_argv)
+{
+ int status;
+ pid_t pid;
+#if defined(DEBUG)
+ enum {do_debug = 1};
+#else
+ enum {do_debug = 0};
+#endif
+
+ if (do_debug) {
+ const char *const *p = cmd_argv;
+
+ pb_log("%s: ", __func__);
+ while (*p) {
+ pb_log("%s ", *p);
+ p++;
+ }
+ pb_log("\n");
+ } else
+ pb_log("%s: %s\n", __func__, cmd_argv[0]);
+
+ pid = fork();
+ if (pid == -1) {
+ pb_log("%s: fork failed: %s\n", __func__, strerror(errno));
+ return -1;
+ }
+
+ if (pid == 0) {
+ execvp(cmd_argv[0], (char *const *)cmd_argv);
+ pb_log("%s: exec failed: %s\n", __func__, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ if (waitpid(pid, &status, 0) == -1) {
+ pb_log("%s: waitpid failed: %s\n", __func__,
+ strerror(errno));
+ return -1;
+ }
+
+ if (do_debug && WIFSIGNALED(status) && WTERMSIG(status) == SIGINT)
+ pb_log("%s: signaled\n", __func__);
+
+ if (!WIFEXITED(status)) {
+ pb_log("%s: %s failed\n", __func__, cmd_argv[0]);
+ return -1;
+ }
+
+ if (WEXITSTATUS(status))
+ pb_log("%s: WEXITSTATUS %d\n", __func__, WEXITSTATUS(status));
+
+ return WEXITSTATUS(status);
+}
diff --git a/lib/system/system.h b/lib/system/system.h
new file mode 100644
index 0000000..47c7c02
--- /dev/null
+++ b/lib/system/system.h
@@ -0,0 +1,20 @@
+#if !defined(_PB_LIB_SYSTEM_H)
+#define _PB_LIB_SYSTEM_H
+
+struct pb_system_apps {
+ const char *cp;
+ const char *kexec;
+ const char *mount;
+ const char *sftp;
+ const char *tftp;
+ const char *umount;
+ const char *wget;
+};
+
+extern const struct pb_system_apps pb_system_apps;
+
+int pb_run_cmd(const char *const *cmd_argv);
+int pb_mkdir_recursive(const char *dir);
+int pb_rmdir_recursive(const char *base, const char *dir);
+
+#endif
diff --git a/rules.mk b/rules.mk
index 097daae..1790db1 100644
--- a/rules.mk
+++ b/rules.mk
@@ -33,6 +33,7 @@ rules = utils/99-petitboot.rules
list_objs = lib/list/list.o
log_objs = lib/log/log.o
protocol_objs = lib/pb-protocol/pb-protocol.o
+system_objs = lib/system/system.o
talloc_objs = lib/talloc/talloc.o
waiter_objs = lib/waiter/waiter.o
@@ -51,8 +52,8 @@ twin_objs = ui/twin/pb-twin.o
makefiles = Makefile $(top_srcdir)/rules.mk
# object collections
-lib_objs = $(list_objs) $(log_objs) $(protocol_objs) $(talloc_objs) \
- $(waiter_objs)
+lib_objs = $(list_objs) $(log_objs) $(protocol_objs) $(system_objs) \
+ $(talloc_objs) $(waiter_objs)
daemon_objs = $(lib_objs) $(parser_objs) $(discover_objs)
OpenPOWER on IntegriCloud