vlen = strlen(var);
p = NULL;
while (data + vlen + 1 < end) {
- if (strncmp(data, var, vlen) == 0) {
- p = data + vlen;
+ /* Skip past NUL padding */
+ if (*data == '\0') {
+ data++;
+ continue;
+ }
+ if (strncmp(data, var, vlen) == 0 && data[vlen] == '=') {
+ p = data + vlen + 1;
break;
}
data += strlen(data) + 1;
}
ssize_t
-dhcpcd_decode(char *dst, size_t dlen, const char *src)
+dhcpcd_encode_string_escape(char *dst, size_t len, const char *src, size_t slen)
+{
+ const char *end;
+ size_t bytes;
+ char c;
+
+ end = src + slen;
+ bytes = 0;
+ while (src < end) {
+ c = *src++;
+ if ((c == '\\' || !isascii(c) || !isprint(c))) {
+ if (c == '\\') {
+ if (dst) {
+ if (len == 0 || len == 1) {
+ errno = ENOSPC;
+ return -1;
+ }
+ *dst++ = '\\'; *dst++ = '\\';
+ len -= 2;
+ }
+ bytes += 2;
+ continue;
+ }
+ if (dst) {
+ if (len < 5) {
+ errno = ENOSPC;
+ return -1;
+ }
+ *dst++ = '\\';
+ *dst++ = (((unsigned char)c >> 6) & 03) + '0';
+ *dst++ = (((unsigned char)c >> 3) & 07) + '0';
+ *dst++ = ( (unsigned char)c & 07) + '0';
+ len -= 4;
+ }
+ bytes += 4;
+ } else {
+ if (dst) {
+ if (len == 0) {
+ errno = ENOSPC;
+ return -1;
+ }
+ *dst++ = (char)c;
+ len--;
+ }
+ bytes++;
+ }
+ }
+
+ if (dst) {
+ if (len == 0) {
+ errno = ENOSPC;
+ return -1;
+ }
+ *dst = '\0';
+ }
+ bytes++;
+
+ return (ssize_t)bytes;
+}
+
+ssize_t
+dhcpcd_decode_string_escape(char *dst, size_t dlen, const char *src)
{
+ char c, esc;
+ int oct;
+ ssize_t bytes;
- assert(dst);
- assert(src);
- return strnunvis(dst, dlen, src);
+ bytes = 0;
+ for (;;) {
+ c = *src++;
+ if (c == '\0')
+ break;
+ if (dst && --dlen == 0) {
+ errno = ENOSPC;
+ return 0;
+ }
+ switch (c) {
+ case '\\':
+ if (*src == '\0') {
+ errno = EINVAL;
+ return -1;
+ }
+ esc = *src++;
+ switch (esc) {
+ case '\\':
+ case '0':
+ case '1':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ oct = esc - '0';
+ if (*src >= '0' && *src <='7')
+ oct = oct * 8 + (*src++ - '0');
+ else {
+ errno = EINVAL;
+ return -1;
+ }
+ if (*src >= '0' && *src <='7')
+ oct = oct * 8 + (*src++ - '0');
+ else {
+ errno = EINVAL;
+ return -1;
+ }
+ if (dst)
+ *dst++ = (char)oct;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ break;
+ default:
+ if (dst)
+ *dst++ = c;
+ }
+ bytes++;
+ }
+ return bytes;
}
ssize_t
return (ssize_t)bytes;
}
-ssize_t
-dhcpcd_encode(char *dst, size_t dlen, const char *src, size_t slen)
-{
- char *d, c, v[5], *ve, *vp;
- const char *send;
-
- d = dst;
- send = src + slen;
- while (src < send) {
- c = *src++;
- ve = vis(v, c, VIS_OCTAL | VIS_CSTYLE, src != send ? *src : 0);
- if (dlen < (size_t)(ve - v) + 1) {
- errno = ENOSPC;
- return -1;
- }
- dlen -= (size_t)(ve - v);
- vp = v;
- while (vp != ve)
- *d++ = *vp++;
- }
- *d = '\0';
-
- return d - dst;
-}
-
-ssize_t
-dhcpcd_decode_shell(char *dst, size_t dlen, const char *src)
-{
- char *tmp;
- ssize_t l;
-
- assert(dst);
- assert(src);
-
- tmp = malloc(dlen);
- if (tmp == NULL)
- return -1;
- if ((l = dhcpcd_decode(tmp, dlen, src)) != -1)
- l = dhcpcd_encode(dst, dlen, tmp, (size_t)l);
-
- free(tmp);
- return l;
-}
-
const char *
dhcpcd_get_prefix_value(const DHCPCD_IF *i, const char *prefix, const char *var)
{
static DHCPCD_IF *
dhcpcd_new_if(DHCPCD_CONNECTION *con, char *data, size_t len)
{
- const char *ifname, *ifclass, *reason, *type, *order, *flags, *ssid;
+ const char *ifname, *ifclass, *reason, *type, *order, *flags;
char *orderdup, *o, *p;
DHCPCD_IF *e, *i, *l, *n, *nl;
int ti;
bool addedi;
- ifname = get_value(data, len, "interface=");
+ ifname = get_value(data, len, "interface");
if (ifname == NULL || *ifname == '\0') {
errno = ESRCH;
return NULL;
}
- reason = get_value(data, len, "reason=");
+ reason = get_value(data, len, "reason");
if (reason == NULL || *reason == '\0') {
errno = ESRCH;
return NULL;
}
- ifclass = get_value(data, len, "ifclass=");
+ ifclass = get_value(data, len, "ifclass");
/* Skip pseudo interfaces */
if (ifclass && *ifclass != '\0') {
errno = ENOTSUP;
errno = ENOTSUP;
return NULL;
}
- order = get_value(data, len, "interface_order=");
+ order = get_value(data, len, "interface_order");
if (order == NULL || *order == '\0') {
errno = ESRCH;
return NULL;
i->ifname = ifname;
i->type = type;
i->reason = reason;
- flags = dhcpcd_get_value(i, "ifflags=");
+ flags = dhcpcd_get_value(i, "ifflags");
if (flags)
i->flags = (unsigned int)strtoul(flags, NULL, 0);
else
if (strcmp(reason, "CARRIER") == 0)
i->up = true;
else
- i->up = strtobool(dhcpcd_get_value(i, "if_up="));
- i->wireless = strtobool(dhcpcd_get_value(i, "ifwireless="));
- ssid = dhcpcd_get_value(i, i->up ? "new_ssid=" : "old_ssid=");
- if (ssid == NULL ||
- dhcpcd_decode_shell(i->ssid, sizeof(i->ssid), ssid) == -1)
- *i->ssid = '\0';
+ i->up = strtobool(dhcpcd_get_value(i, "if_up"));
+ i->wireless = strtobool(dhcpcd_get_value(i, "ifwireless"));
+ i->ssid = dhcpcd_get_value(i, "ifssid");
/* Sort! */
n = nl = NULL;
assert(i);
/* Don't report non SLAAC configurations */
if (strcmp(i->type, "ra") == 0 && i->up &&
- dhcpcd_get_value(i, "ra1_prefix=") == NULL)
+ dhcpcd_get_value(i, "ra1_prefix") == NULL)
return NULL;
showssid = false;
}
pfx = i->up ? "new_" : "old_";
- if ((ip = dhcpcd_get_prefix_value(i, pfx, "ip_address=")))
- iplen = dhcpcd_get_prefix_value(i, pfx, "subnet_cidr=");
- else if ((ip = dhcpcd_get_value(i, "ra1_prefix=")))
+ if ((ip = dhcpcd_get_prefix_value(i, pfx, "ip_address")))
+ iplen = dhcpcd_get_prefix_value(i, pfx, "subnet_cidr");
+ else if ((ip = dhcpcd_get_value(i, "ra1_prefix")))
iplen = NULL;
else if ((ip = dhcpcd_get_prefix_value(i, pfx,
- "dhcp6_ia_na1_ia_addr1=")))
+ "dhcp6_ia_na1_ia_addr1")))
iplen = "128";
else {
ip = NULL;