summaryrefslogtreecommitdiff
path: root/usr.sbin/btd/btd.c
diff options
context:
space:
mode:
authorUwe Stuehler <uwe@cvs.openbsd.org>2008-11-26 06:51:44 +0000
committerUwe Stuehler <uwe@cvs.openbsd.org>2008-11-26 06:51:44 +0000
commit82a67aa5c79659c28ace847e9d1ddbf8485e1a0c (patch)
tree76ae7602af14363a78a597b2f90a6d2b1f8cbd65 /usr.sbin/btd/btd.c
parent9dc81ca0a6153a852c7e65abefc7cc4718473541 (diff)
Implement config reloading (still only work in progress)
Diffstat (limited to 'usr.sbin/btd/btd.c')
-rw-r--r--usr.sbin/btd/btd.c239
1 files changed, 163 insertions, 76 deletions
diff --git a/usr.sbin/btd/btd.c b/usr.sbin/btd/btd.c
index f2c04fec282..8957280e9b7 100644
--- a/usr.sbin/btd/btd.c
+++ b/usr.sbin/btd/btd.c
@@ -1,4 +1,22 @@
-/* $OpenBSD: btd.c,v 1.1 2008/11/24 23:34:42 uwe Exp $ */
+/* $OpenBSD: btd.c,v 1.2 2008/11/26 06:51:43 uwe Exp $ */
+
+/*
+ * Copyright (c) 2008 Uwe Stuehler <uwe@openbsd.org>
+ * Copyright (c) 2003 Can Erkin Acar
+ * Copyright (c) 2003 Anil Madhavapeddy <anil@recoil.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
#include <sys/ioctl.h>
#include <sys/wait.h>
@@ -7,9 +25,9 @@
#include <err.h>
#include <errno.h>
-#include <event.h>
#include <fcntl.h>
#include <libgen.h>
+#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -18,27 +36,23 @@
#include "btd.h"
-void sighdlr(int, short, void *);
-__dead void usage(void);
-int check_child(pid_t, const char *);
+static void sighdlr(int);
+static __dead void usage(void);
+static int check_child(pid_t, const char *);
+static int btd_read(void *, size_t);
+static int btd_write(const void *, size_t);
+static int dispatch_imsg(struct btd *);
+static void btd_open_hci(struct btd *);
+static void btd_set_link_policy(struct btd *);
static const char *progname;
-static int quit = 0;
-static int reconfig = 0;
-static int sigchld = 0;
-
-static struct event ev_sigchld;
-static struct event ev_sighup;
-static struct event ev_sigint;
-static struct event ev_sigterm;
-static struct bufferevent *ev_bt;
-
-static void readcb(struct bufferevent *, void *);
-static void writecb(struct bufferevent *, void *);
-static void errorcb(struct bufferevent *, short, void *);
-
-void
-sighdlr(int sig, short what, void *arg)
+static volatile sig_atomic_t quit = 0;
+static volatile sig_atomic_t reconfig = 0;
+static volatile sig_atomic_t sigchld = 0;
+static int pipe_fd;
+
+static void
+sighdlr(int sig)
{
switch (sig) {
case SIGTERM:
@@ -54,7 +68,7 @@ sighdlr(int sig, short what, void *arg)
}
}
-__dead void
+static __dead void
usage(void)
{
fprintf(stderr, "usage: %s [-d]\n", progname);
@@ -68,6 +82,7 @@ main(int argc, char *argv[])
pid_t chld_pid, pid;
int pipe_chld[2];
struct passwd *pw;
+ struct pollfd pfd;
int ch;
progname = basename(argv[0]);
@@ -115,29 +130,30 @@ main(int argc, char *argv[])
setproctitle("[priv]");
- /* only after daemon() */
- event_init();
-
- signal_set(&ev_sigchld, SIGCHLD, sighdlr, &env);
- signal_set(&ev_sighup, SIGHUP, sighdlr, &env);
- signal_set(&ev_sigint, SIGINT, sighdlr, &env);
- signal_set(&ev_sigterm, SIGTERM, sighdlr, &env);
- signal_add(&ev_sigchld, NULL);
- signal_add(&ev_sighup, NULL);
- signal_add(&ev_sigint, NULL);
- signal_add(&ev_sigterm, NULL);
+ signal(SIGCHLD, sighdlr);
+ signal(SIGTERM, sighdlr);
+ signal(SIGINT, sighdlr);
+ signal(SIGHUP, sighdlr);
close(pipe_chld[1]);
+ pipe_fd = pipe_chld[0];
- if ((ev_bt = bufferevent_new(pipe_chld[0], readcb,
- writecb, errorcb, &env)) == NULL)
- fatalx("bufferevent_new ev_bt");
+ while (quit == 0) {
+ int nfds;
- bufferevent_enable(ev_bt, EV_READ);
+ pfd.fd = pipe_fd;
+ pfd.events = POLLIN;
- while (quit == 0) {
- if (!event_loop(EVLOOP_ONCE))
- quit = 1;
+ if ((nfds = poll(&pfd, 1, 0)) == -1)
+ if (errno != EINTR) {
+ log_warn("poll error");
+ quit = 1;
+ }
+
+
+ if (pfd.revents & POLLIN)
+ if (dispatch_imsg(&env) == -1)
+ quit = 1;
if (sigchld) {
if (check_child(chld_pid, "child")) {
@@ -146,9 +162,10 @@ main(int argc, char *argv[])
}
sigchld = 0;
}
+
}
- signal_del(&ev_sigchld);
+ signal(SIGCHLD, SIG_DFL);
if (chld_pid)
kill(chld_pid, SIGTERM);
@@ -187,57 +204,127 @@ check_child(pid_t pid, const char *pname)
return (0);
}
-static void
-readcb(struct bufferevent *ev, void *arg)
+static int
+btd_read(void *buf, size_t n)
{
- log_warnx("readcb");
+ if (atomic_read(pipe_fd, buf, n) < 0) {
+ close(pipe_fd);
+ pipe_fd = -1;
+ quit = 1;
+ return -1;
+ }
+
+ return 0;
}
-static void
-writecb(struct bufferevent *ev, void *arg)
+static int
+btd_write(const void *buf, size_t n)
+{
+ if (atomic_write(pipe_fd, buf, n) < 0) {
+ close(pipe_fd);
+ pipe_fd = -1;
+ quit = 1;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+dispatch_imsg(struct btd *env)
{
- /* nothing to do here */
- log_warnx("writecb");
+ enum imsg_type type;
+
+ if (btd_read(&type, sizeof(type)) < 0) {
+ log_warnx("btd_read");
+ return -1;
+ }
+
+ switch (type) {
+ case IMSG_OPEN_HCI:
+ btd_open_hci(env);
+ break;
+ case IMSG_SET_LINK_POLICY:
+ btd_set_link_policy(env);
+ break;
+ default:
+ log_warnx("invalid message, type=%#x", type);
+ return -1;
+ }
+
+ return 0;
}
static void
-errorcb(struct bufferevent *ev, short what, void *arg)
+btd_open_hci(struct btd *env)
{
- log_warnx("Pipe error");
- quit = 1;
+ struct sockaddr_bt sa;
+ bdaddr_t addr;
+ int fd;
+ int err = 0;
+
+ if (btd_read(&addr, sizeof(addr)) < 0)
+ return;
+
+ if ((fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) == -1) {
+ err = errno;
+ btd_write(&err, sizeof(err));
+ return;
+ }
+
+ bzero(&sa, sizeof(sa));
+ sa.bt_len = sizeof(sa);
+ sa.bt_family = AF_BLUETOOTH;
+ bdaddr_copy(&sa.bt_bdaddr, &addr);
+
+ if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0 ||
+ connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
+ err = errno;
+ close(fd);
+ fd = -1;
+ }
+
+ send_fd(pipe_fd, fd);
+
+ (void)btd_write(&err, sizeof(err));
+
+ if (fd != -1)
+ close(fd);
}
-#ifdef notyet
-void
-btd_devctl(struct imsg *imsg)
+static void
+btd_set_link_policy(struct btd *env)
{
- struct btdev_attach_args baa;
- char buf[sizeof(int) + sizeof(bdaddr_t)];
- unsigned long cmd;
- int res;
+ struct btreq btr;
+ bdaddr_t addr;
+ uint16_t link_policy;
+ int err = 0;
int fd;
- if (devinfo_load_attach_args(&baa, imsg->data,
- imsg->hdr.len - IMSG_HEADER_SIZE))
- fatalx("invalid IMSG_ATTACH/DETACH received");
+ if (btd_read(&addr, sizeof(addr)) < 0 ||
+ btd_read(&link_policy, sizeof(link_policy)) < 0)
+ return;
+
+ if ((fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) == -1) {
+ err = errno;
+ btd_write(&err, sizeof(err));
+ return;
+ }
+
+ bdaddr_copy(&btr.btr_bdaddr, &addr);
- if ((fd = open(BTHUB_PATH, O_WRONLY, 0)) == -1) {
- res = errno;
- log_warn("can't open %s", BTHUB_PATH);
- goto ret;
+ if (ioctl(fd, SIOCGBTINFOA, &btr) < 0) {
+ err = errno;
+ close(fd);
+ btd_write(&err, sizeof(err));
+ return;
}
- cmd = imsg->hdr.type == IMSG_ATTACH ? BTDEV_ATTACH : BTDEV_DETACH;
- if (ioctl(fd, cmd, &baa) == -1)
- res = errno;
+ btr.btr_link_policy = link_policy;
- res = 0;
- (void)close(fd);
-ret:
- devinfo_unload_attach_args(&baa);
+ if (ioctl(fd, SIOCSBTPOLICY, &btr) < 0)
+ err = errno;
- memcpy(buf, &res, sizeof(res));
- memcpy((int *)buf + 1, &baa.bd_raddr, sizeof(bdaddr_t));
- /* send reply */
+ btd_write(&err, sizeof(err));
+ close(fd);
}
-#endif