On Fri, Mar 14, 2025 at 08:29:15AM +0300, Michael Tokarev via Postfix-users wrote:
> I'm sure I've seen this issue before here on postfix-users. > But can't find it. > > When main.cf does not have a trailing newline, using `postconf -e foo=bar' > to add new parameter makes bad main.cf. For example: > > $ head -c-1 /etc/postfix/main.cf > main.cf > $ tail -n1 main.cf > default_destination_concurrency_limit = 1$ MAIL_CONFIG=$(pwd) > /usr/sbin/postconf -e foo=bar > $ tail -n1 main.cf > default_destination_concurrency_limit = 1foo=bar > $ _ > > (note the command in 3rd line is in the same line as `tail` output) > > I wonder if I should add a wrapper around postconf to check for the > missing trailing newline. This is kinda strange provided all other > parts of postfix cope with this situation just fine. Why not fix the problem, rather than put a bandaid on the symptom? -- Viktor.
--- a/src/postconf/postconf_edit.c +++ b/src/postconf/postconf_edit.c @@ -110,11 +110,16 @@ static char *pcf_find_cf_info(VSTRING *buf, VSTREAM *dst) /* pcf_next_cf_line - return next content line, pass non-content */ -static char *pcf_next_cf_line(VSTRING *buf, VSTREAM *src, VSTREAM *dst, int *lineno) +static char *pcf_next_cf_line(VSTRING *buf, VSTREAM *src, VSTREAM *dst, + int *lineno, int *neednl) { char *cp; while (vstring_get(buf, src) != VSTREAM_EOF) { + if (neednl) { + cp = STR(buf); + *neednl = *cp && cp[strlen(cp) - 1] != '\n'; + } if (lineno) *lineno += 1; if ((cp = pcf_find_cf_info(buf, dst)) != 0) @@ -126,7 +131,7 @@ static char *pcf_next_cf_line(VSTRING *buf, VSTREAM *src, VSTREAM *dst, int *lin /* pcf_gobble_cf_line - accumulate multi-line content, pass non-content */ static void pcf_gobble_cf_line(VSTRING *full_entry_buf, VSTRING *line_buf, - VSTREAM *src, VSTREAM *dst, int *lineno) + VSTREAM *src, VSTREAM *dst, int *lineno) { int ch; @@ -165,6 +170,7 @@ void pcf_edit_main(int mode, int argc, char **argv) HTABLE_INFO **ht_info; HTABLE_INFO **ht; int interesting; + int neednl; const char *err; /* @@ -228,7 +234,8 @@ void pcf_edit_main(int mode, int argc, char **argv) #define STR(x) vstring_str(x) interesting = 0; - while ((cp = pcf_next_cf_line(buf, src, dst, (int *) 0)) != 0) { + neednl = 0; + while ((cp = pcf_next_cf_line(buf, src, dst, (int *) 0, &neednl)) != 0) { /* Copy, skip or replace continued text. */ if (cp > STR(buf)) { if (interesting == 0) @@ -243,15 +250,18 @@ void pcf_edit_main(int mode, int argc, char **argv) if ((interesting = !!cvalue) != 0) { if (cvalue->found++ == 1) msg_warn("%s: multiple entries for \"%s\"", path, STR(key)); - if (mode & PCF_EDIT_CONF) + if (mode & PCF_EDIT_CONF) { vstream_fprintf(dst, "%s = %s\n", STR(key), cvalue->value); - else if (mode & PCF_COMMENT_OUT) + neednl = 0; + } else if (mode & PCF_COMMENT_OUT) vstream_fprintf(dst, "#%s", cp); } else { vstream_fputs(STR(buf), dst); } } } + if (neednl) + VSTREAM_PUTC('\n', dst); /* * Generate new entries for parameters that were not found. @@ -315,6 +325,7 @@ void pcf_edit_master(int mode, int argc, char **argv) PCF_MASTER_EDIT_REQ *edit_reqs; PCF_MASTER_EDIT_REQ *req; int num_reqs = argc; + int neednl; const char *edit_opts = "-Me, -Fe, -Pe, -X, or -#"; char *service_name; char *service_type; @@ -424,7 +435,9 @@ void pcf_edit_master(int mode, int argc, char **argv) service_name_type_matched = 0; new_entry = 0; lineno = 0; - while ((cp = pcf_next_cf_line(parse_buf, src, dst, &lineno)) != 0) { + neednl = 0; + while ((cp = pcf_next_cf_line(parse_buf, src, dst, &lineno, + &neednl)) != 0) { vstring_strcpy(line_buf, STR(parse_buf)); /* @@ -572,6 +585,7 @@ void pcf_edit_master(int mode, int argc, char **argv) pcf_print_master_entry(dst, PCF_FOLD_LINE, new_entry); pcf_free_master_entry(new_entry); new_entry = 0; + neednl = 0; } else if (service_name_type_matched == 0) { vstream_fputs(STR(line_buf), dst); } else if (mode & PCF_COMMENT_OUT) { @@ -579,6 +593,8 @@ void pcf_edit_master(int mode, int argc, char **argv) } } } + if (neednl) + VSTREAM_PUTC('\n', dst); /* * Postprocessing: when editing entire service entries, generate new
_______________________________________________ Postfix-users mailing list -- postfix-users@postfix.org To unsubscribe send an email to postfix-users-le...@postfix.org