From: Roy Marples Date: Mon, 14 Apr 2008 15:08:46 +0000 (+0000) Subject: Replace the clean_metas functions with a write_string function. The main difference... X-Git-Tag: v4.0.2~490 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=46bd6451b0fd285a28a6079045bb5b964f657f65;p=thirdparty%2Fdhcpcd.git Replace the clean_metas functions with a write_string function. The main difference is that we escape non ascii or printable chars and avoid mallocing. --- diff --git a/configure.c b/configure.c index 0f11b3c1..215ea2fe 100644 --- a/configure.c +++ b/configure.c @@ -339,14 +339,10 @@ configure_routes(struct interface *iface, const struct dhcp_message *dhcp, static void print_clean(FILE *f, const char *name, const char *value) { - char *clean; - - if (! value) - return; - - clean = clean_metas(value); - fprintf(f, "%s='%s'\n", name, clean); - free(clean); + fprintf(f, "%s=", name); + if (value) + write_string(f, (const uint8_t*)value, strlen(value)); + fputc('\n', f); } int @@ -371,42 +367,42 @@ write_info(const struct interface *iface, const struct dhcp_message *dhcp, } if (dhcp->yiaddr) { - fprintf(f, "IPADDR='%s'\n", inet_ntoa(iface->addr)); - fprintf(f, "NETMASK='%s'\n", inet_ntoa(iface->net)); + fprintf(f, "IPADDR=%s\n", inet_ntoa(iface->addr)); + fprintf(f, "NETMASK=%s\n", inet_ntoa(iface->net)); addr.s_addr = dhcp->yiaddr & iface->net.s_addr; - fprintf(f, "NETWORK='%s'\n", inet_ntoa(addr)); + fprintf(f, "NETWORK=%s\n", inet_ntoa(addr)); if (get_option_addr(&addr.s_addr, dhcp, DHCP_BROADCAST) == -1) addr.s_addr = dhcp->yiaddr | ~iface->net.s_addr; - fprintf(f, "BROADCAST='%s'\n", inet_ntoa(addr)); + fprintf(f, "BROADCAST=%s\n", inet_ntoa(addr)); ort = get_option_routes(dhcp); doneone = 0; - fprintf(f, "ROUTES='"); + fprintf(f, "ROUTES="); for (rt = ort; rt; rt = rt->next) { if (rt->dest.s_addr == 0) continue; if (doneone) - fputc(' ', f); + fprintf(f, "\\ "); else doneone = 1; fprintf(f, "%s", inet_ntoa(rt->dest)); fprintf(f, ",%s", inet_ntoa(rt->net)); fprintf(f, ",%s", inet_ntoa(rt->gate)); } - fprintf(f, "'\n"); + fputc('\n', f); doneone = 0; - fprintf(f, "GATEWAYS='"); + fprintf(f, "GATEWAYS="); for (rt = ort; rt; rt = rt->next) { if (rt->dest.s_addr != 0) continue; if (doneone) - fputc(' ', f); + fprintf(f, "\\ "); else doneone = 1; fprintf(f, "%s", inet_ntoa(rt->gate)); } - fprintf(f, "'\n"); + fputc('\n', f); free_routes(ort); } @@ -422,25 +418,25 @@ write_info(const struct interface *iface, const struct dhcp_message *dhcp, */ if (dhcp->siaddr) { addr.s_addr = dhcp->siaddr; - fprintf(f, "DHCPSID='%s'\n", inet_ntoa(addr)); + fprintf(f, "DHCPSID=%s\n", inet_ntoa(addr)); } if (dhcp->servername[0]) print_clean(f, "DHCPSNAME", (const char *)dhcp->servername); if (!(options->options & DHCPCD_INFORM) && dhcp->yiaddr) { if (!(options->options & DHCPCD_TEST)) - fprintf(f, "LEASEDFROM='%u'\n", lease->leasedfrom); - fprintf(f, "LEASETIME='%u'\n", lease->leasetime); - fprintf(f, "RENEWALTIME='%u'\n", lease->renewaltime); - fprintf(f, "REBINDTIME='%u'\n", lease->rebindtime); + fprintf(f, "LEASEDFROM=%u\n", lease->leasedfrom); + fprintf(f, "LEASETIME=%u\n", lease->leasetime); + fprintf(f, "RENEWALTIME=%u\n", lease->renewaltime); + fprintf(f, "REBINDTIME=%u\n", lease->rebindtime); } print_clean(f, "INTERFACE", iface->name); print_clean(f, "CLASSID", options->classid); if (iface->clientid_len > 0) { - fprintf(f, "CLIENTID='%s'\n", + fprintf(f, "CLIENTID=%s\n", hwaddr_ntoa(iface->clientid, iface->clientid_len)); } - fprintf(f, "DHCPCHADDR='%s'\n", + fprintf(f, "DHCPCHADDR=%s\n", hwaddr_ntoa(iface->hwaddr, iface->hwlen)); if (!(options->options & DHCPCD_TEST)) diff --git a/dhcp.c b/dhcp.c index d328acb1..9655f090 100644 --- a/dhcp.c +++ b/dhcp.c @@ -25,6 +25,7 @@ * SUCH DAMAGE. */ +#include #include #include #include @@ -101,7 +102,7 @@ const struct dhcp_option dhcp_options[] = { { DHCP_NISDOMAIN, IPV4, "NISDOMAIN" }, { DHCP_NISSERVER, IPV4, "NISSERVER" }, { DHCP_NTPSERVER, IPV4, "NTPSERVER" }, - { DHCP_VENDORSPECIFICINFO, 0, "VENDORSPECIFICINFO" }, + { DHCP_VENDORSPECIFICINFO, STRING, "VENDORSPECIFICINFO" }, { DHCP_NETBIOSNAMESERVER, IPV4, "NETBIOSNAMESERVER" }, { DHCP_NETBIOSDGRAMSERVER, IPV4, "NETBIOSDGRAMSERVER" }, { DHCP_NETBIOSNODETYPE, UINT8, "NETBIOSNODETYPE" }, @@ -177,7 +178,7 @@ valid_length(uint8_t option, const uint8_t *data, int *type) if (type) *type = t; - if (dhcp_options[i].type & STRING) + if (t == 0 || t & STRING) return 0; sz = 0; @@ -830,39 +831,36 @@ read_lease(const struct interface *iface) return dhcp; } -/* Create a malloced string of cstr, changing ' to '\'' - * so the contents work in a shell */ -char * -clean_metas(const char *cstr) +ssize_t +write_string(FILE *f, const uint8_t *data, ssize_t len) { - const char *p = cstr; - char *new; - char *n; - size_t len; - size_t pos; - - if (cstr == NULL || (len = strlen(cstr)) == 0) - return (xstrdup("")); - - n = new = xmalloc(sizeof(char) * len + 2); - do - if (*p == '\'') { - pos = n - new; - len += 4; - new = xrealloc(new, sizeof(char) * len + 1); - n = new + pos; - *n++ = '\''; - *n++ = '\\'; - *n++ = '\''; - *n++ = '\''; - } else - *n++ = *p; - while (*p++); - - /* Terminate the sucker */ - *n = '\0'; - - return new; + uint8_t c; + const uint8_t *e; + ssize_t bytes = 0; + + if (!len) + len = *data++; + e = data + len; + while (data < e) { + c = *data++; + if (!isascii(c) || !isprint(c)) { + bytes += fprintf(f, "\\%03o", c); + continue; + } + switch (c) { + case '"': /* FALLTHROUGH */ + case '\'': /* FALLTHROUGH */ + case '$': /* FALLTHROUGH */ + case '`': /* FALLTHROUGH */ + case '\\': /* FALLTHROUGH */ + case ' ': /* FALLTHROUGH */ + if (fputc('\\', f)) + bytes++; + } + if (fputc(c, f)) + bytes++; + } + return bytes; } ssize_t @@ -870,8 +868,6 @@ write_options(FILE *f, const struct dhcp_message *dhcp) { uint8_t i; const uint8_t *p, *e, *t; - char *s; - char *c; uint32_t u32; uint16_t u16; uint8_t u8; @@ -879,32 +875,16 @@ write_options(FILE *f, const struct dhcp_message *dhcp) ssize_t retval = 0; for (i = 0; i < sizeof(dhcp_options) / sizeof(dhcp_options[0]); i++) { - if (!dhcp_options[i].var || !dhcp_options[i].type) + if (!dhcp_options[i].var) continue; - retval += fprintf(f, "%s='", dhcp_options[i].var); + retval += fprintf(f, "%s=", dhcp_options[i].var); /* Unknown type, so just print escape codes */ - if (dhcp_options[i].type == 0) { + if (dhcp_options[i].type == STRING) { p = get_option(dhcp, dhcp_options[i].option); - if (p) { - u8 = *p++; - e = p + u8; - while (p < e) { - u8 = *p++; - retval += fprintf(f, "\\%03d", u8); - } - } - } - - if (dhcp_options[i].type & STRING) { - s = get_option_string(dhcp, dhcp_options[i].option); - if (s) { - c = clean_metas(s); - retval += fprintf(f, "%s", c); - free(c); - free(s); - } + if (p) + retval += write_string(f, p, 0); } if ((dhcp_options[i].type & IPV4 || @@ -915,17 +895,19 @@ write_options(FILE *f, const struct dhcp_message *dhcp) t = p; e = p + u8; while (p < e) { - if (t != p) - retval += fprintf(f, " "); + if (p != t) + retval += fprintf(f, "\\ "); if (dhcp_options[i].type & UINT8) { retval += fprintf(f, "%d", *p); p++; } else if (dhcp_options[i].type & UINT16) { memcpy(&u16, p, sizeof(u16)); + u16 = ntohs(u16); retval += fprintf(f, "%d", *p); p += sizeof(u16); } else if (dhcp_options[i].type & UINT32) { memcpy(&u32, p, sizeof(u32)); + u32 = ntohl(u32); retval += fprintf(f, "%d", *p); p += sizeof(u32); } else if (dhcp_options[i].type & IPV4) { @@ -952,7 +934,7 @@ write_options(FILE *f, const struct dhcp_message *dhcp) retval += fprintf(f, "%d", u16); } - retval += fprintf(f, "'\n"); + retval += fprintf(f, "\n"); } return retval; } diff --git a/dhcp.h b/dhcp.h index 3031ff5d..879cff72 100644 --- a/dhcp.h +++ b/dhcp.h @@ -215,11 +215,11 @@ struct dhcp_lease { int make_reqmask(struct options *options, char **opts); const uint8_t *get_option(const struct dhcp_message *, uint8_t); char *get_option_string(const struct dhcp_message *, uint8_t); -int get_option_addr(uint32_t *a, const struct dhcp_message *dhcp, uint8_t option); -int get_option_uint32(uint32_t *i, const struct dhcp_message *dhcp, uint8_t option); -int get_option_uint16(uint16_t *i, const struct dhcp_message *dhcp, uint8_t option); -int get_option_uint8(uint8_t *i, const struct dhcp_message *dhcp, uint8_t option); -struct rt *get_option_routes(const struct dhcp_message *dhcp); +int get_option_addr(uint32_t *, const struct dhcp_message *, uint8_t); +int get_option_uint32(uint32_t *, const struct dhcp_message *, uint8_t); +int get_option_uint16(uint16_t *, const struct dhcp_message *, uint8_t); +int get_option_uint8(uint8_t *, const struct dhcp_message *, uint8_t); +struct rt *get_option_routes(const struct dhcp_message *); struct rt *decode_rfc3442(const uint8_t *); ssize_t make_message(struct dhcp_message **, const struct interface *, const struct dhcp_lease *, @@ -229,6 +229,6 @@ int valid_dhcp_packet(unsigned char *); ssize_t write_lease(const struct interface *, const struct dhcp_message *); struct dhcp_message *read_lease(const struct interface *iface); -char *clean_metas(const char *cstr); -ssize_t write_options(FILE *f, const struct dhcp_message *dhcp); +ssize_t write_string(FILE *f, const uint8_t *, ssize_t); +ssize_t write_options(FILE *f, const struct dhcp_message *); #endif