summaryrefslogtreecommitdiff
path: root/mailbox/nntp/nntp_stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'mailbox/nntp/nntp_stream.c')
-rw-r--r--mailbox/nntp/nntp_stream.c145
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;
+}

Return to:

Send suggestions and report system problems to the System administrator.