xref: /freebsd/contrib/sendmail/libsmutil/snprintf.c (revision 06f25ae9f1d6020a600a10f713046203d1a82570)
106f25ae9SGregory Neil Shapiro /*
206f25ae9SGregory Neil Shapiro  * Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
306f25ae9SGregory Neil Shapiro  *	All rights reserved.
406f25ae9SGregory Neil Shapiro  * Copyright (c) 1997 Eric P. Allman.  All rights reserved.
506f25ae9SGregory Neil Shapiro  * Copyright (c) 1988, 1993
606f25ae9SGregory Neil Shapiro  *	The Regents of the University of California.  All rights reserved.
706f25ae9SGregory Neil Shapiro  *
806f25ae9SGregory Neil Shapiro  * By using this file, you agree to the terms and conditions set
906f25ae9SGregory Neil Shapiro  * forth in the LICENSE file which can be found at the top level of
1006f25ae9SGregory Neil Shapiro  * the sendmail distribution.
1106f25ae9SGregory Neil Shapiro  *
1206f25ae9SGregory Neil Shapiro  */
1306f25ae9SGregory Neil Shapiro 
1406f25ae9SGregory Neil Shapiro #ifndef lint
1506f25ae9SGregory Neil Shapiro static char id[] = "@(#)$Id: snprintf.c,v 8.27.16.1 2000/07/15 17:35:18 gshapiro Exp $";
1606f25ae9SGregory Neil Shapiro #endif /* ! lint */
1706f25ae9SGregory Neil Shapiro 
1806f25ae9SGregory Neil Shapiro #include <sendmail.h>
1906f25ae9SGregory Neil Shapiro 
2006f25ae9SGregory Neil Shapiro /*
2106f25ae9SGregory Neil Shapiro **  SNPRINTF, VSNPRINT -- counted versions of printf
2206f25ae9SGregory Neil Shapiro **
2306f25ae9SGregory Neil Shapiro **	These versions have been grabbed off the net.  They have been
2406f25ae9SGregory Neil Shapiro **	cleaned up to compile properly and support for .precision and
2506f25ae9SGregory Neil Shapiro **	%lx has been added.
2606f25ae9SGregory Neil Shapiro */
2706f25ae9SGregory Neil Shapiro 
2806f25ae9SGregory Neil Shapiro /**************************************************************
2906f25ae9SGregory Neil Shapiro  * Original:
3006f25ae9SGregory Neil Shapiro  * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
3106f25ae9SGregory Neil Shapiro  * A bombproof version of doprnt (sm_dopr) included.
3206f25ae9SGregory Neil Shapiro  * Sigh.  This sort of thing is always nasty do deal with.  Note that
3306f25ae9SGregory Neil Shapiro  * the version here does not include floating point...
3406f25ae9SGregory Neil Shapiro  *
3506f25ae9SGregory Neil Shapiro  * snprintf() is used instead of sprintf() as it does limit checks
3606f25ae9SGregory Neil Shapiro  * for string length.  This covers a nasty loophole.
3706f25ae9SGregory Neil Shapiro  *
3806f25ae9SGregory Neil Shapiro  * The other functions are there to prevent NULL pointers from
3906f25ae9SGregory Neil Shapiro  * causing nast effects.
4006f25ae9SGregory Neil Shapiro  **************************************************************/
4106f25ae9SGregory Neil Shapiro 
4206f25ae9SGregory Neil Shapiro /*static char _id[] = "$OrigId: snprintf.c,v 1.2 1995/10/09 11:19:47 roberto Exp $";*/
4306f25ae9SGregory Neil Shapiro void	sm_dopr();
4406f25ae9SGregory Neil Shapiro char	*DoprEnd;
4506f25ae9SGregory Neil Shapiro int	SnprfOverflow;
4606f25ae9SGregory Neil Shapiro 
4706f25ae9SGregory Neil Shapiro #if !HASSNPRINTF && !SNPRINTF_IS_BROKEN
4806f25ae9SGregory Neil Shapiro # define sm_snprintf	snprintf
4906f25ae9SGregory Neil Shapiro # ifndef luna2
5006f25ae9SGregory Neil Shapiro #  define sm_vsnprintf	vsnprintf
5106f25ae9SGregory Neil Shapiro extern int	vsnprintf __P((char *, size_t, const char *, va_list));
5206f25ae9SGregory Neil Shapiro # endif /* ! luna2 */
5306f25ae9SGregory Neil Shapiro #endif /* !HASSNPRINTF && !SNPRINTF_IS_BROKEN */
5406f25ae9SGregory Neil Shapiro 
5506f25ae9SGregory Neil Shapiro /* VARARGS3 */
5606f25ae9SGregory Neil Shapiro int
5706f25ae9SGregory Neil Shapiro # ifdef __STDC__
5806f25ae9SGregory Neil Shapiro sm_snprintf(char *str, size_t count, const char *fmt, ...)
5906f25ae9SGregory Neil Shapiro # else /* __STDC__ */
6006f25ae9SGregory Neil Shapiro sm_snprintf(str, count, fmt, va_alist)
6106f25ae9SGregory Neil Shapiro 	char *str;
6206f25ae9SGregory Neil Shapiro 	size_t count;
6306f25ae9SGregory Neil Shapiro 	const char *fmt;
6406f25ae9SGregory Neil Shapiro 	va_dcl
6506f25ae9SGregory Neil Shapiro # endif /* __STDC__ */
6606f25ae9SGregory Neil Shapiro {
6706f25ae9SGregory Neil Shapiro 	int len;
6806f25ae9SGregory Neil Shapiro 	VA_LOCAL_DECL
6906f25ae9SGregory Neil Shapiro 
7006f25ae9SGregory Neil Shapiro 	VA_START(fmt);
7106f25ae9SGregory Neil Shapiro 	len = sm_vsnprintf(str, count, fmt, ap);
7206f25ae9SGregory Neil Shapiro 	VA_END;
7306f25ae9SGregory Neil Shapiro 	return len;
7406f25ae9SGregory Neil Shapiro }
7506f25ae9SGregory Neil Shapiro 
7606f25ae9SGregory Neil Shapiro int
7706f25ae9SGregory Neil Shapiro sm_vsnprintf(str, count, fmt, args)
7806f25ae9SGregory Neil Shapiro 	char *str;
7906f25ae9SGregory Neil Shapiro 	size_t count;
8006f25ae9SGregory Neil Shapiro 	const char *fmt;
8106f25ae9SGregory Neil Shapiro 	va_list args;
8206f25ae9SGregory Neil Shapiro {
8306f25ae9SGregory Neil Shapiro 	str[0] = 0;
8406f25ae9SGregory Neil Shapiro 	DoprEnd = str + count - 1;
8506f25ae9SGregory Neil Shapiro 	SnprfOverflow = 0;
8606f25ae9SGregory Neil Shapiro 	sm_dopr( str, fmt, args );
8706f25ae9SGregory Neil Shapiro 	if (count > 0)
8806f25ae9SGregory Neil Shapiro 		DoprEnd[0] = 0;
8906f25ae9SGregory Neil Shapiro 	if (SnprfOverflow && tTd(57, 2))
9006f25ae9SGregory Neil Shapiro 		dprintf("\nvsnprintf overflow, len = %ld, str = %s",
9106f25ae9SGregory Neil Shapiro 			(long) count, shortenstring(str, MAXSHORTSTR));
9206f25ae9SGregory Neil Shapiro 	return strlen(str);
9306f25ae9SGregory Neil Shapiro }
9406f25ae9SGregory Neil Shapiro 
9506f25ae9SGregory Neil Shapiro /*
9606f25ae9SGregory Neil Shapiro  * sm_dopr(): poor man's version of doprintf
9706f25ae9SGregory Neil Shapiro  */
9806f25ae9SGregory Neil Shapiro 
9906f25ae9SGregory Neil Shapiro void fmtstr __P((char *value, int ljust, int len, int zpad, int maxwidth));
10006f25ae9SGregory Neil Shapiro void fmtnum __P((long value, int base, int dosign, int ljust, int len, int zpad));
10106f25ae9SGregory Neil Shapiro void dostr __P(( char * , int ));
10206f25ae9SGregory Neil Shapiro char *output;
10306f25ae9SGregory Neil Shapiro void dopr_outch __P(( int c ));
10406f25ae9SGregory Neil Shapiro int	SyslogErrno;
10506f25ae9SGregory Neil Shapiro 
10606f25ae9SGregory Neil Shapiro void
10706f25ae9SGregory Neil Shapiro sm_dopr( buffer, format, args )
10806f25ae9SGregory Neil Shapiro        char *buffer;
10906f25ae9SGregory Neil Shapiro        const char *format;
11006f25ae9SGregory Neil Shapiro        va_list args;
11106f25ae9SGregory Neil Shapiro {
11206f25ae9SGregory Neil Shapiro        int ch;
11306f25ae9SGregory Neil Shapiro        long value;
11406f25ae9SGregory Neil Shapiro        int longflag  = 0;
11506f25ae9SGregory Neil Shapiro        int pointflag = 0;
11606f25ae9SGregory Neil Shapiro        int maxwidth  = 0;
11706f25ae9SGregory Neil Shapiro        char *strvalue;
11806f25ae9SGregory Neil Shapiro        int ljust;
11906f25ae9SGregory Neil Shapiro        int len;
12006f25ae9SGregory Neil Shapiro        int zpad;
12106f25ae9SGregory Neil Shapiro #if !HASSTRERROR && !defined(ERRLIST_PREDEFINED)
12206f25ae9SGregory Neil Shapiro 	extern char *sys_errlist[];
12306f25ae9SGregory Neil Shapiro 	extern int sys_nerr;
12406f25ae9SGregory Neil Shapiro #endif /* !HASSTRERROR && !defined(ERRLIST_PREDEFINED) */
12506f25ae9SGregory Neil Shapiro 
12606f25ae9SGregory Neil Shapiro 
12706f25ae9SGregory Neil Shapiro        output = buffer;
12806f25ae9SGregory Neil Shapiro        while( (ch = *format++) != '\0' ){
12906f25ae9SGregory Neil Shapiro 	       switch( ch ){
13006f25ae9SGregory Neil Shapiro 	       case '%':
13106f25ae9SGregory Neil Shapiro 		       ljust = len = zpad = maxwidth = 0;
13206f25ae9SGregory Neil Shapiro 		       longflag = pointflag = 0;
13306f25ae9SGregory Neil Shapiro 	       nextch:
13406f25ae9SGregory Neil Shapiro 		       ch = *format++;
13506f25ae9SGregory Neil Shapiro 		       switch( ch ){
13606f25ae9SGregory Neil Shapiro 		       case 0:
13706f25ae9SGregory Neil Shapiro 			       dostr( "**end of format**" , 0);
13806f25ae9SGregory Neil Shapiro 			       return;
13906f25ae9SGregory Neil Shapiro 		       case '-': ljust = 1; goto nextch;
14006f25ae9SGregory Neil Shapiro 		       case '0': /* set zero padding if len not set */
14106f25ae9SGregory Neil Shapiro 			       if(len==0 && !pointflag) zpad = '0';
14206f25ae9SGregory Neil Shapiro 				/* FALLTHROUGH */
14306f25ae9SGregory Neil Shapiro 		       case '1': case '2': case '3':
14406f25ae9SGregory Neil Shapiro 		       case '4': case '5': case '6':
14506f25ae9SGregory Neil Shapiro 		       case '7': case '8': case '9':
14606f25ae9SGregory Neil Shapiro 			       if (pointflag)
14706f25ae9SGregory Neil Shapiro 				 maxwidth = maxwidth*10 + ch - '0';
14806f25ae9SGregory Neil Shapiro 			       else
14906f25ae9SGregory Neil Shapiro 				 len = len*10 + ch - '0';
15006f25ae9SGregory Neil Shapiro 			       goto nextch;
15106f25ae9SGregory Neil Shapiro 		       case '*':
15206f25ae9SGregory Neil Shapiro 			       if (pointflag)
15306f25ae9SGregory Neil Shapiro 				 maxwidth = va_arg( args, int );
15406f25ae9SGregory Neil Shapiro 			       else
15506f25ae9SGregory Neil Shapiro 				 len = va_arg( args, int );
15606f25ae9SGregory Neil Shapiro 			       goto nextch;
15706f25ae9SGregory Neil Shapiro 		       case '.': pointflag = 1; goto nextch;
15806f25ae9SGregory Neil Shapiro 		       case 'l': longflag = 1; goto nextch;
15906f25ae9SGregory Neil Shapiro 		       case 'u': case 'U':
16006f25ae9SGregory Neil Shapiro 			       /*fmtnum(value,base,dosign,ljust,len,zpad) */
16106f25ae9SGregory Neil Shapiro 			       if( longflag ){
16206f25ae9SGregory Neil Shapiro 				       value = va_arg( args, long );
16306f25ae9SGregory Neil Shapiro 			       } else {
16406f25ae9SGregory Neil Shapiro 				       value = va_arg( args, int );
16506f25ae9SGregory Neil Shapiro 			       }
16606f25ae9SGregory Neil Shapiro 			       fmtnum( value, 10,0, ljust, len, zpad ); break;
16706f25ae9SGregory Neil Shapiro 		       case 'o': case 'O':
16806f25ae9SGregory Neil Shapiro 			       /*fmtnum(value,base,dosign,ljust,len,zpad) */
16906f25ae9SGregory Neil Shapiro 			       if( longflag ){
17006f25ae9SGregory Neil Shapiro 				       value = va_arg( args, long );
17106f25ae9SGregory Neil Shapiro 			       } else {
17206f25ae9SGregory Neil Shapiro 				       value = va_arg( args, int );
17306f25ae9SGregory Neil Shapiro 			       }
17406f25ae9SGregory Neil Shapiro 			       fmtnum( value, 8,0, ljust, len, zpad ); break;
17506f25ae9SGregory Neil Shapiro 		       case 'd': case 'D':
17606f25ae9SGregory Neil Shapiro 			       if( longflag ){
17706f25ae9SGregory Neil Shapiro 				       value = va_arg( args, long );
17806f25ae9SGregory Neil Shapiro 			       } else {
17906f25ae9SGregory Neil Shapiro 				       value = va_arg( args, int );
18006f25ae9SGregory Neil Shapiro 			       }
18106f25ae9SGregory Neil Shapiro 			       fmtnum( value, 10,1, ljust, len, zpad ); break;
18206f25ae9SGregory Neil Shapiro 		       case 'x':
18306f25ae9SGregory Neil Shapiro 			       if( longflag ){
18406f25ae9SGregory Neil Shapiro 				       value = va_arg( args, long );
18506f25ae9SGregory Neil Shapiro 			       } else {
18606f25ae9SGregory Neil Shapiro 				       value = va_arg( args, int );
18706f25ae9SGregory Neil Shapiro 			       }
18806f25ae9SGregory Neil Shapiro 			       fmtnum( value, 16,0, ljust, len, zpad ); break;
18906f25ae9SGregory Neil Shapiro 		       case 'X':
19006f25ae9SGregory Neil Shapiro 			       if( longflag ){
19106f25ae9SGregory Neil Shapiro 				       value = va_arg( args, long );
19206f25ae9SGregory Neil Shapiro 			       } else {
19306f25ae9SGregory Neil Shapiro 				       value = va_arg( args, int );
19406f25ae9SGregory Neil Shapiro 			       }
19506f25ae9SGregory Neil Shapiro 			       fmtnum( value,-16,0, ljust, len, zpad ); break;
19606f25ae9SGregory Neil Shapiro 		       case 's':
19706f25ae9SGregory Neil Shapiro 			       strvalue = va_arg( args, char *);
19806f25ae9SGregory Neil Shapiro 			       if (maxwidth > 0 || !pointflag) {
19906f25ae9SGregory Neil Shapiro 				 if (pointflag && len > maxwidth)
20006f25ae9SGregory Neil Shapiro 				   len = maxwidth; /* Adjust padding */
20106f25ae9SGregory Neil Shapiro 				 fmtstr( strvalue,ljust,len,zpad, maxwidth);
20206f25ae9SGregory Neil Shapiro 			       }
20306f25ae9SGregory Neil Shapiro 			       break;
20406f25ae9SGregory Neil Shapiro 		       case 'c':
20506f25ae9SGregory Neil Shapiro 			       ch = va_arg( args, int );
20606f25ae9SGregory Neil Shapiro 			       dopr_outch( ch ); break;
20706f25ae9SGregory Neil Shapiro 		       case 'm':
20806f25ae9SGregory Neil Shapiro #if HASSTRERROR
20906f25ae9SGregory Neil Shapiro 			       dostr(strerror(SyslogErrno), 0);
21006f25ae9SGregory Neil Shapiro #else /* HASSTRERROR */
21106f25ae9SGregory Neil Shapiro 			       if (SyslogErrno < 0 || SyslogErrno >= sys_nerr)
21206f25ae9SGregory Neil Shapiro 			       {
21306f25ae9SGregory Neil Shapiro 				   dostr("Error ", 0);
21406f25ae9SGregory Neil Shapiro 				   fmtnum(SyslogErrno, 10, 0, 0, 0, 0);
21506f25ae9SGregory Neil Shapiro 			       }
21606f25ae9SGregory Neil Shapiro 			       else
21706f25ae9SGregory Neil Shapiro 				   dostr((char *)sys_errlist[SyslogErrno], 0);
21806f25ae9SGregory Neil Shapiro #endif /* HASSTRERROR */
21906f25ae9SGregory Neil Shapiro 			       break;
22006f25ae9SGregory Neil Shapiro 
22106f25ae9SGregory Neil Shapiro 		       case '%': dopr_outch( ch ); continue;
22206f25ae9SGregory Neil Shapiro 		       default:
22306f25ae9SGregory Neil Shapiro 			       dostr(  "???????" , 0);
22406f25ae9SGregory Neil Shapiro 		       }
22506f25ae9SGregory Neil Shapiro 		       break;
22606f25ae9SGregory Neil Shapiro 	       default:
22706f25ae9SGregory Neil Shapiro 		       dopr_outch( ch );
22806f25ae9SGregory Neil Shapiro 		       break;
22906f25ae9SGregory Neil Shapiro 	       }
23006f25ae9SGregory Neil Shapiro        }
23106f25ae9SGregory Neil Shapiro        *output = 0;
23206f25ae9SGregory Neil Shapiro }
23306f25ae9SGregory Neil Shapiro 
23406f25ae9SGregory Neil Shapiro void
23506f25ae9SGregory Neil Shapiro fmtstr(  value, ljust, len, zpad, maxwidth )
23606f25ae9SGregory Neil Shapiro        char *value;
23706f25ae9SGregory Neil Shapiro        int ljust, len, zpad, maxwidth;
23806f25ae9SGregory Neil Shapiro {
23906f25ae9SGregory Neil Shapiro        int padlen, strleng;     /* amount to pad */
24006f25ae9SGregory Neil Shapiro 
24106f25ae9SGregory Neil Shapiro        if( value == 0 ){
24206f25ae9SGregory Neil Shapiro 	       value = "<NULL>";
24306f25ae9SGregory Neil Shapiro        }
24406f25ae9SGregory Neil Shapiro        for( strleng = 0; value[strleng]; ++ strleng ); /* strlen */
24506f25ae9SGregory Neil Shapiro        if (strleng > maxwidth && maxwidth)
24606f25ae9SGregory Neil Shapiro 	 strleng = maxwidth;
24706f25ae9SGregory Neil Shapiro        padlen = len - strleng;
24806f25ae9SGregory Neil Shapiro        if( padlen < 0 ) padlen = 0;
24906f25ae9SGregory Neil Shapiro        if( ljust ) padlen = -padlen;
25006f25ae9SGregory Neil Shapiro        while( padlen > 0 ) {
25106f25ae9SGregory Neil Shapiro 	       dopr_outch( ' ' );
25206f25ae9SGregory Neil Shapiro 	       --padlen;
25306f25ae9SGregory Neil Shapiro        }
25406f25ae9SGregory Neil Shapiro        dostr( value, maxwidth );
25506f25ae9SGregory Neil Shapiro        while( padlen < 0 ) {
25606f25ae9SGregory Neil Shapiro 	       dopr_outch( ' ' );
25706f25ae9SGregory Neil Shapiro 	       ++padlen;
25806f25ae9SGregory Neil Shapiro        }
25906f25ae9SGregory Neil Shapiro }
26006f25ae9SGregory Neil Shapiro 
26106f25ae9SGregory Neil Shapiro void
26206f25ae9SGregory Neil Shapiro fmtnum(  value, base, dosign, ljust, len, zpad )
26306f25ae9SGregory Neil Shapiro        long value;
26406f25ae9SGregory Neil Shapiro        int base, dosign, ljust, len, zpad;
26506f25ae9SGregory Neil Shapiro {
26606f25ae9SGregory Neil Shapiro        int signvalue = 0;
26706f25ae9SGregory Neil Shapiro        unsigned long uvalue;
26806f25ae9SGregory Neil Shapiro        char convert[20];
26906f25ae9SGregory Neil Shapiro        int place = 0;
27006f25ae9SGregory Neil Shapiro        int padlen = 0; /* amount to pad */
27106f25ae9SGregory Neil Shapiro        int caps = 0;
27206f25ae9SGregory Neil Shapiro 
27306f25ae9SGregory Neil Shapiro        /* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
27406f25ae9SGregory Neil Shapiro 	       value, base, dosign, ljust, len, zpad )); */
27506f25ae9SGregory Neil Shapiro        uvalue = value;
27606f25ae9SGregory Neil Shapiro        if( dosign ){
27706f25ae9SGregory Neil Shapiro 	       if( value < 0 ) {
27806f25ae9SGregory Neil Shapiro 		       signvalue = '-';
27906f25ae9SGregory Neil Shapiro 		       uvalue = -value;
28006f25ae9SGregory Neil Shapiro 	       }
28106f25ae9SGregory Neil Shapiro        }
28206f25ae9SGregory Neil Shapiro        if( base < 0 ){
28306f25ae9SGregory Neil Shapiro 	       caps = 1;
28406f25ae9SGregory Neil Shapiro 	       base = -base;
28506f25ae9SGregory Neil Shapiro        }
28606f25ae9SGregory Neil Shapiro        do{
28706f25ae9SGregory Neil Shapiro 	       convert[place++] =
28806f25ae9SGregory Neil Shapiro 		       (caps? "0123456789ABCDEF":"0123456789abcdef")
28906f25ae9SGregory Neil Shapiro 			[uvalue % (unsigned)base  ];
29006f25ae9SGregory Neil Shapiro 	       uvalue = (uvalue / (unsigned)base );
29106f25ae9SGregory Neil Shapiro        }while(uvalue);
29206f25ae9SGregory Neil Shapiro        convert[place] = 0;
29306f25ae9SGregory Neil Shapiro        padlen = len - place;
29406f25ae9SGregory Neil Shapiro        if( padlen < 0 ) padlen = 0;
29506f25ae9SGregory Neil Shapiro        if( ljust ) padlen = -padlen;
29606f25ae9SGregory Neil Shapiro        /* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
29706f25ae9SGregory Neil Shapiro 	       convert,place,signvalue,padlen)); */
29806f25ae9SGregory Neil Shapiro        if( zpad && padlen > 0 ){
29906f25ae9SGregory Neil Shapiro 	       if( signvalue ){
30006f25ae9SGregory Neil Shapiro 		       dopr_outch( signvalue );
30106f25ae9SGregory Neil Shapiro 		       --padlen;
30206f25ae9SGregory Neil Shapiro 		       signvalue = 0;
30306f25ae9SGregory Neil Shapiro 	       }
30406f25ae9SGregory Neil Shapiro 	       while( padlen > 0 ){
30506f25ae9SGregory Neil Shapiro 		       dopr_outch( zpad );
30606f25ae9SGregory Neil Shapiro 		       --padlen;
30706f25ae9SGregory Neil Shapiro 	       }
30806f25ae9SGregory Neil Shapiro        }
30906f25ae9SGregory Neil Shapiro        while( padlen > 0 ) {
31006f25ae9SGregory Neil Shapiro 	       dopr_outch( ' ' );
31106f25ae9SGregory Neil Shapiro 	       --padlen;
31206f25ae9SGregory Neil Shapiro        }
31306f25ae9SGregory Neil Shapiro        if( signvalue ) dopr_outch( signvalue );
31406f25ae9SGregory Neil Shapiro        while( place > 0 ) dopr_outch( convert[--place] );
31506f25ae9SGregory Neil Shapiro        while( padlen < 0 ){
31606f25ae9SGregory Neil Shapiro 	       dopr_outch( ' ' );
31706f25ae9SGregory Neil Shapiro 	       ++padlen;
31806f25ae9SGregory Neil Shapiro        }
31906f25ae9SGregory Neil Shapiro }
32006f25ae9SGregory Neil Shapiro 
32106f25ae9SGregory Neil Shapiro void
32206f25ae9SGregory Neil Shapiro dostr( str , cut)
32306f25ae9SGregory Neil Shapiro      char *str;
32406f25ae9SGregory Neil Shapiro      int cut;
32506f25ae9SGregory Neil Shapiro {
32606f25ae9SGregory Neil Shapiro   if (cut) {
32706f25ae9SGregory Neil Shapiro     while(*str && cut-- > 0) dopr_outch(*str++);
32806f25ae9SGregory Neil Shapiro   } else {
32906f25ae9SGregory Neil Shapiro     while(*str) dopr_outch(*str++);
33006f25ae9SGregory Neil Shapiro   }
33106f25ae9SGregory Neil Shapiro }
33206f25ae9SGregory Neil Shapiro 
33306f25ae9SGregory Neil Shapiro void
33406f25ae9SGregory Neil Shapiro dopr_outch( c )
33506f25ae9SGregory Neil Shapiro        int c;
33606f25ae9SGregory Neil Shapiro {
33706f25ae9SGregory Neil Shapiro #if 0
33806f25ae9SGregory Neil Shapiro        if( iscntrl(c) && c != '\n' && c != '\t' ){
33906f25ae9SGregory Neil Shapiro 	       c = '@' + (c & 0x1F);
34006f25ae9SGregory Neil Shapiro 	       if( DoprEnd == 0 || output < DoprEnd )
34106f25ae9SGregory Neil Shapiro 		       *output++ = '^';
34206f25ae9SGregory Neil Shapiro        }
34306f25ae9SGregory Neil Shapiro #endif /* 0 */
34406f25ae9SGregory Neil Shapiro        if( DoprEnd == 0 || output < DoprEnd )
34506f25ae9SGregory Neil Shapiro 	       *output++ = c;
34606f25ae9SGregory Neil Shapiro        else
34706f25ae9SGregory Neil Shapiro 		SnprfOverflow++;
34806f25ae9SGregory Neil Shapiro }
34906f25ae9SGregory Neil Shapiro 
35006f25ae9SGregory Neil Shapiro /*
35106f25ae9SGregory Neil Shapiro **  QUAD_TO_STRING -- Convert a quad type to a string.
35206f25ae9SGregory Neil Shapiro **
35306f25ae9SGregory Neil Shapiro **	Convert a quad type to a string.  This must be done
35406f25ae9SGregory Neil Shapiro **	separately as %lld/%qd are not supported by snprint()
35506f25ae9SGregory Neil Shapiro **	and adding support would slow down systems which only
35606f25ae9SGregory Neil Shapiro **	emulate the data type.
35706f25ae9SGregory Neil Shapiro **
35806f25ae9SGregory Neil Shapiro **	Parameters:
35906f25ae9SGregory Neil Shapiro **		value -- number to convert to a string.
36006f25ae9SGregory Neil Shapiro **
36106f25ae9SGregory Neil Shapiro **	Returns:
36206f25ae9SGregory Neil Shapiro **		pointer to a string.
36306f25ae9SGregory Neil Shapiro */
36406f25ae9SGregory Neil Shapiro 
36506f25ae9SGregory Neil Shapiro char *
36606f25ae9SGregory Neil Shapiro quad_to_string(value)
36706f25ae9SGregory Neil Shapiro 	QUAD_T value;
36806f25ae9SGregory Neil Shapiro {
36906f25ae9SGregory Neil Shapiro 	char *formatstr;
37006f25ae9SGregory Neil Shapiro 	static char buf[64];
37106f25ae9SGregory Neil Shapiro 
37206f25ae9SGregory Neil Shapiro 	/*
37306f25ae9SGregory Neil Shapiro 	**  Use sprintf() instead of snprintf() since snprintf()
37406f25ae9SGregory Neil Shapiro 	**  does not support %qu or %llu.  The buffer is large enough
37506f25ae9SGregory Neil Shapiro 	**  to hold the string so there is no danger of buffer
37606f25ae9SGregory Neil Shapiro 	**  overflow.
37706f25ae9SGregory Neil Shapiro 	*/
37806f25ae9SGregory Neil Shapiro 
37906f25ae9SGregory Neil Shapiro #if NEED_PERCENTQ
38006f25ae9SGregory Neil Shapiro 	formatstr = "%qu";
38106f25ae9SGregory Neil Shapiro #else /* NEED_PERCENTQ */
38206f25ae9SGregory Neil Shapiro 	formatstr = "%llu";
38306f25ae9SGregory Neil Shapiro #endif /* NEED_PERCENTQ */
38406f25ae9SGregory Neil Shapiro 	sprintf(buf, formatstr, value);
38506f25ae9SGregory Neil Shapiro 	return buf;
38606f25ae9SGregory Neil Shapiro }
38706f25ae9SGregory Neil Shapiro /*
38806f25ae9SGregory Neil Shapiro **  SHORTENSTRING -- return short version of a string
38906f25ae9SGregory Neil Shapiro **
39006f25ae9SGregory Neil Shapiro **	If the string is already short, just return it.  If it is too
39106f25ae9SGregory Neil Shapiro **	long, return the head and tail of the string.
39206f25ae9SGregory Neil Shapiro **
39306f25ae9SGregory Neil Shapiro **	Parameters:
39406f25ae9SGregory Neil Shapiro **		s -- the string to shorten.
39506f25ae9SGregory Neil Shapiro **		m -- the max length of the string (strlen()).
39606f25ae9SGregory Neil Shapiro **
39706f25ae9SGregory Neil Shapiro **	Returns:
39806f25ae9SGregory Neil Shapiro **		Either s or a short version of s.
39906f25ae9SGregory Neil Shapiro */
40006f25ae9SGregory Neil Shapiro 
40106f25ae9SGregory Neil Shapiro char *
40206f25ae9SGregory Neil Shapiro shortenstring(s, m)
40306f25ae9SGregory Neil Shapiro 	register const char *s;
40406f25ae9SGregory Neil Shapiro 	int m;
40506f25ae9SGregory Neil Shapiro {
40606f25ae9SGregory Neil Shapiro 	int l;
40706f25ae9SGregory Neil Shapiro 	static char buf[MAXSHORTSTR + 1];
40806f25ae9SGregory Neil Shapiro 
40906f25ae9SGregory Neil Shapiro 	l = strlen(s);
41006f25ae9SGregory Neil Shapiro 	if (l < m)
41106f25ae9SGregory Neil Shapiro 		return (char *) s;
41206f25ae9SGregory Neil Shapiro 	if (m > MAXSHORTSTR)
41306f25ae9SGregory Neil Shapiro 		m = MAXSHORTSTR;
41406f25ae9SGregory Neil Shapiro 	else if (m < 10)
41506f25ae9SGregory Neil Shapiro 	{
41606f25ae9SGregory Neil Shapiro 		if (m < 5)
41706f25ae9SGregory Neil Shapiro 		{
41806f25ae9SGregory Neil Shapiro 			(void) strlcpy(buf, s, m + 1);
41906f25ae9SGregory Neil Shapiro 			return buf;
42006f25ae9SGregory Neil Shapiro 		}
42106f25ae9SGregory Neil Shapiro 		(void) strlcpy(buf, s, m - 2);
42206f25ae9SGregory Neil Shapiro 		(void) strlcat(buf, "...", sizeof buf);
42306f25ae9SGregory Neil Shapiro 		return buf;
42406f25ae9SGregory Neil Shapiro 	}
42506f25ae9SGregory Neil Shapiro 	m = (m - 3) / 2;
42606f25ae9SGregory Neil Shapiro 	(void) strlcpy(buf, s, m + 1);
42706f25ae9SGregory Neil Shapiro 	(void) strlcat(buf, "...", sizeof buf);
42806f25ae9SGregory Neil Shapiro 	(void) strlcat(buf, s + l - m, sizeof buf);
42906f25ae9SGregory Neil Shapiro 	return buf;
43006f25ae9SGregory Neil Shapiro }
431