summaryrefslogtreecommitdiff
path: root/usr.sbin/snmpd/imsg.c
diff options
context:
space:
mode:
authorPierre-Yves Ritschard <pyr@cvs.openbsd.org>2009-06-06 05:52:02 +0000
committerPierre-Yves Ritschard <pyr@cvs.openbsd.org>2009-06-06 05:52:02 +0000
commit8d0733a46ab21b9a74bb53e474cab34e0e458771 (patch)
treee95f633833861d3b804667bdb7cb0eb67331294b /usr.sbin/snmpd/imsg.c
parentf4e5d68bcd3927bf4124d5b83fe246911d8c0c92 (diff)
sync snmpd with the common imsg code, making it lib ready as well.
ok eric@
Diffstat (limited to 'usr.sbin/snmpd/imsg.c')
-rw-r--r--usr.sbin/snmpd/imsg.c96
1 files changed, 43 insertions, 53 deletions
diff --git a/usr.sbin/snmpd/imsg.c b/usr.sbin/snmpd/imsg.c
index a7671183bec..cc1d07e0466 100644
--- a/usr.sbin/snmpd/imsg.c
+++ b/usr.sbin/snmpd/imsg.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: imsg.c,v 1.5 2008/03/24 16:11:05 deraadt Exp $ */
+/* $OpenBSD: imsg.c,v 1.6 2009/06/06 05:52:01 pyr Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -16,35 +16,27 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <sys/types.h>
-#include <sys/socket.h>
+#include <sys/param.h>
#include <sys/queue.h>
+#include <sys/socket.h>
#include <sys/uio.h>
-#include <sys/param.h>
-#include <sys/tree.h>
-
-#include <net/if.h>
#include <errno.h>
-#include <event.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include "snmpd.h"
+#include "imsg.h"
void
-imsg_init(struct imsgbuf *ibuf, int fd, void (*handler)(int, short, void *))
+imsg_init(struct imsgbuf *ibuf, int fd)
{
- if (!ibuf->pid) {
- msgbuf_init(&ibuf->w);
- bzero(&ibuf->r, sizeof(ibuf->r));
- ibuf->pid = getpid();
- ibuf->handler = handler;
- TAILQ_INIT(&ibuf->fds);
- }
+ msgbuf_init(&ibuf->w);
+ bzero(&ibuf->r, sizeof(ibuf->r));
ibuf->fd = fd;
ibuf->w.fd = fd;
+ ibuf->pid = getpid();
+ TAILQ_INIT(&ibuf->fds);
}
ssize_t
@@ -54,7 +46,7 @@ imsg_read(struct imsgbuf *ibuf)
struct cmsghdr *cmsg;
union {
struct cmsghdr hdr;
- char buf[CMSG_SPACE(sizeof(int) * 16)];
+ char buf[CMSG_SPACE(sizeof(int) * 16)];
} cmsgbuf;
struct iovec iov;
ssize_t n;
@@ -72,7 +64,6 @@ imsg_read(struct imsgbuf *ibuf)
if ((n = recvmsg(ibuf->fd, &msg, 0)) == -1) {
if (errno != EINTR && errno != EAGAIN) {
- log_warn("imsg_read: pipe read error");
return (-1);
}
return (-2);
@@ -85,13 +76,14 @@ imsg_read(struct imsgbuf *ibuf)
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS) {
fd = (*(int *)CMSG_DATA(cmsg));
- if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL)
- fatal("imsg_read calloc");
+ if ((ifd = calloc(1, sizeof(struct imsg_fd))) == NULL) {
+ /* XXX: this return can leak */
+ return (-1);
+ }
ifd->fd = fd;
TAILQ_INSERT_TAIL(&ibuf->fds, ifd, entry);
- } else
- log_warn("imsg_read: got unexpected ctl data level %d "
- "type %d", cmsg->cmsg_level, cmsg->cmsg_type);
+ }
+ /* we do not handle other ctl data level */
}
return (n);
@@ -110,8 +102,7 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
memcpy(&imsg->hdr, ibuf->r.buf, sizeof(imsg->hdr));
if (imsg->hdr.len < IMSG_HEADER_SIZE ||
imsg->hdr.len > MAX_IMSGSIZE) {
- log_warnx("imsg_get: imsg hdr len %u out of bounds, type=%u",
- imsg->hdr.len, imsg->hdr.type);
+ errno = ERANGE;
return (-1);
}
if (imsg->hdr.len > av)
@@ -119,7 +110,6 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
ibuf->r.rptr = ibuf->r.buf + IMSG_HEADER_SIZE;
if ((imsg->data = malloc(datalen)) == NULL) {
- log_warn("imsg_get");
return (-1);
}
memcpy(imsg->data, ibuf->r.rptr, datalen);
@@ -135,11 +125,10 @@ imsg_get(struct imsgbuf *ibuf, struct imsg *imsg)
}
int
-imsg_compose(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid,
+imsg_compose(struct imsgbuf *ibuf, u_int16_t type, u_int32_t peerid,
pid_t pid, int fd, void *data, u_int16_t datalen)
{
struct buf *wbuf;
- int n;
if ((wbuf = imsg_create(ibuf, type, peerid, pid, datalen)) == NULL)
return (-1);
@@ -149,18 +138,16 @@ imsg_compose(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid,
wbuf->fd = fd;
- if ((n = imsg_close(ibuf, wbuf)) < 0)
- return (-1);
+ imsg_close(ibuf, wbuf);
- return (n);
+ return (1);
}
int
-imsg_composev(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid,
+imsg_composev(struct imsgbuf *ibuf, u_int16_t type, u_int32_t peerid,
pid_t pid, int fd, const struct iovec *iov, int iovcnt)
{
struct buf *wbuf;
- int n;
int i, datalen = 0;
for (i = 0; i < iovcnt; i++)
@@ -175,15 +162,14 @@ imsg_composev(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid,
wbuf->fd = fd;
- if ((n = imsg_close(ibuf, wbuf)) < 0)
- return (-1);
+ imsg_close(ibuf, wbuf);
- return (n);
+ return (1);
}
/* ARGSUSED */
struct buf *
-imsg_create(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid,
+imsg_create(struct imsgbuf *ibuf, u_int16_t type, u_int32_t peerid,
pid_t pid, u_int16_t datalen)
{
struct buf *wbuf;
@@ -191,9 +177,7 @@ imsg_create(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid,
datalen += IMSG_HEADER_SIZE;
if (datalen > MAX_IMSGSIZE) {
- log_warnx("imsg_create: len %u > MAX_IMSGSIZE; "
- "type %u peerid %lu", datalen + IMSG_HEADER_SIZE,
- type, peerid);
+ errno = ERANGE;
return (NULL);
}
@@ -202,7 +186,6 @@ imsg_create(struct imsgbuf *ibuf, enum imsg_type type, u_int32_t peerid,
if ((hdr.pid = pid) == 0)
hdr.pid = ibuf->pid;
if ((wbuf = buf_dynamic(datalen, MAX_IMSGSIZE)) == NULL) {
- log_warn("imsg_create: buf_open");
return (NULL);
}
if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1)
@@ -216,29 +199,20 @@ imsg_add(struct buf *msg, void *data, u_int16_t datalen)
{
if (datalen)
if (buf_add(msg, data, datalen) == -1) {
- log_warnx("imsg_add: buf_add error");
buf_free(msg);
return (-1);
}
return (datalen);
}
-int
+void
imsg_close(struct imsgbuf *ibuf, struct buf *msg)
{
- int n;
struct imsg_hdr *hdr;
hdr = (struct imsg_hdr *)msg->buf;
hdr->len = (u_int16_t)msg->wpos;
- if ((n = buf_close(&ibuf->w, msg)) < 0) {
- log_warnx("imsg_close: buf_close error");
- buf_free(msg);
- return (-1);
- }
- imsg_event_add(ibuf);
-
- return (n);
+ buf_close(&ibuf->w, msg);
}
void
@@ -262,3 +236,19 @@ imsg_get_fd(struct imsgbuf *ibuf)
return (fd);
}
+
+int
+imsg_flush(struct imsgbuf *ibuf)
+{
+ while (ibuf->w.queued)
+ if (msgbuf_write(&ibuf->w) < 0)
+ return (-1);
+ return (0);
+}
+
+void
+imsg_clear(struct imsgbuf *ibuf)
+{
+ while (ibuf->w.queued)
+ msgbuf_clear(&ibuf->w);
+}