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.
13 SM_RCSID("@(#)$Id: util.c,v 1.9 2006/08/30 18:35:51 ca Exp $")
14 #include <sm/setjmp.h>
16 #include <sm/assert.h>
18 #include <sm/string.h>
19 #include <sm/sendmail.h>
23 ** STR2PRT -- convert "unprintable" characters in a string to \oct
26 ** s -- string to convert
30 ** This is a static local buffer, string must be copied
31 ** before this function is called again!
42 static char *buf = NULL;
47 for (h = s, l = 1; *h != '\0'; h++, l++)
54 else if (!(isascii(*h) && isprint(*h)))
64 char *nbuf = sm_pmalloc_x(l);
71 for (h = buf; *s != '\0' && l > 0; s++, l--)
74 if (isascii(c) && isprint(c) && c != '\\')
98 (void) sm_snprintf(h, l, "%03o",
99 (unsigned int)((unsigned char) c));
102 ** XXX since l is unsigned this may
103 ** wrap around if the calculation is screwed
119 ** QUOTE_INTERNAL_CHARS -- do quoting of internal characters
121 ** Necessary to make sure that we don't have metacharacters such
122 ** as the internal versions of "$*" or "$&" in a string.
123 ** The input and output pointers can be the same.
126 ** ibp -- a pointer to the string to translate
127 ** obp -- a pointer to an output buffer
128 ** bsp -- pointer to the length of the output buffer
131 ** A possibly new bp (if the buffer needed to grow); if
132 ** it is different, *bsp will updated to the size of
133 ** the new buffer and the caller is responsible for
134 ** freeing the memory.
137 #define SM_MM_QUOTE(ch) (((ch) & 0377) == METAQUOTE || (((ch) & 0340) == 0200))
140 quote_internal_chars(ibp, obp, bsp)
147 bool buffer_same, needs_quoting;
149 buffer_same = ibp == obp;
150 needs_quoting = false;
152 /* determine length of output string (starts at 1 for trailing '\0') */
153 for (ip = ibp, olen = 1; *ip != '\0'; ip++, olen++)
155 if (SM_MM_QUOTE(*ip))
158 needs_quoting = true;
162 /* is the output buffer big enough? */
165 obp = sm_malloc_x(olen);
171 ** shortcut: no change needed?
172 ** Note: we don't check this first as some bozo may use the same
173 ** buffers but restrict the size of the output buffer to less
174 ** than the length of the input buffer in which case we need to
175 ** allocate a new buffer.
182 bufused = sm_strlcpy(obp, ibp, *bsp);
183 SM_ASSERT(bufused <= olen);
190 obp = sm_malloc_x(olen);
195 for (ip = ibp, op = obp, bufused = 0; *ip != '\0'; ip++)
197 if (SM_MM_QUOTE(*ip))
199 SM_ASSERT(bufused < olen);
200 op[bufused++] = METAQUOTE;
202 SM_ASSERT(bufused < olen);
210 ** DEQUOTE_INTERNAL_CHARS -- undo the effect of quote_internal_chars
213 ** ibp -- a pointer to the string to be translated.
214 ** obp -- a pointer to the output buffer. Can be the
216 ** obs -- the size of the output buffer.
219 ** number of character added to obp
223 dequote_internal_chars(ibp, obp, obs)
234 for (ip = ibp, op = obp; *ip != '\0'; ip++)
236 if ((*ip & 0377) == METAQUOTE && !quoted)
241 if (op < &obp[obs - 1])