1 /* $NetBSD: postconf_print.c,v 1.1.1.1 2014/07/06 19:27:53 tron Exp $ */
2
3 /*++
4 /* NAME
5 /* postconf_print 3
6 /* SUMMARY
7 /* basic line printing support
8 /* SYNOPSIS
9 /* #include <postconf.h>
10 /*
11 /* void pcf_print_line(fp, mode, const char *fmt, ...)
12 /* VSTREAM *fp;
13 /* int mode;
14 /* const char *fmt;
15 /* DESCRIPTION
16 /* pcf_print_line() formats text, normalized whitespace, and
17 /* optionally folds long lines.
18 /*
19 /* Arguments:
20 /* .IP fp
21 /* Output stream.
22 /* .IP mode
23 /* Bit-wise OR of zero or more of the following (other flags
24 /* are ignored):
25 /* .RS
26 /* .IP PCF_FOLD_LINE
27 /* Fold long lines.
28 /* .RE
29 /* .IP fmt
30 /* Format string.
31 /* DIAGNOSTICS
32 /* Problems are reported to the standard error stream.
33 /* LICENSE
34 /* .ad
35 /* .fi
36 /* The Secure Mailer license must be distributed with this software.
37 /* AUTHOR(S)
38 /* Wietse Venema
39 /* IBM T.J. Watson Research
40 /* P.O. Box 704
41 /* Yorktown Heights, NY 10598, USA
42 /*--*/
43
44 /* System library. */
45
46 #include <sys_defs.h>
47 #include <string.h>
48 #include <stdarg.h>
49
50 /* Utility library. */
51
52 #include <msg.h>
53 #include <vstream.h>
54 #include <vstring.h>
55
56 /* Application-specific. */
57
58 #include <postconf.h>
59
60 /* SLMs. */
61
62 #define STR(x) vstring_str(x)
63
64 /* pcf_print_line - show line possibly folded, and with normalized whitespace */
65
pcf_print_line(VSTREAM * fp,int mode,const char * fmt,...)66 void pcf_print_line(VSTREAM *fp, int mode, const char *fmt,...)
67 {
68 va_list ap;
69 static VSTRING *buf = 0;
70 char *start;
71 char *next;
72 int line_len = 0;
73 int word_len;
74
75 /*
76 * One-off initialization.
77 */
78 if (buf == 0)
79 buf = vstring_alloc(100);
80
81 /*
82 * Format the text.
83 */
84 va_start(ap, fmt);
85 vstring_vsprintf(buf, fmt, ap);
86 va_end(ap);
87
88 /*
89 * Normalize the whitespace. We don't use the line_wrap() routine because
90 * 1) that function does not normalize whitespace between words and 2) we
91 * want to normalize whitespace even when not wrapping lines.
92 *
93 * XXX Some parameters preserve whitespace: for example, smtpd_banner and
94 * smtpd_reject_footer. If we have to preserve whitespace between words,
95 * then perhaps readlline() can be changed to canonicalize whitespace
96 * that follows a newline.
97 */
98 for (start = STR(buf); *(start += strspn(start, PCF_SEPARATORS)) != 0; start = next) {
99 word_len = strcspn(start, PCF_SEPARATORS);
100 if (*(next = start + word_len) != 0)
101 *next++ = 0;
102 if (word_len > 0 && line_len > 0) {
103 if ((mode & PCF_FOLD_LINE) == 0
104 || line_len + word_len < PCF_LINE_LIMIT) {
105 vstream_fputs(" ", fp);
106 line_len += 1;
107 } else {
108 vstream_fputs("\n" PCF_INDENT_TEXT, fp);
109 line_len = PCF_INDENT_LEN;
110 }
111 }
112 vstream_fputs(start, fp);
113 line_len += word_len;
114 }
115 vstream_fputs("\n", fp);
116 }
117