1/*++
2/* NAME
3/*	concatenate 3
4/* SUMMARY
5/*	concatenate strings
6/* SYNOPSIS
7/*	#include <stringops.h>
8/*
9/*	char	*concatenate(str, ...)
10/*	const char *str;
11/* DESCRIPTION
12/*	The \fBconcatenate\fR routine concatenates a null-terminated
13/*	list of pointers to null-terminated character strings.
14/*	The result is dynamically allocated and should be passed to myfree()
15/*	when no longer needed.
16/* LICENSE
17/* .ad
18/* .fi
19/*	The Secure Mailer license must be distributed with this software.
20/* AUTHOR(S)
21/*	Wietse Venema
22/*	IBM T.J. Watson Research
23/*	P.O. Box 704
24/*	Yorktown Heights, NY 10598, USA
25/*--*/
26
27/* System library. */
28
29#include <sys_defs.h>
30#include <stdlib.h>			/* 44BSD stdarg.h uses abort() */
31#include <stdarg.h>
32#include <string.h>
33
34/* Utility library. */
35
36#include "mymalloc.h"
37#include "stringops.h"
38#include "compat_va_copy.h"
39
40/* concatenate - concatenate null-terminated list of strings */
41
42char   *concatenate(const char *arg0,...)
43{
44    char   *result;
45    va_list ap;
46    va_list ap2;
47    ssize_t len;
48    char   *arg;
49
50    /*
51     * Initialize argument lists.
52     */
53    va_start(ap, arg0);
54    VA_COPY(ap2, ap);
55
56    /*
57     * Compute the length of the resulting string.
58     */
59    len = strlen(arg0);
60    while ((arg = va_arg(ap, char *)) != 0)
61	len += strlen(arg);
62    va_end(ap);
63
64    /*
65     * Build the resulting string. Don't care about wasting a CPU cycle.
66     */
67    result = mymalloc(len + 1);
68    strcpy(result, arg0);
69    while ((arg = va_arg(ap2, char *)) != 0)
70	strcat(result, arg);
71    va_end(ap2);
72    return (result);
73}
74