#include <config.h>
#include <stdio.h>
#include "cvs.h"
#include "buffer.h"
#include "ms-buffer.h"
#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT)
#ifdef PROXY_SUPPORT
struct ms_buffer
{
struct buffer *buf;
struct buffer *cur;
List *bufs;
bool block;
};
static int
ms_buffer_block (void *closure, bool block)
{
struct ms_buffer *mb = closure;
mb->block = block;
if (block)
return set_block (mb->cur);
else
return set_nonblock (mb->cur);
}
static int
ms_buffer_input (void *closure, char *data, size_t need, size_t size,
size_t *got)
{
struct ms_buffer *mb = closure;
int status;
assert (mb->cur->input);
status = (*mb->cur->input) (mb->cur->closure, data, need, size, got);
if (status == -1)
{
Node *p;
if (list_isempty (mb->bufs)) return -1;
buf_shutdown (mb->cur);
buf_free (mb->cur);
p = mb->bufs->list->next;
mb->cur = p->data;
p->delproc = NULL;
p->data = NULL;
delnode (p);
if (!buf_empty_p (mb->cur)) buf_append_buffer (mb->buf, mb->cur);
ms_buffer_block (closure, mb->block);
*got = 0;
status = 0;
}
return status;
}
static int
ms_buffer_get_fd (void *closure)
{
struct ms_buffer *mb = closure;
return buf_get_fd (mb->cur);
}
static int
ms_buffer_shutdown (struct buffer *buf)
{
struct ms_buffer *mb = buf->closure;
Node *p;
int err = 0;
assert (mb->cur);
err += buf_shutdown (mb->cur);
buf_free (mb->cur);
for (p = mb->bufs->list->next; p != mb->bufs->list; p = p->next)
{
assert (p);
err += buf_shutdown (p->data);
}
dellist (&mb->bufs);
return err;
}
static void
delbuflist (Node *p)
{
if (p->data)
buf_free (p->data);
}
struct buffer *
ms_buffer_initialize (void (*memory) (struct buffer *),
struct buffer *buf, struct buffer *buf2)
{
struct ms_buffer *mb = xmalloc (sizeof *mb);
struct buffer *retbuf;
Node *p;
mb->block = false;
mb->cur = buf;
set_nonblock (buf);
mb->bufs = getlist ();
p = getnode ();
p->data = buf2;
p->delproc = delbuflist;
addnode (mb->bufs, p);
retbuf = buf_initialize (ms_buffer_input, NULL, NULL,
ms_buffer_block, ms_buffer_get_fd,
ms_buffer_shutdown, memory, mb);
if (!buf_empty_p (buf)) buf_append_buffer (retbuf, buf);
mb->buf = retbuf;
return retbuf;
}
#endif
#endif