4 * Copyright (c) 1997-2009 Erez Zadok
5 * Copyright (c) 1990 Jan-Simon Pendry
6 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
7 * Copyright (c) 1990 The Regents of the University of California.
10 * This code is derived from software contributed to Berkeley by
11 * Jan-Simon Pendry at Imperial College, London.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgment:
23 * This product includes software developed by the University of
24 * California, Berkeley and its contributors.
25 * 4. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 * File: am-utils/libamu/strutil.c
52 #endif /* HAVE_CONFIG_H */
58 strnsave(const char *str
, int len
)
60 char *sp
= (char *) xmalloc(len
+ 1);
61 memmove(sp
, str
, len
);
69 * Concatenate three strings and store the result in the buffer pointed to
70 * by p, making p large enough to hold the strings
73 str3cat(char *p
, char *s1
, char *s2
, char *s3
)
79 p
= (char *) xrealloc(p
, l1
+ l2
+ l3
+ 1);
81 memmove(p
+ l1
, s2
, l2
);
82 memmove(p
+ l1
+ l2
, s3
, l3
+ 1);
88 * Split s using ch as delimiter and qc as quote character
91 strsplit(char *s
, int ch
, int qc
)
97 ivec
= (char **) xmalloc((ic
+ 1) * sizeof(char *));
105 while (*s
&& (ch
== ' ' ? (isascii((unsigned char)*s
) && isspace((unsigned char)*s
)) : *s
== ch
))
115 * remember start of string
122 while (*s
&& !(ch
== ' ' ? (isascii((unsigned char)*s
) && isspace((unsigned char)*s
)) : *s
== ch
)) {
128 while (*s
&& *s
!= qc
)
140 * save string in new ivec slot
143 ivec
= (char **) xrealloc((voidp
) ivec
, (ic
+ 1) * sizeof(char *));
145 plog(XLOG_DEBUG
, "strsplit saved \"%s\"", v
);
149 plog(XLOG_DEBUG
, "strsplit saved a total of %d strings", ic
);
158 * Use generic strlcpy to copy a string more carefully, null-terminating it
159 * as needed. However, if the copied string was truncated due to lack of
160 * space, then warn us.
162 * For now, xstrlcpy returns VOID because it doesn't look like anywhere in
163 * the Amd code do we actually use the return value of strncpy/strlcpy.
167 _xstrlcpy(const char *filename
, int lineno
, char *dst
, const char *src
, size_t len
)
168 #else /* not DEBUG */
169 xstrlcpy(char *dst
, const char *src
, size_t len
)
170 #endif /* not DEBUG */
174 if (strlcpy(dst
, src
, len
) >= len
)
176 plog(XLOG_ERROR
, "xstrlcpy(%s:%d): string \"%s\" truncated to \"%s\"",
177 filename
, lineno
, src
, dst
);
178 #else /* not DEBUG */
179 plog(XLOG_ERROR
, "xstrlcpy: string \"%s\" truncated to \"%s\"", src
, dst
);
180 #endif /* not DEBUG */
185 * Use generic strlcat to concatenate a string more carefully,
186 * null-terminating it as needed. However, if the copied string was
187 * truncated due to lack of space, then warn us.
189 * For now, xstrlcat returns VOID because it doesn't look like anywhere in
190 * the Amd code do we actually use the return value of strncat/strlcat.
194 _xstrlcat(const char *filename
, int lineno
, char *dst
, const char *src
, size_t len
)
195 #else /* not DEBUG */
196 xstrlcat(char *dst
, const char *src
, size_t len
)
197 #endif /* not DEBUG */
201 if (strlcat(dst
, src
, len
) >= len
) {
202 /* strlcat does not null terminate if the size of src is equal to len. */
203 dst
[strlen(dst
) - 1] = '\0';
205 plog(XLOG_ERROR
, "xstrlcat(%s:%d): string \"%s\" truncated to \"%s\"",
206 filename
, lineno
, src
, dst
);
207 #else /* not DEBUG */
208 plog(XLOG_ERROR
, "xstrlcat: string \"%s\" truncated to \"%s\"", src
, dst
);
209 #endif /* not DEBUG */
214 /* our version of snprintf */
216 #if defined(DEBUG) && (defined(HAVE_C99_VARARGS_MACROS) || defined(HAVE_GCC_VARARGS_MACROS))
217 _xsnprintf(const char *filename
, int lineno
, char *str
, size_t size
, const char *format
, ...)
218 #else /* not DEBUG or no C99/GCC-style vararg cpp macros supported */
219 xsnprintf(char *str
, size_t size
, const char *format
, ...)
220 #endif /* not DEBUG or no C99/GCC-style vararg cpp macros supported */
225 va_start(ap
, format
);
226 #if defined(DEBUG) && (defined(HAVE_C99_VARARGS_MACROS) || defined(HAVE_GCC_VARARGS_MACROS))
227 ret
= _xvsnprintf(filename
, lineno
, str
, size
, format
, ap
);
228 #else /* not DEBUG or no C99/GCC-style vararg cpp macros supported */
229 ret
= xvsnprintf(str
, size
, format
, ap
);
230 #endif /* not DEBUG or no C99/GCC-style vararg cpp macros supported */
237 /* our version of vsnprintf */
239 #if defined(DEBUG) && (defined(HAVE_C99_VARARGS_MACROS) || defined(HAVE_GCC_VARARGS_MACROS))
240 _xvsnprintf(const char *filename
, int lineno
, char *str
, size_t size
, const char *format
, va_list ap
)
241 #else /* not DEBUG or no C99/GCC-style vararg cpp macros supported */
242 xvsnprintf(char *str
, size_t size
, const char *format
, va_list ap
)
243 #endif /* not DEBUG or no C99/GCC-style vararg cpp macros supported */
247 #ifdef HAVE_VSNPRINTF
248 ret
= vsnprintf(str
, size
, format
, ap
);
249 #else /* not HAVE_VSNPRINTF */
250 ret
= vsprintf(str
, format
, ap
); /* less secure version */
251 #endif /* not HAVE_VSNPRINTF */
253 * If error or truncation, plog error.
255 * WARNING: we use the static 'maxtrunc' variable below to break out any
256 * possible infinite recursion between plog() and xvsnprintf(). If it
257 * ever happens, it'd indicate a bug in Amd.
259 if (ret
< 0 || (size_t) ret
>= size
) { /* error or truncation occured */
260 static int maxtrunc
; /* hack to avoid inifinite loop */
262 #if defined(DEBUG) && (defined(HAVE_C99_VARARGS_MACROS) || defined(HAVE_GCC_VARARGS_MACROS))
263 plog(XLOG_ERROR
, "xvsnprintf(%s:%d): string %p truncated (ret=%d, format=\"%s\")",
264 filename
, lineno
, str
, ret
, format
);
265 #else /* not DEBUG or no C99/GCC-style vararg cpp macros supported */
266 plog(XLOG_ERROR
, "xvsnprintf: string %p truncated (ret=%d, format=\"%s\")",
268 #endif /* not DEBUG or no C99/GCC-style vararg cpp macros supported */