2
* This file is part of libESMTP, a library for submission of RFC 2822
3
* formatted electronic mail messages using the SMTP protocol described
6
* Copyright (C) 2001,2002 Brian Stafford <brian@stafford.uklinux.net>
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.
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.
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
23
/* Functions to read lines or blocks of text from the message source.
24
These functions allow the library to interface to the application
25
using a callback function. This is intended to allow the application
26
maximum flexibility in managing its message storage. */
36
#include "message-source.h"
38
/* This is similar to code in siobuf.c */
42
/* Callback to fill the input buffer */
43
const char *(*cb) (void **ctx, int *len, void *arg);
48
const char *rp; /* input buffer pointer */
49
int rn; /* number of bytes unread in buffer */
51
/* Output buffer (used by msg_gets()) */
57
msg_source_create (void)
61
if ((source = malloc (sizeof (struct msg_source))) != NULL)
62
memset (source, 0, sizeof (struct msg_source));
67
msg_source_destroy (msg_source_t source)
69
assert (source != NULL);
71
if (source->ctx != NULL)
73
if (source->buf != NULL)
79
msg_source_set_cb (msg_source_t source,
80
const char *(*cb) (void **ctx, int *len, void *arg),
83
assert (source != NULL);
85
if (source->ctx != NULL)
94
/* Use the callback to get data from the message source.
97
msg_fill (msg_source_t source)
99
assert (source != NULL && source->cb != NULL);
101
source->rp = (*source->cb) (&source->ctx, &source->rn, source->arg);
102
return source->rn > 0;
106
msg_rewind (msg_source_t source)
108
assert (source != NULL && source->cb != NULL);
110
(*source->cb) (&source->ctx, NULL, source->arg);
113
/* Line oriented reader. An output buffer is allocated as required.
114
The return value is a pointer to the line and remains valid until the
115
next call to msg_gets (). The line is guaranteed to be terminated
116
with a \r\n. Len is set to the number of octets in the buffer.
117
The line is *not* terminated with a \0.
119
If concatenate is non-zero, the next line of input is concatenated
120
with the existing line and the return value points to the original
121
line in the buffer. In this case *len is the number of octets in
122
the buffer when called and is updated to the new count on return.
125
msg_gets (msg_source_t source, int *len, int concatenate)
127
int lastc, c, buflen;
130
assert (source != NULL && len != NULL);
132
if (source->rn <= 0 && !msg_fill (source))
135
if (source->buf == NULL)
137
source->nalloc = 1023; /* RFC 2821 max line length + slack */
138
source->buf = malloc (source->nalloc + 2);
139
if (source->buf == NULL)
143
buflen = source->nalloc;
151
while (source->rn > 0 || msg_fill (source))
158
source->nalloc += buflen;
159
nbuf = realloc (source->buf, source->nalloc + 2);
165
p = nbuf + (p - source->buf);
170
if (c == '\n' && lastc == '\r')
172
*len = p - source->buf;
177
/* Only get here if the input was not properly terminated with a \r\n.
178
The handling of the DATA command in protocol.c relies on the \n
179
so we add it here. This is why there is 2 characters of slack in
180
malloc and realloc above. */
184
*len = p - source->buf;
188
/* Return the next character in the source, i.e. the first character
189
that will be returned by the next call to msg_gets(). This is
190
currently only used to check for RFC 2822 header continuation lines.
191
It is not safe to use in conjunction with msg_getb().
194
msg_nextc (msg_source_t source)
196
assert (source != NULL);
198
if (source->rn <= 0 && !msg_fill (source))
204
/* Block oriented reader. The output buffer is not used for efficiency.
207
msg_getb (msg_source_t source, int *len)
209
assert (source != NULL);
211
if (source->rn <= 0 && !msg_fill (source))
214
/* Just return whatever is in the input buffer */