diff options
Diffstat (limited to 'mailbox/nntp/nntp_stream.c')
-rw-r--r-- | mailbox/nntp/nntp_stream.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/mailbox/nntp/nntp_stream.c b/mailbox/nntp/nntp_stream.c new file mode 100644 index 000000000..a76f91743 --- /dev/null +++ b/mailbox/nntp/nntp_stream.c @@ -0,0 +1,145 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2003, 2004 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <string.h> +#include <errno.h> +#include <stdlib.h> +#include <mailutils/sys/nntp.h> + +/* Implementation of the stream for TOP and RETR. */ +struct mu_nntp_stream +{ + mu_nntp_t nntp; + int done; +}; + +static void +mu_nntp_stream_destroy (stream_t stream) +{ + struct mu_nntp_stream *nntp_stream = stream_get_owner (stream); + if (nntp_stream) + { + free (nntp_stream); + } +} + +static int +mu_nntp_stream_read (stream_t stream, char *buf, size_t buflen, off_t offset, size_t *pn) +{ + struct mu_nntp_stream *nntp_stream = stream_get_owner (stream); + size_t n = 0; + int status = 0; + char *p = buf; + + (void)offset; + if (nntp_stream) + { + if (!nntp_stream->done) + { + do + { + size_t nread = 0; + + /* The nntp_readline () function will always read one less to + be able to null terminate the buffer, this will cause + serious grief for stream_read() where it is legitimate to + have a buffer of 1 char. So we must catch it here. */ + if (buflen == 1) + { + char buffer[2]; + *buffer = '\0'; + status = mu_nntp_readline (nntp_stream->nntp, buffer, 2, &nread); + *p = *buffer; + } + else + status = mu_nntp_readline (nntp_stream->nntp, p, buflen, &nread); + + if (status != 0) + break; + if (nread == 0) + { + nntp_stream->nntp->state = MU_NNTP_NO_STATE; + nntp_stream->done = 1; + break; + } + n += nread; + buflen -= nread; + p += nread; + } + while (buflen > 0); + } + } + if (pn) + *pn = n; + return status; +} + +static int +mu_nntp_stream_readline (stream_t stream, char *buf, size_t buflen, off_t offset, size_t *pn) +{ + struct mu_nntp_stream *nntp_stream = stream_get_owner (stream); + size_t n = 0; + int status = 0; + + (void)offset; + if (nntp_stream) + { + if (!nntp_stream->done) + { + status = mu_nntp_readline (nntp_stream->nntp, buf, buflen, &n); + if (n == 0) + { + nntp_stream->nntp->state = MU_NNTP_NO_STATE; + nntp_stream->done = 1; + } + } + } + if (pn) + *pn = n; + return status; +} + +int +mu_nntp_stream_create (mu_nntp_t nntp, stream_t *pstream) +{ + struct mu_nntp_stream *nntp_stream; + int status; + + nntp_stream = malloc (sizeof *nntp_stream); + if (nntp_stream == NULL) + return ENOMEM; + + nntp_stream->nntp = nntp; + nntp_stream->done = 0; + + status = stream_create (pstream, MU_STREAM_READ | MU_STREAM_NO_CLOSE | MU_STREAM_NO_CHECK, nntp_stream); + if (status != 0) + { + free (nntp_stream); + return status; + } + + stream_set_read (*pstream, mu_nntp_stream_read, nntp_stream); + stream_set_readline (*pstream, mu_nntp_stream_readline, nntp_stream); + stream_set_destroy (*pstream, mu_nntp_stream_destroy, nntp_stream); + + return 0; +} |