/*++ /* NAME /* postconf_print 3 /* SUMMARY /* basic line printing support /* SYNOPSIS /* #include /* /* void pcf_print_line(fp, mode, const char *fmt, ...) /* VSTREAM *fp; /* int mode; /* const char *fmt; /* DESCRIPTION /* pcf_print_line() formats text, normalized whitespace, and /* optionally folds long lines. /* /* Arguments: /* .IP fp /* Output stream. /* .IP mode /* Bit-wise OR of zero or more of the following (other flags /* are ignored): /* .RS /* .IP PCF_FOLD_LINE /* Fold long lines. /* .RE /* .IP fmt /* Format string. /* DIAGNOSTICS /* Problems are reported to the standard error stream. /* LICENSE /* .ad /* .fi /* The Secure Mailer license must be distributed with this software. /* AUTHOR(S) /* Wietse Venema /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA /*--*/ /* System library. */ #include #include #include /* Utility library. */ #include #include #include /* Application-specific. */ #include /* SLMs. */ #define STR(x) vstring_str(x) /* pcf_print_line - show line possibly folded, and with normalized whitespace */ void pcf_print_line(VSTREAM *fp, int mode, const char *fmt,...) { va_list ap; static VSTRING *buf = 0; char *start; char *next; int line_len = 0; int word_len; /* * One-off initialization. */ if (buf == 0) buf = vstring_alloc(100); /* * Format the text. */ va_start(ap, fmt); vstring_vsprintf(buf, fmt, ap); va_end(ap); /* * Normalize the whitespace. We don't use the line_wrap() routine because * 1) that function does not normalize whitespace between words and 2) we * want to normalize whitespace even when not wrapping lines. * * XXX Some parameters preserve whitespace: for example, smtpd_banner and * smtpd_reject_footer. If we have to preserve whitespace between words, * then perhaps readlline() can be changed to canonicalize whitespace * that follows a newline. */ for (start = STR(buf); *(start += strspn(start, PCF_SEPARATORS)) != 0; start = next) { word_len = strcspn(start, PCF_SEPARATORS); if (*(next = start + word_len) != 0) *next++ = 0; if (word_len > 0 && line_len > 0) { if ((mode & PCF_FOLD_LINE) == 0 || line_len + word_len < PCF_LINE_LIMIT) { vstream_fputs(" ", fp); line_len += 1; } else { vstream_fputs("\n" PCF_INDENT_TEXT, fp); line_len = PCF_INDENT_LEN; } } vstream_fputs(start, fp); line_len += word_len; } vstream_fputs("\n", fp); }