Pull up CVS idents from FreeBSD to match our current version.
[dragonfly.git] / contrib / ntpd / buffer.c
blobddd775c839eb78ded5283e1e4203c6de6aa947a0
1 /* $OpenBSD: src/usr.sbin/ntpd/buffer.c,v 1.6 2005/03/23 11:36:35 henning Exp $ */
3 /*
4 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
20 #include <sys/uio.h>
22 #include <errno.h>
23 #include <limits.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
29 #include "ntpd.h"
31 void buf_enqueue(struct msgbuf *, struct buf *);
32 void buf_dequeue(struct msgbuf *, struct buf *);
34 struct buf *
35 buf_open(size_t len)
37 struct buf *buf;
39 if ((buf = calloc(1, sizeof(struct buf))) == NULL)
40 return (NULL);
41 if ((buf->buf = malloc(len)) == NULL) {
42 free(buf);
43 return (NULL);
45 buf->size = len;
47 return (buf);
50 int
51 buf_add(struct buf *buf, void *data, size_t len)
53 if (buf->wpos + len > buf->size)
54 return (-1);
56 memcpy(buf->buf + buf->wpos, data, len);
57 buf->wpos += len;
58 return (0);
61 int
62 buf_close(struct msgbuf *msgbuf, struct buf *buf)
64 buf_enqueue(msgbuf, buf);
65 return (1);
68 void
69 buf_free(struct buf *buf)
71 free(buf->buf);
72 free(buf);
75 void
76 msgbuf_init(struct msgbuf *msgbuf)
78 msgbuf->queued = 0;
79 msgbuf->fd = -1;
80 TAILQ_INIT(&msgbuf->bufs);
83 void
84 msgbuf_clear(struct msgbuf *msgbuf)
86 struct buf *buf;
88 while ((buf = TAILQ_FIRST(&msgbuf->bufs)) != NULL)
89 buf_dequeue(msgbuf, buf);
92 int
93 msgbuf_write(struct msgbuf *msgbuf)
95 struct iovec iov[IOV_MAX];
96 struct buf *buf, *next;
97 int i = 0;
98 ssize_t n;
100 bzero(&iov, sizeof(iov));
101 TAILQ_FOREACH(buf, &msgbuf->bufs, entries) {
102 if (i >= IOV_MAX)
103 break;
104 iov[i].iov_base = buf->buf + buf->rpos;
105 iov[i].iov_len = buf->size - buf->rpos;
106 i++;
109 if ((n = writev(msgbuf->fd, iov, i)) == -1) {
110 if (errno == EAGAIN) /* cannot write immediately */
111 return (0);
112 else
113 return (-1);
116 if (n == 0) { /* connection closed */
117 errno = 0;
118 return (-2);
121 for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0;
122 buf = next) {
123 next = TAILQ_NEXT(buf, entries);
124 if (buf->rpos + n >= buf->size) {
125 n -= buf->size - buf->rpos;
126 buf_dequeue(msgbuf, buf);
127 } else {
128 buf->rpos += n;
129 n = 0;
133 return (0);
136 void
137 buf_enqueue(struct msgbuf *msgbuf, struct buf *buf)
139 TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entries);
140 msgbuf->queued++;
143 void
144 buf_dequeue(struct msgbuf *msgbuf, struct buf *buf)
146 TAILQ_REMOVE(&msgbuf->bufs, buf, entries);
147 msgbuf->queued--;
148 buf_free(buf);