diff options
author | Geoff Levand <geoffrey.levand@am.sony.com> | 2009-04-12 15:11:48 +0000 |
---|---|---|
committer | Jeremy Kerr <jk@ozlabs.org> | 2009-06-30 15:29:15 +0800 |
commit | b3e1a66f23b7338d88e0668b8cf10ffe139a9a03 (patch) | |
tree | 66d897b15282e574e9823c45dedf92a257fd1636 | |
parent | dc13479d33efc6cf4b55bfd7b4875c44e4a9bbd0 (diff) | |
download | talos-petitboot-b3e1a66f23b7338d88e0668b8cf10ffe139a9a03.tar.gz talos-petitboot-b3e1a66f23b7338d88e0668b8cf10ffe139a9a03.zip |
Move common system routines to lib
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>
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | lib/system/system.c | 157 | ||||
-rw-r--r-- | lib/system/system.h | 20 | ||||
-rw-r--r-- | rules.mk | 5 |
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 @@ -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) |