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 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