summaryrefslogtreecommitdiffstats
path: root/src/ipv6nd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2019-06-18 11:33:53 +0100
committerRoy Marples <roy@marples.name>2019-06-18 11:33:53 +0100
commitae3c3144861a285e77d69e888cd7cd732fb2d7a1 (patch)
treed692e469c71cd8f9e64a0fb62d701ae48bbbfc5e /src/ipv6nd.c
parent6da1356363264bcfb6237797965ef59c234fa795 (diff)
downloaddhcpcd-ae3c3144861a285e77d69e888cd7cd732fb2d7a1.tar.xz
script: Write variables to a FILE
Each variable is NULL terminated inside the file just like the control stream which saves us from having to flatten it when writing to the control stream. Once written, create env pointers to the start of each string just after the NULL terminator. This also means that we just need to free two buffers when dhcpcd exits (FILE buffer and env buffer) rather than each variable individually. If open_memstream(3) is not supported by libc then dhcpcd will write to a file in /tmp instead.
Diffstat (limited to 'src/ipv6nd.c')
-rw-r--r--src/ipv6nd.c70
1 files changed, 28 insertions, 42 deletions
diff --git a/src/ipv6nd.c b/src/ipv6nd.c
index 5ece711e..b879c171 100644
--- a/src/ipv6nd.c
+++ b/src/ipv6nd.c
@@ -1384,11 +1384,11 @@ ipv6nd_getoption(struct dhcpcd_ctx *ctx,
}
ssize_t
-ipv6nd_env(char **env, const char *prefix, const struct interface *ifp)
+ipv6nd_env(FILE *fp, const struct interface *ifp)
{
size_t i, j, n, len, olen;
struct ra *rap;
- char ndprefix[32], abuf[24];
+ char ndprefix[32];
struct dhcp_opt *opt;
uint8_t *p;
struct nd_opt_hdr ndo;
@@ -1401,34 +1401,24 @@ ipv6nd_env(char **env, const char *prefix, const struct interface *ifp)
if (rap->iface != ifp)
continue;
i++;
- if (prefix != NULL)
- snprintf(ndprefix, sizeof(ndprefix),
- "%s_nd%zu", prefix, i);
- else
- snprintf(ndprefix, sizeof(ndprefix),
- "nd%zu", i);
- if (env)
- setvar(&env[n], ndprefix, "from", rap->sfrom);
- n++;
- if (env)
- setvard(&env[n], ndprefix, "acquired",
- (size_t)rap->acquired.tv_sec);
- n++;
- if (env)
- setvard(&env[n], ndprefix, "now", (size_t)now.tv_sec);
- n++;
+ snprintf(ndprefix, sizeof(ndprefix), "nd%zu", i);
+ if (efprintf(fp, "%s_from=%s", ndprefix, rap->sfrom) == -1)
+ return -1;
+ if (efprintf(fp, "%s_acquired=%ld", ndprefix,
+ rap->acquired.tv_sec) == -1)
+ return -1;
+ if (efprintf(fp, "%s_now=%ld", ndprefix, now.tv_sec) == -1)
+ return -1;
/* Zero our indexes */
- if (env) {
- for (j = 0, opt = rap->iface->ctx->nd_opts;
- j < rap->iface->ctx->nd_opts_len;
- j++, opt++)
- dhcp_zero_index(opt);
- for (j = 0, opt = rap->iface->options->nd_override;
- j < rap->iface->options->nd_override_len;
- j++, opt++)
- dhcp_zero_index(opt);
- }
+ for (j = 0, opt = rap->iface->ctx->nd_opts;
+ j < rap->iface->ctx->nd_opts_len;
+ j++, opt++)
+ dhcp_zero_index(opt);
+ for (j = 0, opt = rap->iface->options->nd_override;
+ j < rap->iface->options->nd_override_len;
+ j++, opt++)
+ dhcp_zero_index(opt);
/* Unlike DHCP, ND6 options *may* occur more than once.
* There is also no provision for option concatenation
@@ -1461,13 +1451,12 @@ ipv6nd_env(char **env, const char *prefix, const struct interface *ifp)
if (j == rap->iface->ctx->nd_opts_len)
opt = NULL;
}
- if (opt) {
- n += dhcp_envoption(rap->iface->ctx,
- env == NULL ? NULL : &env[n],
- ndprefix, rap->iface->name,
- opt, ipv6nd_getoption,
- p + sizeof(ndo), olen - sizeof(ndo));
- }
+ if (opt == NULL)
+ continue;
+ dhcp_envoption(rap->iface->ctx, fp,
+ ndprefix, rap->iface->name,
+ opt, ipv6nd_getoption,
+ p + sizeof(ndo), olen - sizeof(ndo));
}
/* We need to output the addresses we actually made
@@ -1481,15 +1470,12 @@ ipv6nd_env(char **env, const char *prefix, const struct interface *ifp)
!(ia->flags & IPV6_AF_ADDED) ||
ia->prefix_vltime == 0)
continue;
- j++;
- if (env) {
- snprintf(abuf, sizeof(abuf), "addr%zu", j);
- setvar(&env[n], ndprefix, abuf, ia->saddr);
- }
- n++;
+ if (efprintf(fp, "%s_addr%zu=%s",
+ ndprefix, j++, ia->saddr) == -1)
+ return -1;
}
}
- return (ssize_t)n;
+ return 1;
}
void