/* Go through the file and parse each line */ int config_parse(const char *unit, const char *filename, FILE *f, const char *sections, ConfigItemLookup lookup, const void *table, ConfigParseFlags flags, void *userdata) { _cleanup_free_ char *section = NULL, *continuation = NULL; _cleanup_fclose_ FILE *ours = NULL; unsigned line = 0, section_line = 0; bool section_ignored = false; int r; assert(filename); assert(lookup); if (!f) { f = ours = fopen(filename, "re"); if (!f) { /* Only log on request, except for ENOENT, * since we return 0 to the caller. */ if ((flags & CONFIG_PARSE_WARN) || errno == ENOENT) log_full(errno == ENOENT ? LOG_DEBUG : LOG_ERR, "Failed to open configuration file '%s': %m", filename); return errno == ENOENT ? 0 : -errno; } } fd_warn_permissions(filename, fileno(f)); for (;;) { _cleanup_free_ char *buf = NULL; bool escaped = false; char *l, *p, *e; r = read_line(f, LONG_LINE_MAX, &buf); if (r == 0) break; if (r == -ENOBUFS) { if (flags & CONFIG_PARSE_WARN) log_error_errno(r, "%s:%u: Line too long", filename, line); return r; } if (r < 0) { if (CONFIG_PARSE_WARN) log_error_errno(r, "%s:%u: Error while reading configuration file: %m", filename, line); return r; } l = buf; if (!(flags & CONFIG_PARSE_REFUSE_BOM)) { char *q; q = startswith(buf, UTF8_BYTE_ORDER_MARK); if (q) { l = q; flags |= CONFIG_PARSE_REFUSE_BOM; } } if (continuation) { if (strlen(continuation) + strlen(l) > LONG_LINE_MAX) { if (flags & CONFIG_PARSE_WARN) log_error("%s:%u: Continuation line too long", filename, line); return -ENOBUFS; } if (!strextend(&continuation, l, NULL)) { if (flags & CONFIG_PARSE_WARN) log_oom(); return -ENOMEM; } p = continuation; } else p = l; for (e = p; *e; e++) { if (escaped) escaped = false; else if (*e == '\\') escaped = true; } if (escaped) { *(e-1) = ' '; if (!continuation) { continuation = strdup(l); if (!continuation) { if (flags & CONFIG_PARSE_WARN) log_oom(); return -ENOMEM; } } continue; } r = parse_line(unit, filename, ++line, sections, lookup, table, flags, §ion, §ion_line, §ion_ignored, p, userdata); if (r < 0) { if (flags & CONFIG_PARSE_WARN) log_warning_errno(r, "%s:%u: Failed to parse file: %m", filename, line); return r; } continuation = mfree(continuation); } return 0; }
/* Go through the file and parse each line */ int config_parse(const char *unit, const char *filename, FILE *f, const char *sections, ConfigItemLookup lookup, const void *table, bool relaxed, bool allow_include, bool warn, void *userdata) { _cleanup_free_ char *section = NULL, *continuation = NULL; _cleanup_fclose_ FILE *ours = NULL; unsigned line = 0, section_line = 0; bool section_ignored = false; int r; assert(filename); assert(lookup); if (!f) { f = ours = fopen(filename, "re"); if (!f) { /* Only log on request, except for ENOENT, * since we return 0 to the caller. */ if (warn || errno == ENOENT) log_full(errno == ENOENT ? LOG_DEBUG : LOG_ERR, "Failed to open configuration file '%s': %m", filename); return errno == ENOENT ? 0 : -errno; } } fd_warn_permissions(filename, fileno(f)); while (!feof(f)) { char l[LINE_MAX], *p, *c = NULL, *e; bool escaped = false; if (!fgets(l, sizeof(l), f)) { if (feof(f)) break; log_error_errno(errno, "Failed to read configuration file '%s': %m", filename); return -errno; } truncate_nl(l); if (continuation) { c = strappend(continuation, l); if (!c) { if (warn) log_oom(); return -ENOMEM; } continuation = mfree(continuation); p = c; } else p = l; for (e = p; *e; e++) { if (escaped) escaped = false; else if (*e == '\\') escaped = true; } if (escaped) { *(e-1) = ' '; if (c) continuation = c; else { continuation = strdup(l); if (!continuation) { if (warn) log_oom(); return -ENOMEM; } } continue; } r = parse_line(unit, filename, ++line, sections, lookup, table, relaxed, allow_include, §ion, §ion_line, §ion_ignored, p, userdata); free(c); if (r < 0) { if (warn) log_warning_errno(r, "Failed to parse file '%s': %m", filename); return r; } } return 0; }
/* Go through the file and parse each line */ int config_parse(const char *unit, const char *filename, FILE *f, const char *sections, ConfigItemLookup lookup, void *table, bool relaxed, bool allow_include, void *userdata) { _cleanup_free_ char *section = NULL, *continuation = NULL; _cleanup_fclose_ FILE *ours = NULL; unsigned line = 0, section_line = 0; int r; assert(filename); assert(lookup); if (!f) { f = ours = fopen(filename, "re"); if (!f) { log_error("Failed to open configuration file '%s': %m", filename); return -errno; } } fd_warn_permissions(filename, fileno(f)); while (!feof(f)) { char l[LINE_MAX], *p, *c = NULL, *e; bool escaped = false; if (!fgets(l, sizeof(l), f)) { if (feof(f)) break; log_error("Failed to read configuration file '%s': %m", filename); return -errno; } truncate_nl(l); if (continuation) { c = strappend(continuation, l); if (!c) return -ENOMEM; free(continuation); continuation = NULL; p = c; } else p = l; for (e = p; *e; e++) { if (escaped) escaped = false; else if (*e == '\\') escaped = true; } if (escaped) { *(e-1) = ' '; if (c) continuation = c; else { continuation = strdup(l); if (!continuation) return -ENOMEM; } continue; } r = parse_line(unit, filename, ++line, sections, lookup, table, relaxed, allow_include, §ion, §ion_line, p, userdata); free(c); if (r < 0) return r; } return 0; }