~ubuntu-branches/ubuntu/trusty/libesmtp/trusty-proposed

« back to all changes in this revision

Viewing changes to concatenate.c

  • Committer: Bazaar Package Importer
  • Author(s): Jeremy T. Bouse
  • Date: 2002-03-06 08:37:48 UTC
  • Revision ID: james.westby@ubuntu.com-20020306083748-ihmt32mddsslvg5i
Tags: upstream-0.8.11
ImportĀ upstreamĀ versionĀ 0.8.11

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  This file is part of libESMTP, a library for submission of RFC 2822
 
3
 *  formatted electronic mail messages using the SMTP protocol described
 
4
 *  in RFC 2821.
 
5
 *
 
6
 *  Copyright (C) 2001,2002  Brian Stafford  <brian@stafford.uklinux.net>
 
7
 *
 
8
 *  This library is free software; you can redistribute it and/or
 
9
 *  modify it under the terms of the GNU Lesser General Public
 
10
 *  License as published by the Free Software Foundation; either
 
11
 *  version 2.1 of the License, or (at your option) any later version.
 
12
 *
 
13
 *  This library is distributed in the hope that it will be useful,
 
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
 *  Lesser General Public License for more details.
 
17
 *
 
18
 *  You should have received a copy of the GNU Lesser General Public
 
19
 *  License along with this library; if not, write to the Free Software
 
20
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
21
 */
 
22
 
 
23
/* Stuff to maintain a dynamically sized buffer for a string.  I seem
 
24
   to keep writing code like this, so I've put it in a file by itself.
 
25
   Maybe I should consolidate some other string buffering code with this.
 
26
 
 
27
   NOTE: no \0 terminating strings
 
28
 */
 
29
 
 
30
#ifdef HAVE_CONFIG_H
 
31
#include <config.h>
 
32
#endif
 
33
 
 
34
#include <assert.h>
 
35
 
 
36
#include <stdio.h>
 
37
#include <string.h>
 
38
#include <stdlib.h>
 
39
#include <stdarg.h>
 
40
 
 
41
#include <missing.h> /* declarations for missing library functions */
 
42
 
 
43
#include "concatenate.h"
 
44
 
 
45
/* malloc/realloc the buffer to be the requested length.
 
46
   Return 0 on failure, non-zero otherwise */
 
47
static int
 
48
cat_alloc (struct catbuf *catbuf, size_t length)
 
49
{
 
50
  char *nbuf;
 
51
 
 
52
  assert (catbuf != NULL && length > 0);
 
53
 
 
54
  if (catbuf->buffer == NULL)
 
55
    catbuf->buffer = malloc (length);
 
56
  else
 
57
    {
 
58
      nbuf = realloc (catbuf->buffer, length);
 
59
      if (nbuf == NULL)
 
60
        free (catbuf->buffer);
 
61
      catbuf->buffer = nbuf;
 
62
    }
 
63
  catbuf->allocated = (catbuf->buffer == NULL) ? 0 : length;
 
64
  if (catbuf->allocated < catbuf->string_length)
 
65
    catbuf->string_length = catbuf->allocated;
 
66
  return catbuf->buffer != NULL;
 
67
}
 
68
 
 
69
/* Reset the string to zero length without freeing the allocated memory */
 
70
void
 
71
cat_reset (struct catbuf *catbuf, size_t minimum_length)
 
72
{
 
73
  assert (catbuf != NULL);
 
74
 
 
75
  catbuf->string_length = 0;
 
76
  if (minimum_length > catbuf->allocated)
 
77
    cat_alloc (catbuf, minimum_length);
 
78
}
 
79
 
 
80
/* Initialise a buffer */
 
81
void
 
82
cat_init (struct catbuf *catbuf, size_t minimum_length)
 
83
{
 
84
  assert (catbuf != NULL);
 
85
 
 
86
  memset (catbuf, 0, sizeof (struct catbuf));
 
87
  if (minimum_length > 0)
 
88
    cat_alloc (catbuf, minimum_length);
 
89
}
 
90
 
 
91
/* Free memory allocated to the buffer */
 
92
void
 
93
cat_free (struct catbuf *catbuf)
 
94
{
 
95
  assert (catbuf != NULL);
 
96
 
 
97
  if (catbuf->buffer != NULL)
 
98
    free (catbuf->buffer);
 
99
  memset (catbuf, 0, sizeof (struct catbuf));
 
100
}
 
101
 
 
102
/* Return a pointer to the buffer and put its length in *len. */
 
103
char *
 
104
cat_buffer (struct catbuf *catbuf, int *len)
 
105
{
 
106
  assert (catbuf != NULL);
 
107
 
 
108
  if (len != NULL)
 
109
    *len = catbuf->string_length;
 
110
  return catbuf->buffer;
 
111
}
 
112
 
 
113
/* Shrink the allocated memory to the minimum needed.  Return a
 
114
   pointer to the buffer and put its length in *len. */
 
115
char *
 
116
cat_shrink (struct catbuf *catbuf, int *len)
 
117
{
 
118
  assert (catbuf != NULL);
 
119
 
 
120
  if (catbuf->buffer != NULL)
 
121
    cat_alloc (catbuf, catbuf->string_length);
 
122
  if (len != NULL)
 
123
    *len = catbuf->string_length;
 
124
  return catbuf->buffer;
 
125
}
 
126
 
 
127
/* Concatenate a string to the buffer.  N.B. the buffer is NOT terminated
 
128
   by a \0.  If len < 0 then string must be \0 terminated. */
 
129
char *
 
130
concatenate (struct catbuf *catbuf, const char *string, int len)
 
131
{
 
132
  size_t shortfall;
 
133
 
 
134
  assert (catbuf != NULL && string != NULL);
 
135
 
 
136
  if (len < 0)
 
137
    len = strlen (string);
 
138
 
 
139
  /* Ensure that the buffer is big enough to accept the string */
 
140
  if (catbuf->buffer == NULL)
 
141
    shortfall = 512;
 
142
  else
 
143
    shortfall = len - (catbuf->allocated - catbuf->string_length);
 
144
  if (shortfall > 0)
 
145
    {
 
146
      if (shortfall % 128 != 0)
 
147
        shortfall += 128 - shortfall % 128;
 
148
      if (!cat_alloc (catbuf, catbuf->allocated + shortfall))
 
149
        return NULL;
 
150
    }
 
151
 
 
152
  /* Copy the string */
 
153
  memcpy (catbuf->buffer + catbuf->string_length, string, len);
 
154
  catbuf->string_length += len;
 
155
 
 
156
  return catbuf->buffer;
 
157
}
 
158
 
 
159
char *
 
160
vconcatenate (struct catbuf *catbuf, ...)
 
161
{
 
162
  va_list alist;
 
163
  const char *string;
 
164
 
 
165
  assert (catbuf != NULL);
 
166
 
 
167
  va_start (alist, catbuf);
 
168
  while ((string = va_arg (alist, const char *)) != NULL)
 
169
    concatenate (catbuf, string, -1);
 
170
  va_end (alist);
 
171
  return catbuf->buffer;
 
172
}
 
173
 
 
174
int
 
175
cat_printf (struct catbuf *catbuf, const char *format, ...)
 
176
{
 
177
  va_list alist;
 
178
  char buf[1024];
 
179
  int len;
 
180
 
 
181
  assert (catbuf != NULL && format != NULL);
 
182
 
 
183
  va_start (alist, format);
 
184
  len = vsnprintf (buf, sizeof buf, format, alist);
 
185
  va_end (alist);
 
186
  if (len <= 0)
 
187
    return len;
 
188
  if (len >= (int) sizeof buf)
 
189
    len = sizeof buf;
 
190
  concatenate (catbuf, buf, len);
 
191
  return len;
 
192
}