int config_parse_label(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { Network *network = userdata; _cleanup_address_free_ Address *n = NULL; char *label; int r; assert(filename); assert(section); assert(lvalue); assert(rvalue); assert(data); r = address_new_static(network, section_line, &n); if (r < 0) return r; label = strdup(rvalue); if (!label) return log_oom(); if (!ascii_is_valid(label) || strlen(label) >= IFNAMSIZ) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Interface label is not ASCII clean or is too" " long, ignoring assignment: %s", rvalue); free(label); return 0; } free(n->label); if (*label) n->label = label; else { free(label); n->label = NULL; } n = NULL; return 0; }
static bool valid_machine_name(const char *p) { size_t l; if (!filename_is_safe(p)) return false; if (!ascii_is_valid(p)) return false; l = strlen(p); if (l < 1 || l> 64) return false; return true; }
int config_parse_ifname(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { char **s = data; char *n; assert(filename); assert(lvalue); assert(rvalue); assert(data); n = strdup(rvalue); if (!n) return log_oom(); if (!ascii_is_valid(n) || strlen(n) >= IFNAMSIZ) { log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Interface name is not ASCII clean or is too long, ignoring assignment: %s", rvalue); free(n); return 0; } free(*s); if (*n) *s = n; else { free(n); *s = NULL; } return 0; }
static int parse_options(const uint8_t options[], size_t buflen, uint8_t *overload, uint8_t *message_type, char **error_message, dhcp_option_cb_t cb, void *userdata) { uint8_t code, len; const uint8_t *option; size_t offset = 0; while (offset < buflen) { code = options[offset ++]; switch (code) { case DHCP_OPTION_PAD: continue; case DHCP_OPTION_END: return 0; } if (buflen < offset + 1) return -ENOBUFS; len = options[offset ++]; if (buflen < offset + len) return -EINVAL; option = &options[offset]; switch (code) { case DHCP_OPTION_MESSAGE_TYPE: if (len != 1) return -EINVAL; if (message_type) *message_type = *option; break; case DHCP_OPTION_ERROR_MESSAGE: if (len == 0) return -EINVAL; if (error_message) { _cleanup_free_ char *string = NULL; /* Accept a trailing NUL byte */ if (memchr(option, 0, len - 1)) return -EINVAL; string = strndup((const char *) option, len); if (!string) return -ENOMEM; if (!ascii_is_valid(string)) return -EINVAL; free(*error_message); *error_message = string; string = NULL; } break; case DHCP_OPTION_OVERLOAD: if (len != 1) return -EINVAL; if (overload) *overload = *option; break; default: if (cb) cb(code, len, option, userdata); break; } offset += len; } if (offset < buflen) return -EINVAL; return 0; }
static void test_ascii_is_valid(void) { assert_se(ascii_is_valid("alsdjf\t\vbarr\nba z")); assert_se(!ascii_is_valid("\342\204\242")); assert_se(!ascii_is_valid("\341\204")); }
int config_parse_dnssd_txt(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { _cleanup_(dnssd_txtdata_freep) DnssdTxtData *txt_data = NULL; DnssdService *s = userdata; DnsTxtItem *last = NULL; assert(filename); assert(lvalue); assert(rvalue); assert(s); if (isempty(rvalue)) { /* Flush out collected items */ s->txt_data_items = dnssd_txtdata_free_all(s->txt_data_items); return 0; } txt_data = new0(DnssdTxtData, 1); if (!txt_data) return log_oom(); for (;;) { _cleanup_free_ char *word = NULL; _cleanup_free_ char *key = NULL; _cleanup_free_ char *value = NULL; _cleanup_free_ void *decoded = NULL; size_t length = 0; DnsTxtItem *i; int r; r = extract_first_word(&rvalue, &word, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX); if (r == 0) break; if (r == -ENOMEM) return log_oom(); if (r < 0) return log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue); r = split_pair(word, "=", &key, &value); if (r == -ENOMEM) return log_oom(); if (r == -EINVAL) key = TAKE_PTR(word); if (!ascii_is_valid(key)) { log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid syntax, ignoring: %s", key); return -EINVAL; } switch (ltype) { case DNS_TXT_ITEM_DATA: if (value) { r = unbase64mem(value, strlen(value), &decoded, &length); if (r == -ENOMEM) return log_oom(); if (r < 0) return log_syntax(unit, LOG_ERR, filename, line, r, "Invalid base64 encoding, ignoring: %s", value); } r = dnssd_txt_item_new_from_data(key, decoded, length, &i); if (r < 0) return log_oom(); break; case DNS_TXT_ITEM_TEXT: r = dnssd_txt_item_new_from_string(key, value, &i); if (r < 0) return log_oom(); break; default: assert_not_reached("Unknown type of Txt config"); } LIST_INSERT_AFTER(items, txt_data->txt, last, i); last = i; } if (!LIST_IS_EMPTY(txt_data->txt)) { LIST_PREPEND(items, s->txt_data_items, txt_data); txt_data = NULL; } return 0; }