Commit f50de094 f50de094ab26e6e81438d056e31236e776e4dc65 by Alain Magloire

nntp_carrier.c nntp_connect.c nntp_create.c nntp_debug.c

 	nntp_destroy.c nntp_disconnect.c nntp_readline.c
 	nntp_response.c nntp_sendline.c nntp_stream.c nntp_timeout.c

framework for NNTP support
1 parent fcba0963
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 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 <stdlib.h>
#include <errno.h>
#include <mailutils/sys/nntp.h>
int
mu_nntp_set_carrier (mu_nntp_t nntp, stream_t carrier)
{
/* Sanity checks. */
if (nntp == NULL)
return EINVAL;
if (nntp->carrier)
{
/* Close any old carrier. */
mu_nntp_disconnect (nntp);
stream_destroy (&nntp->carrier, nntp);
}
nntp->carrier = carrier;
return 0;
}
int
mu_nntp_get_carrier (mu_nntp_t nntp, stream_t *pcarrier)
{
/* Sanity checks. */
if (nntp == NULL)
return EINVAL;
if (pcarrier == NULL)
return MU_ERR_OUT_PTR_NULL;
*pcarrier = nntp->carrier;
return 0;
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 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 <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <mailutils/sys/nntp.h>
/* Open the connection to the server. */
int
mu_nntp_connect (mu_nntp_t nntp)
{
int status;
/* Sanity checks. */
if (nntp == NULL)
return EINVAL;
/* A networking stack. */
if (nntp->carrier == NULL)
return EINVAL;
/* Enter the pop state machine, and boogy: AUTHORISATION State. */
switch (nntp->state)
{
default:
/* FALLTHROUGH */
/* If nntp was in an error state going through here should clear it. */
case MU_NNTP_NO_STATE:
status = mu_nntp_disconnect (nntp);
MU_NNTP_CHECK_EAGAIN (nntp, status);
nntp->state = MU_NNTP_CONNECT;
case MU_NNTP_CONNECT:
/* Establish the connection. */
status = stream_open (nntp->carrier);
MU_NNTP_CHECK_EAGAIN (nntp, status);
nntp->acknowledge = 0;
nntp->state = MU_NNTP_GREETINGS;
case MU_NNTP_GREETINGS:
/* Get the greetings. */
{
size_t len = 0;
char *right, *left;
status = mu_nntp_response (nntp, NULL, 0, &len);
MU_NNTP_CHECK_EAGAIN (nntp, status);
mu_nntp_debug_ack (nntp);
if (nntp->ack.buf[0] == '2')
{
stream_close (nntp->carrier);
nntp->state = MU_NNTP_NO_STATE;
return EACCES;
}
nntp->state = MU_NNTP_NO_STATE;
}
} /* End AUTHORISATION state. */
return status;
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 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 <stdlib.h>
#include <errno.h>
#include <mailutils/errno.h>
#include <mailutils/sys/nntp.h>
/* Initialise a mu_nntp_t handle. */
int
mu_nntp_create (mu_nntp_t *pnntp)
{
mu_nntp_t nntp;
/* Sanity check. */
if (pnntp == NULL)
return EINVAL;
nntp = calloc (1, sizeof *nntp);
if (nntp == NULL)
return ENOMEM;
/* Reserve space for the ack(nowledgement) response.
According to RFC 977: The maximum length of the first line of a
command response (including the initial greeting) is unchanged at
512 octets (including the terminating CRLF). */
nntp->ack.len = 512;
nntp->ack.buf = calloc (nntp->ack.len, 1);
if (nntp->ack.buf == NULL)
{
mu_nntp_destroy (&nntp);
return ENOMEM;
}
nntp->ack.ptr = nntp->ack.buf;
/* Reserve space for the data response/content.
RFC 977 recommands 255, but we grow it as needed. */
nntp->io.len = 255;
nntp->io.buf = calloc (nntp->io.len, 1);
if (nntp->io.buf == NULL)
{
mu_nntp_destroy (&nntp);
return ENOMEM;
}
nntp->io.ptr = nntp->io.buf;
nntp->state = MU_NNTP_NO_STATE; /* Init with no state. */
nntp->timeout = (10 * 60) * 100; /* The default Timeout is 10 minutes. */
nntp->acknowledge = 0; /* No Ack received. */
*pnntp = nntp;
return 0; /* Okdoke. */
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 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 <stdlib.h>
#include <errno.h>
#include <mailutils/sys/nntp.h>
int
mu_nntp_set_debug (mu_nntp_t nntp, mu_debug_t debug)
{
if (nntp == NULL)
return EINVAL;
if (nntp->debug)
mu_debug_destroy (&nntp->debug, NULL);
nntp->debug = debug;
return 0;
}
int
mu_nntp_debug_cmd (mu_nntp_t nntp)
{
if (nntp->debug)
mu_debug_print(nntp->debug, MU_DEBUG_PROT, "%s", nntp->io.buf);
return 0;
}
int
mu_nntp_debug_ack (mu_nntp_t nntp)
{
if (nntp->debug)
{
mu_debug_print (nntp->debug, MU_DEBUG_PROT, "%s\n", nntp->ack.buf);
}
return 0;
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 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 <stdlib.h>
#include <mailutils/errno.h>
#include <mailutils/sys/nntp.h>
void
mu_nntp_destroy (mu_nntp_t *pnntp)
{
if (pnntp && *pnntp)
{
mu_nntp_t nntp = *pnntp;
/* Free the response buffer. */
if (nntp->ack.buf)
free (nntp->ack.buf);
/* Free the io buffer. */
if (nntp->io.buf)
free (nntp->io.buf);
/* Release the carrier. */
if (nntp->carrier)
stream_destroy (&nntp->carrier, nntp);
free (nntp);
*pnntp = NULL;
}
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 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 <stdlib.h>
#include <string.h>
#include <errno.h>
#include <mailutils/sys/nntp.h>
int
mu_nntp_disconnect (mu_nntp_t nntp)
{
/* Sanity checks. */
if (nntp == NULL)
return EINVAL;
/* We can keep some of the fields, if they decide to nntp_connect() again but
clear the states. */
nntp->state = MU_NNTP_NO_STATE;
nntp->acknowledge = 0;
/* Clear the buffers. */
memset (nntp->io.buf, '\0', nntp->io.len);
nntp->io.ptr = nntp->io.buf;
memset (nntp->ack.buf, '\0', nntp->ack.len);
nntp->ack.ptr = nntp->ack.buf;
/* Close the stream. */
return stream_close (nntp->carrier);
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
#include <mailutils/sys/nntp.h>
#include <mailutils/error.h>
int
mu_nntp_carrier_is_ready (stream_t carrier, int flag, int timeout)
{
struct timeval tv, *tvp = NULL;
int wflags = flag;
int status;
if (timeout >= 0)
{
tv.tv_sec = timeout / 100;
tv.tv_usec = (timeout % 1000) * 1000;
tvp = &tv;
}
status = stream_wait (carrier, &wflags, tvp);
if (status)
return 0; /* FIXME: provide a way to return error code! */
return wflags & flag;
}
/* Read a complete line from the nntp server. Transform CRLF to LF, remove
the stuff byte termination octet ".", put a null in the buffer
when done. And Do a select() (stream_is_readready()) for the timeout. */
static int
mu_nntp_getline (mu_nntp_t nntp)
{
size_t n = 0;
size_t total = nntp->io.ptr - nntp->io.buf;
int status = 0;
/* Must get a full line before bailing out. */
do
{
/* Timeout with select(), note that we have to reset select()
since on linux tv is modified when error. */
if (nntp->timeout)
{
int ready = mu_nntp_carrier_is_ready (nntp->carrier,
MU_STREAM_READY_RD,
nntp->timeout);
if (ready == 0)
return ETIMEDOUT;
}
status = stream_sequential_readline (nntp->carrier, nntp->io.buf + total, nntp->io.len - total, &n);
if (status != 0)
return status;
/* The server went away: It maybe a timeout and some nntp server
does not send the -ERR. Consider this like an error. */
if (n == 0)
return EIO;
total += n;
nntp->io.nl = memchr (nntp->io.buf, '\n', total);
if (nntp->io.nl == NULL) /* Do we have a full line. */
{
/* Allocate a bigger buffer ? */
if (total >= nntp->io.len - 1)
{
nntp->io.len *= 2;
nntp->io.buf = realloc (nntp->io.buf, nntp->io.len + 1);
if (nntp->io.buf == NULL)
return ENOMEM;
}
}
nntp->io.ptr = nntp->io.buf + total;
}
while (nntp->io.nl == NULL); /* Bail only if we have a complete line. */
/* When examining a multi-line response, the client checks to see if the
line begins with the termination octet "."(DOT). If yes and if octets
other than CRLF follow, the first octet of the line (the termination
octet) is stripped away. */
if (total >= 3 && nntp->io.buf[0] == '.')
{
if (nntp->io.buf[1] != '\r' && nntp->io.buf[2] != '\n')
{
memmove (nntp->io.buf, nntp->io.buf + 1, total - 1);
nntp->io.ptr--;
nntp->io.nl--;
}
/* And if CRLF immediately follows the termination character, then
the response from the NNTP server is ended and the line containing
".CRLF" is not considered part of the multi-line response. */
else if (nntp->io.buf[1] == '\r' && nntp->io.buf[2] == '\n')
{
nntp->io.buf[0] = '\0';
nntp->io.ptr = nntp->io.buf;
nntp->io.nl = NULL;
}
}
/* \r\n --> \n\0, conversion. */
if (nntp->io.nl > nntp->io.buf)
{
*(nntp->io.nl - 1) = '\n';
*(nntp->io.nl) = '\0';
nntp->io.ptr = nntp->io.nl;
}
return status;
}
/* Call nntp_getline() for the dirty work, and consume i.e. put
in the user buffer only buflen. If buflen == 0 or buffer == NULL
nothing is consume, the data is save for another call to nntp_readline()
with a buffer != NULL.
*/
int
mu_nntp_readline (mu_nntp_t nntp, char *buffer, size_t buflen, size_t *pnread)
{
size_t nread = 0;
size_t n = 0;
int status = 0;
/* Do we need to fill up? Yes if no NL or the buffer is empty. */
if (nntp->carrier && (nntp->io.nl == NULL || nntp->io.ptr == nntp->io.buf))
{
status = mu_nntp_getline (nntp);
if (status != 0)
return status;
}
/* How much we can copy ? */
n = nntp->io.ptr - nntp->io.buf;
/* Consume the line? */
if (buffer && buflen)
{
buflen--; /* For the null. */
if (buflen)
{
int nleft = buflen - n;
/* We got more then requested. */
if (nleft < 0)
{
size_t sentinel;
nread = buflen;
sentinel = nntp->io.ptr - (nntp->io.buf + nread);
memcpy (buffer, nntp->io.buf, nread);
memmove (nntp->io.buf, nntp->io.buf + nread, sentinel);
nntp->io.ptr = nntp->io.buf + sentinel;
}
else
{
/* Drain our buffer. */;
nread = n;
memcpy (buffer, nntp->io.buf, nread);
nntp->io.ptr = nntp->io.buf;
/* Clear of all residue. */
memset (nntp->io.buf, '\0', nntp->io.len);
}
}
buffer[nread] = '\0';
}
else
nread = n;
if (pnread)
*pnread = nread;
return status;
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 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 <mailutils/sys/nntp.h>
/* If we did not grap the ack already, call nntp_readline() but handle
Nonblocking also. */
int
mu_nntp_response (mu_nntp_t nntp, char *buffer, size_t buflen, size_t *pnread)
{
size_t n = 0;
int status = 0;
if (nntp == NULL)
return EINVAL;
if (!nntp->acknowledge)
{
size_t len = nntp->ack.len - (nntp->ack.ptr - nntp->ack.buf);
status = mu_nntp_readline (nntp, nntp->ack.ptr, len, &n);
nntp->ack.ptr += n;
if (status == 0)
{
len = nntp->ack.ptr - nntp->ack.buf;
if (len && nntp->ack.buf[len - 1] == '\n')
nntp->ack.buf[len - 1] = '\0';
nntp->acknowledge = 1; /* Flag that we have the ack. */
nntp->ack.ptr = nntp->ack.buf;
}
else
{
/* Provide them with an error. */
const char *econ = "500 NNTP IO ERROR";
n = strlen (econ);
strcpy (nntp->ack.buf, econ);
}
}
else
n = strlen (nntp->ack.buf);
if (buffer)
{
buflen--; /* Leave space for the NULL. */
n = (buflen < n) ? buflen : n;
memcpy (buffer, nntp->ack.buf, n);
buffer[n] = '\0';
}
if (pnread)
*pnread = n;
return status;
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 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
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <mailutils/sys/nntp.h>
/* A socket may write less then expected but stream.c:stream_write() will
always try to send the entire buffer unless an error is reported. We have
to cope with nonblocking, it is done by keeping track with the nntp->ptr
pointer if the write failed we keep track and restart where we left. */
int
mu_nntp_send (mu_nntp_t nntp)
{
int status = 0;
if (nntp->carrier && (nntp->io.ptr > nntp->io.buf))
{
size_t n = 0;
size_t len = nntp->io.ptr - nntp->io.buf;
/* Timeout with select(), note that we have to reset select()
since on linux tv is modified when error. */
if (nntp->timeout)
{
int ready = mu_nntp_carrier_is_ready (nntp->carrier,
MU_STREAM_READY_WR,
nntp->timeout);
if (ready == 0)
return ETIMEDOUT;
}
status = stream_write (nntp->carrier, nntp->io.buf, len, 0, &n);
if (n)
{
/* Consume what we sent. */
memmove (nntp->io.buf, nntp->io.buf + n, len - n);
nntp->io.ptr -= n;
}
}
else
nntp->io.ptr = nntp->io.buf;
return status;
}
/* According to RFC 2449: The maximum length of a command is increased from
47 characters (4 character command, single space, 40 character argument,
CRLF) to 255 octets, including the terminating CRLF. But we are flexible
on this and realloc() as needed. NOTE: The terminated CRLF is not
included. */
int
mu_nntp_writeline (mu_nntp_t nntp, const char *format, ...)
{
int len;
va_list ap;
int done = 1;
va_start(ap, format);
/* C99 says that a conforming implementation of snprintf () should
return the number of char that would have been call but many old
GNU/Linux && BSD implementations return -1 on error. Worse,
QnX/Neutrino actually does not put the terminal null char. So
let's try to cope. */
do
{
len = vsnprintf (nntp->io.buf, nntp->io.len - 1, format, ap);
if (len < 0 || len >= (int)nntp->io.len
|| !memchr (nntp->io.buf, '\0', len + 1))
{
nntp->io.len *= 2;
nntp->io.buf = realloc (nntp->io.buf, nntp->io.len);
if (nntp->io.buf == NULL)
return ENOMEM;
done = 0;
}
else
done = 1;
}
while (!done);
va_end(ap);
nntp->io.ptr = nntp->io.buf + len;
return 0;
}
int
mu_nntp_sendline (mu_nntp_t nntp, const char *line)
{
if (line)
{
int status = mu_nntp_writeline (nntp, line);
if (status)
return status;
}
return mu_nntp_send (nntp);
}
/* 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;
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 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 <stdlib.h>
#include <errno.h>
#include <mailutils/sys/nntp.h>
int
mu_nntp_set_timeout (mu_nntp_t nntp, int timeout)
{
/* Sanity checks. */
if (nntp == NULL)
return EINVAL;
nntp->timeout = timeout;
return 0;
}
int
mu_nntp_get_timeout (mu_nntp_t nntp, int *ptimeout)
{
/* Sanity checks. */
if (nntp == NULL)
return EINVAL;
if (ptimeout == NULL)
return MU_ERR_OUT_PTR_NULL;
*ptimeout = nntp->timeout;
return 0;
}