Move common system routines to lib
authorGeoff Levand <geoffrey.levand@am.sony.com>
Sun, 12 Apr 2009 15:11:48 +0000 (15:11 +0000)
committerJeremy Kerr <jk@ozlabs.org>
Tue, 30 Jun 2009 07:29:15 +0000 (15:29 +0800)
Move some of the common system operations to lib system routines.
Creates these common routines:

  pb_mkdir_recursive()
  pb_rmdir_recursive()
  pb_run_cmd()

Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
configure.ac
lib/system/system.c [new file with mode: 0644]
lib/system/system.h [new file with mode: 0644]
rules.mk

index 340cdbf8da0ed0bd7aa4c2e361efc47246a3ed3b..c67f0ed927fd09cdfc2681e4011bff105b3cc942 100644 (file)
@@ -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 (file)
index 0000000..380dded
--- /dev/null
@@ -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 (file)
index 0000000..47c7c02
--- /dev/null
@@ -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
index 097daaee50cdd2e210fdc3457e338935a8615806..1790db1ecdd0a4991f84009c364ad1b99a8cd2a4 100644 (file)
--- 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)