From b3e1a66f23b7338d88e0668b8cf10ffe139a9a03 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Sun, 12 Apr 2009 15:11:48 +0000 Subject: 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 Signed-off-by: Jeremy Kerr --- lib/system/system.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 lib/system/system.c (limited to 'lib/system/system.c') 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 +#include +#include +#include +#include +#include +#include + +#include "log/log.h" +#include +#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); +} -- cgit v1.2.1