2 * Copyright (c) 2006 Sendmail, Inc. and its suppliers.
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
11 #pragma ident "%Z%%M% %I% %E% SMI"
15 SM_RCSID("@(#)$Id: util.c,v 1.9 2006/08/30 18:35:51 ca Exp $")
16 #include <sm/setjmp.h>
18 #include <sm/assert.h>
20 #include <sm/string.h>
21 #include <sm/sendmail.h>
25 ** STR2PRT -- convert "unprintable" characters in a string to \oct
28 ** s -- string to convert
32 ** This is a static local buffer, string must be copied
33 ** before this function is called again!
44 static char *buf
= NULL
;
49 for (h
= s
, l
= 1; *h
!= '\0'; h
++, l
++)
56 else if (!(isascii(*h
) && isprint(*h
)))
66 char *nbuf
= sm_pmalloc_x(l
);
73 for (h
= buf
; *s
!= '\0' && l
> 0; s
++, l
--)
76 if (isascii(c
) && isprint(c
) && c
!= '\\')
100 (void) sm_snprintf(h
, l
, "%03o",
101 (unsigned int)((unsigned char) c
));
104 ** XXX since l is unsigned this may
105 ** wrap around if the calculation is screwed
121 ** QUOTE_INTERNAL_CHARS -- do quoting of internal characters
123 ** Necessary to make sure that we don't have metacharacters such
124 ** as the internal versions of "$*" or "$&" in a string.
125 ** The input and output pointers can be the same.
128 ** ibp -- a pointer to the string to translate
129 ** obp -- a pointer to an output buffer
130 ** bsp -- pointer to the length of the output buffer
133 ** A possibly new bp (if the buffer needed to grow); if
134 ** it is different, *bsp will updated to the size of
135 ** the new buffer and the caller is responsible for
136 ** freeing the memory.
139 #define SM_MM_QUOTE(ch) (((ch) & 0377) == METAQUOTE || (((ch) & 0340) == 0200))
142 quote_internal_chars(ibp
, obp
, bsp
)
149 bool buffer_same
, needs_quoting
;
151 buffer_same
= ibp
== obp
;
152 needs_quoting
= false;
154 /* determine length of output string (starts at 1 for trailing '\0') */
155 for (ip
= ibp
, olen
= 1; *ip
!= '\0'; ip
++, olen
++)
157 if (SM_MM_QUOTE(*ip
))
160 needs_quoting
= true;
164 /* is the output buffer big enough? */
167 obp
= sm_malloc_x(olen
);
173 ** shortcut: no change needed?
174 ** Note: we don't check this first as some bozo may use the same
175 ** buffers but restrict the size of the output buffer to less
176 ** than the length of the input buffer in which case we need to
177 ** allocate a new buffer.
184 bufused
= sm_strlcpy(obp
, ibp
, *bsp
);
185 SM_ASSERT(bufused
<= olen
);
192 obp
= sm_malloc_x(olen
);
197 for (ip
= ibp
, op
= obp
, bufused
= 0; *ip
!= '\0'; ip
++)
199 if (SM_MM_QUOTE(*ip
))
201 SM_ASSERT(bufused
< olen
);
202 op
[bufused
++] = METAQUOTE
;
204 SM_ASSERT(bufused
< olen
);
212 ** DEQUOTE_INTERNAL_CHARS -- undo the effect of quote_internal_chars
215 ** ibp -- a pointer to the string to be translated.
216 ** obp -- a pointer to the output buffer. Can be the
218 ** obs -- the size of the output buffer.
221 ** number of character added to obp
225 dequote_internal_chars(ibp
, obp
, obs
)
236 for (ip
= ibp
, op
= obp
; *ip
!= '\0'; ip
++)
238 if ((*ip
& 0377) == METAQUOTE
&& !quoted
)
243 if (op
< &obp
[obs
- 1])