Added extra/crond.service for systemd
[dcron.git] / concat.c
blob011cd329eb144f876d527fb80f2724ce50a69d1f
2 /*
3 * CONCAT.C
5 * Concatenates a variable number of strings. The argument list must be
6 * terminated with a NULL. Returns a pointer to malloc(3)'ed memory with
7 * the concatenated string, or NULL on error.
9 * This code deals gracefully with potential integer overflows (perhaps when
10 * input strings are maliciously long), as well as with input strings changing
11 * from under it (perhaps because of misbehavior of another thread). It does
12 * not depend on non-portable functions such as snprintf() and asprintf().
14 * Written by Solar Designer <solar at openwall.com> and placed in the
15 * public domain.
17 * retrieved from http://cvsweb.openwall.com/cgi/cvsweb.cgi/Owl/packages/popa3d/popa3d/misc.c
18 * see also http://seclists.org/bugtraq/2006/Nov/594
22 #include "defs.h"
24 Prototype char *concat(const char *s1, ...);
26 char *
27 concat(const char *s1, ...)
29 va_list args;
30 char *s, *p, *result;
31 unsigned long l, m, n;
33 m = n = strlen(s1);
34 va_start(args, s1);
35 while ((s = va_arg(args, char *))) {
36 l = strlen(s);
37 if ((m += l) < l) break;
39 va_end(args);
40 if (s || m >= INT_MAX) return NULL;
42 result = malloc(m + 1);
43 if (!result) return NULL;
45 memcpy(p = result, s1, n);
46 p += n;
47 va_start(args, s1);
48 while ((s = va_arg(args, char *))) {
49 l = strlen(s);
50 if ((n += l) < l || n > m) break;
51 memcpy(p, s, l);
52 p += l;
54 va_end(args);
55 if (s || m != n || p - result != n) {
56 free(result);
57 return NULL;
60 *p = 0;
61 return result;