logerr("ps_init");
goto exit_failure;
}
+ script_runchroot(&ctx, ifo->script);
#endif
#ifdef USE_SIGNALS
goto exit_failure;
}
+ /* Start any dev listening plugin which may want to
+ * change the interface name provided by the kernel */
+ if ((ctx.options & (DHCPCD_MASTER | DHCPCD_DEV)) ==
+ (DHCPCD_MASTER | DHCPCD_DEV))
+ dev_start(&ctx);
+
#ifdef PRIVSEP
if (ctx.options & DHCPCD_PRIVSEP && ps_dropprivs(&ctx) == -1) {
logerr("ps_dropprivs");
* routes. */
eloop_event_add(ctx.eloop, ctx.link_fd, dhcpcd_handlelink, &ctx);
- /* Start any dev listening plugin which may want to
- * change the interface name provided by the kernel */
- if ((ctx.options & (DHCPCD_MASTER | DHCPCD_DEV)) ==
- (DHCPCD_MASTER | DHCPCD_DEV))
- dev_start(&ctx);
-
ctx.ifaces = if_discover(&ctx, &ifaddrs, ctx.ifc, ctx.ifv);
if (ctx.ifaces == NULL) {
logerr("%s: if_discover", __func__);
#include <assert.h>
#include <ctype.h>
#include <errno.h>
+#include <pwd.h>
#include <signal.h>
#include <spawn.h>
#include <stdarg.h>
}
static long
-make_env(const struct interface *ifp, const char *reason)
+make_env(struct dhcpcd_ctx *ctx, const struct interface *ifp,
+ const char *reason)
{
- struct dhcpcd_ctx *ctx = ifp->ctx;
FILE *fp;
long buf_pos, i;
char *path;
int protocol = PROTO_LINK;
- const struct if_options *ifo = ifp->options;
+ const struct if_options *ifo;
const struct interface *ifp2;
int af;
#ifdef INET
}
#endif
+ /* Needed for scripts */
+ path = getenv("PATH");
+ if (efprintf(fp, "PATH=%s", path == NULL ? DEFAULT_PATH:path) == -1)
+ goto eexit;
+ if (efprintf(fp, "reason=%s", reason) == -1)
+ goto eexit;
+ if (efprintf(fp, "pid=%d", getpid()) == -1)
+ goto eexit;
+
+#ifdef PRIVSEP
+ if (strcmp(reason, "CHROOT") == 0) {
+ if (efprintf(fp, "chroot=%s", ctx->ps_user->pw_dir) == -1)
+ goto eexit;
+ goto make;
+ }
+#endif
+
+ ifo = ifp->options;
#ifdef INET
state = D_STATE(ifp);
#ifdef IPV4LL
protocol = PROTO_DHCP;
#endif
- /* Needed for scripts */
- path = getenv("PATH");
- if (efprintf(fp, "PATH=%s", path == NULL ? DEFAULT_PATH:path) == -1)
- goto eexit;
if (efprintf(fp, "interface=%s", ifp->name) == -1)
goto eexit;
- if (efprintf(fp, "reason=%s", reason) == -1)
- goto eexit;
if (ifp->ctx->options & DHCPCD_DUMPLEASE)
goto dumplease;
- if (efprintf(fp, "pid=%d", getpid()) == -1)
- goto eexit;
if (efprintf(fp, "ifcarrier=%s",
ifp->carrier == LINK_UNKNOWN ? "unknown" :
ifp->carrier == LINK_UP ? "up" : "down") == -1)
goto eexit;
}
+make:
/* Convert buffer to argv */
fflush(fp);
struct dhcpcd_ctx *ctx = ifp->ctx;
long len;
- len = make_env(ifp, reason);
+ len = make_env(ifp->ctx, ifp, reason);
if (len == -1)
return -1;
return control_queue(fd, ctx->script_buf, (size_t)len, 1);
return retval;
}
+static int
+script_run(struct dhcpcd_ctx *ctx, char **argv)
+{
+ pid_t pid;
+ int status = 0;
+
+ pid = script_exec(ctx, argv, ctx->script_env);
+ if (pid == -1)
+ logerr("%s: %s", __func__, argv[0]);
+ else if (pid != 0) {
+ /* Wait for the script to finish */
+ while (waitpid(pid, &status, 0) == -1) {
+ if (errno != EINTR) {
+ logerr("%s: waitpid", __func__);
+ status = 0;
+ break;
+ }
+ }
+ if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status))
+ logerrx("%s: %s: WEXITSTATUS %d",
+ __func__, argv[0], WEXITSTATUS(status));
+ } else if (WIFSIGNALED(status))
+ logerrx("%s: %s: %s",
+ __func__, argv[0], strsignal(WTERMSIG(status)));
+ }
+
+ return WEXITSTATUS(status);
+}
+
int
script_runreason(const struct interface *ifp, const char *reason)
{
struct dhcpcd_ctx *ctx = ifp->ctx;
char *argv[2];
- pid_t pid;
int status = 0;
struct fd_list *fd;
return 0;
/* Make our env */
- if (make_env(ifp, reason) == -1) {
+ if (make_env(ifp->ctx, ifp, reason) == -1) {
logerr(__func__);
return -1;
}
}
#endif
- pid = script_exec(ctx, argv, ctx->script_env);
- if (pid == -1)
- logerr("%s: %s", __func__, argv[0]);
- else if (pid != 0) {
- /* Wait for the script to finish */
- while (waitpid(pid, &status, 0) == -1) {
- if (errno != EINTR) {
- logerr("%s: waitpid", __func__);
- status = 0;
- break;
- }
- }
- if (WIFEXITED(status)) {
- if (WEXITSTATUS(status))
- logerrx("%s: %s: WEXITSTATUS %d",
- __func__, argv[0], WEXITSTATUS(status));
- } else if (WIFSIGNALED(status))
- logerrx("%s: %s: %s",
- __func__, argv[0], strsignal(WTERMSIG(status)));
- }
+ status = script_run(ctx, argv);
send_listeners:
/* Send to our listeners */
status = 1;
}
- return WEXITSTATUS(status);
+ return status;
+}
+
+#ifdef PRIVSEP
+int
+script_runchroot(struct dhcpcd_ctx *ctx, char *script)
+{
+ char *argv[2];
+
+ /* Make our env */
+ if (make_env(ctx, NULL, "CHROOT") == -1) {
+ logerr(__func__);
+ return -1;
+ }
+
+ argv[0] = script;
+ argv[1] = NULL;
+ logdebugx("executing `%s' %s", argv[0], "CHROOT");
+
+ return script_run(ctx, argv);
}
+#endif