summaryrefslogtreecommitdiffstats
path: root/plugins/snprintf.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/snprintf.c')
-rw-r--r--plugins/snprintf.c377
1 files changed, 377 insertions, 0 deletions
diff --git a/plugins/snprintf.c b/plugins/snprintf.c
new file mode 100644
index 00000000..1474b639
--- /dev/null
+++ b/plugins/snprintf.c
@@ -0,0 +1,377 @@
1/*
2 * Copyright (c) 1983, 1995, 1996 Eric P. Allman
3 * Copyright (c) 1988, 1993
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by the University of
17 * California, Berkeley and its contributors.
18 * 4. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35/* Some changes made by bbraun@synack.net for use with xinetd */
36
37#if !defined(HAVE_SNPRINTF)
38
39/* Extracted from sendmail 8.8.5 */
40#ifndef lint
41static char sccsid[] = "@(#)$Id$ excerpted from conf.c 8.333 (Berkeley) 1/21/97";
42#endif /* not lint */
43# ifdef __STDC__
44#include <stdio.h>
45#include <stdlib.h>
46
47#ifndef __P
48#define __P(p) p
49#endif
50
51#include <stdarg.h>
52#define VA_LOCAL_DECL va_list ap;
53#define VA_START(f) va_start(ap, f)
54#define VA_END va_end(ap)
55
56#else
57
58#include <sys/types.h>
59#include <stdio.h>
60
61#ifndef __P
62#define __P(p) ()
63#endif
64
65#include <varargs.h>
66#define VA_LOCAL_DECL va_list ap;
67#define VA_START(f) va_start(ap)
68#define VA_END va_end(ap)
69
70#endif
71/*
72** SNPRINTF, VSNPRINT -- counted versions of printf
73**
74** These versions have been grabbed off the net. They have been
75** cleaned up to compile properly and support for .precision and
76** %lx has been added.
77*/
78
79/**************************************************************
80 * Original:
81 * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
82 * A bombproof version of doprnt (dopr) included.
83 * Sigh. This sort of thing is always nasty do deal with. Note that
84 * the version here does not include floating point...
85 *
86 * snprintf() is used instead of sprintf() as it does limit checks
87 * for string length. This covers a nasty loophole.
88 *
89 * The other functions are there to prevent NULL pointers from
90 * causing nast effects.
91 **************************************************************/
92
93/*static char _id[] = "$Id$";*/
94static void dopr();
95static char *end;
96#ifndef _SCO_DS
97/* VARARGS3 */
98int
99# ifdef __STDC__
100snprintf(char *str, size_t count, const char *fmt, ...)
101# else
102snprintf(str, count, fmt, va_alist)
103 char *str;
104 size_t count;
105 char *fmt;
106 va_dcl
107#endif
108{
109 int len;
110 VA_LOCAL_DECL
111
112 VA_START(fmt);
113 len = vsnprintf(str, count, fmt, ap);
114 VA_END;
115 return len;
116}
117#endif
118
119# ifndef luna2
120int
121# ifdef __STDC__
122vsnprintf(char *str, size_t count, const char *fmt, va_list args)
123#else
124vsnprintf(str, count, fmt, args)
125 char *str;
126 int count;
127 char *fmt;
128 va_list args;
129#endif
130{
131 str[0] = 0;
132 end = str + count - 1;
133 dopr( str, fmt, args );
134 if (count > 0)
135 end[0] = 0;
136 return strlen(str);
137}
138
139/*
140 * dopr(): poor man's version of doprintf
141 */
142
143static void fmtstr __P((char *value, int ljust, int len, int zpad, int maxwidth));
144static void fmtnum __P((long value, int base, int dosign, int ljust, int len, int zpad));
145static void dostr __P(( char * , int ));
146static char *output;
147static void dopr_outch __P(( int c ));
148
149static void
150# ifdef __STDC__
151dopr(char * buffer, const char * format, va_list args )
152#else
153dopr( buffer, format, args )
154 char *buffer;
155 char *format;
156 va_list args;
157#endif
158{
159 int ch;
160 long value;
161 int longflag = 0;
162 int pointflag = 0;
163 int maxwidth = 0;
164 char *strvalue;
165 int ljust;
166 int len;
167 int zpad;
168
169 output = buffer;
170 while( (ch = *format++) ){
171 switch( ch ){
172 case '%':
173 ljust = len = zpad = maxwidth = 0;
174 longflag = pointflag = 0;
175 nextch:
176 ch = *format++;
177 switch( ch ){
178 case 0:
179 dostr( "**end of format**" , 0);
180 return;
181 case '-': ljust = 1; goto nextch;
182 case '0': /* set zero padding if len not set */
183 if(len==0 && !pointflag) zpad = '0';
184 case '1': case '2': case '3':
185 case '4': case '5': case '6':
186 case '7': case '8': case '9':
187 if (pointflag)
188 maxwidth = maxwidth*10 + ch - '0';
189 else
190 len = len*10 + ch - '0';
191 goto nextch;
192 case '*':
193 if (pointflag)
194 maxwidth = va_arg( args, int );
195 else
196 len = va_arg( args, int );
197 goto nextch;
198 case '.': pointflag = 1; goto nextch;
199 case 'l': longflag = 1; goto nextch;
200 case 'u': case 'U':
201 /*fmtnum(value,base,dosign,ljust,len,zpad) */
202 if( longflag ){
203 value = va_arg( args, long );
204 } else {
205 value = va_arg( args, int );
206 }
207 fmtnum( value, 10,0, ljust, len, zpad ); break;
208 case 'o': case 'O':
209 /*fmtnum(value,base,dosign,ljust,len,zpad) */
210 if( longflag ){
211 value = va_arg( args, long );
212 } else {
213 value = va_arg( args, int );
214 }
215 fmtnum( value, 8,0, ljust, len, zpad ); break;
216 case 'd': case 'D':
217 if( longflag ){
218 value = va_arg( args, long );
219 } else {
220 value = va_arg( args, int );
221 }
222 fmtnum( value, 10,1, ljust, len, zpad ); break;
223 case 'x':
224 if( longflag ){
225 value = va_arg( args, long );
226 } else {
227 value = va_arg( args, int );
228 }
229 fmtnum( value, 16,0, ljust, len, zpad ); break;
230 case 'X':
231 if( longflag ){
232 value = va_arg( args, long );
233 } else {
234 value = va_arg( args, int );
235 }
236 fmtnum( value,-16,0, ljust, len, zpad ); break;
237 case 's':
238 strvalue = va_arg( args, char *);
239 if (maxwidth > 0 || !pointflag) {
240 if (pointflag && len > maxwidth)
241 len = maxwidth; /* Adjust padding */
242 fmtstr( strvalue,ljust,len,zpad, maxwidth);
243 }
244 break;
245 case 'c':
246 ch = va_arg( args, int );
247 dopr_outch( ch ); break;
248 case '%': dopr_outch( ch ); continue;
249 default:
250 dostr( "???????" , 0);
251 }
252 break;
253 default:
254 dopr_outch( ch );
255 break;
256 }
257 }
258 *output = 0;
259}
260
261static void
262fmtstr( value, ljust, len, zpad, maxwidth )
263 char *value;
264 int ljust, len, zpad, maxwidth;
265{
266 int padlen, strlen; /* amount to pad */
267
268 if( value == 0 ){
269 value = "<NULL>";
270 }
271 for( strlen = 0; value[strlen]; ++ strlen ); /* strlen */
272 if (strlen > maxwidth && maxwidth)
273 strlen = maxwidth;
274 padlen = len - strlen;
275 if( padlen < 0 ) padlen = 0;
276 if( ljust ) padlen = -padlen;
277 while( padlen > 0 ) {
278 dopr_outch( ' ' );
279 --padlen;
280 }
281 dostr( value, maxwidth );
282 while( padlen < 0 ) {
283 dopr_outch( ' ' );
284 ++padlen;
285 }
286}
287
288static void
289fmtnum( value, base, dosign, ljust, len, zpad )
290 long value;
291 int base, dosign, ljust, len, zpad;
292{
293 int signvalue = 0;
294 unsigned long uvalue;
295 char convert[20];
296 int place = 0;
297 int padlen = 0; /* amount to pad */
298 int caps = 0;
299
300 /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
301 value, base, dosign, ljust, len, zpad )); */
302 uvalue = value;
303 if( dosign ){
304 if( value < 0 ) {
305 signvalue = '-';
306 uvalue = -value;
307 }
308 }
309 if( base < 0 ){
310 caps = 1;
311 base = -base;
312 }
313 do{
314 convert[place++] =
315 (caps? "0123456789ABCDEF":"0123456789abcdef")
316 [uvalue % (unsigned)base ];
317 uvalue = (uvalue / (unsigned)base );
318 }while(uvalue);
319 convert[place] = 0;
320 padlen = len - place;
321 if( padlen < 0 ) padlen = 0;
322 if( ljust ) padlen = -padlen;
323 /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
324 convert,place,signvalue,padlen)); */
325 if( zpad && padlen > 0 ){
326 if( signvalue ){
327 dopr_outch( signvalue );
328 --padlen;
329 signvalue = 0;
330 }
331 while( padlen > 0 ){
332 dopr_outch( zpad );
333 --padlen;
334 }
335 }
336 while( padlen > 0 ) {
337 dopr_outch( ' ' );
338 --padlen;
339 }
340 if( signvalue ) dopr_outch( signvalue );
341 while( place > 0 ) dopr_outch( convert[--place] );
342 while( padlen < 0 ){
343 dopr_outch( ' ' );
344 ++padlen;
345 }
346}
347
348static void
349dostr( str , cut)
350 char *str;
351 int cut;
352{
353 if (cut) {
354 while(*str && cut-- > 0) dopr_outch(*str++);
355 } else {
356 while(*str) dopr_outch(*str++);
357 }
358}
359
360static void
361dopr_outch( c )
362 int c;
363{
364#if 0
365 if( iscntrl(c) && c != '\n' && c != '\t' ){
366 c = '@' + (c & 0x1F);
367 if( end == 0 || output < end )
368 *output++ = '^';
369 }
370#endif
371 if( end == 0 || output < end )
372 *output++ = c;
373}
374
375# endif /* !luna2 */
376
377#endif /* HAVE_SNPRINTF */