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 -- [email protected]
To unsubscribe send an email to [email protected]