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