1 /* $NetBSD: bthcid.c,v 1.3 2007/01/25 20:33:41 plunky Exp $ */ 2 /* $DragonFly: src/usr.sbin/bthcid/bthcid.c,v 1.1 2008/01/30 14:10:19 hasso Exp $ */ 3 4 /*- 5 * Copyright (c) 2006 Itronix Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of Itronix Inc. may not be used to endorse 17 * or promote products derived from this software without specific 18 * prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #include <sys/param.h> 34 #include <sys/stat.h> 35 #include <bluetooth.h> 36 #include <err.h> 37 #include <errno.h> 38 #include <event.h> 39 #include <libutil.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <syslog.h> 43 #include <unistd.h> 44 45 #include "bthcid.h" 46 47 const char *socket_name = BTHCID_SOCKET_NAME; 48 int detach = 1; 49 50 static struct event sighup_ev; 51 static struct event sigint_ev; 52 static struct event sigterm_ev; 53 54 static void process_signal(int, short, void *); 55 static void usage(void); 56 57 int 58 main(int argc, char *argv[]) 59 { 60 bdaddr_t bdaddr; 61 int ch; 62 mode_t mode; 63 64 bdaddr_copy(&bdaddr, BDADDR_ANY); 65 mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; 66 67 while ((ch = getopt(argc, argv, "d:fm:ns:h")) != -1) { 68 switch (ch) { 69 case 'd': 70 if (!bt_devaddr(optarg, &bdaddr)) 71 err(EXIT_FAILURE, "%s", optarg); 72 break; 73 74 case 'f': 75 detach = 0; 76 break; 77 78 case 'm': 79 mode = atoi(optarg); 80 break; 81 82 case 'n': 83 socket_name = NULL; 84 break; 85 86 case 's': 87 socket_name = optarg; 88 break; 89 90 case 'h': 91 default: 92 usage(); 93 /* NOT REACHED */ 94 } 95 } 96 97 if (getuid() != 0) 98 errx(EXIT_FAILURE, 99 "** ERROR: You should run %s as privileged user!", 100 getprogname()); 101 102 if (detach) 103 if (daemon(0, 0) < 0) 104 err(EXIT_FAILURE, "Could not daemon()ize"); 105 106 openlog(getprogname(), LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_DAEMON); 107 108 event_init(); 109 110 signal_set(&sigterm_ev, SIGTERM, process_signal, NULL); 111 if (signal_add(&sigterm_ev, NULL) < 0) { 112 syslog(LOG_ERR, "signal_add(sigterm_ev)"); 113 exit(EXIT_FAILURE); 114 } 115 116 signal_set(&sigint_ev, SIGINT, process_signal, NULL); 117 if (signal_add(&sigint_ev, NULL) < 0) { 118 syslog(LOG_ERR, "signal_add(sigint_ev)"); 119 exit(EXIT_FAILURE); 120 } 121 122 signal_set(&sighup_ev, SIGHUP, process_signal, NULL); 123 if (signal_add(&sighup_ev, NULL) < 0) { 124 syslog(LOG_ERR, "signal_add(sighup_ev)"); 125 exit(EXIT_FAILURE); 126 } 127 128 if (init_hci(&bdaddr) < 0) { 129 syslog(LOG_ERR, "init_hci(%s)", bt_ntoa(&bdaddr, NULL)); 130 exit(EXIT_FAILURE); 131 } 132 133 if (init_control(socket_name, mode) < 0) { 134 syslog(LOG_ERR, "init_control(%s)", socket_name); 135 exit(EXIT_FAILURE); 136 } 137 138 if (detach && pidfile(NULL) < 0) { 139 syslog(LOG_ERR, "Could not create PID file: %m"); 140 exit(EXIT_FAILURE); 141 } 142 143 read_config_file(); 144 read_keys_file(); 145 146 event_dispatch(); 147 148 /* NOTREACHED */ 149 /* gcc fodder */ 150 exit(EXIT_FAILURE); 151 } 152 153 static void 154 process_signal(int s, short e __unused, void *arg __unused) 155 { 156 if (s == SIGHUP) { 157 syslog(LOG_DEBUG, "Got SIGHUP (%d). Dumping and rereading config", s); 158 dump_keys_file(); 159 read_config_file(); 160 read_keys_file(); 161 return; 162 } 163 164 165 166 syslog(LOG_DEBUG, "Exiting on signal %d", s); 167 168 if (socket_name) 169 unlink(socket_name); 170 171 clean_config(); 172 closelog(); 173 exit(EXIT_FAILURE); 174 175 } 176 177 /* Display usage and exit */ 178 static void 179 usage(void) 180 { 181 182 fprintf(stderr, 183 "Usage: %s [-fhn] [-c config] [-d devaddr] [-m mode] [-s path]\n" 184 "Where:\n" 185 "\t-c config specify config filename\n" 186 "\t-d device specify device address\n" 187 "\t-f run in foreground\n" 188 "\t-m mode specify socket permissions\n" 189 "\t-n do not listen for clients\n" 190 "\t-s path specify client socket pathname\n" 191 "\t-h display this message\n", 192 getprogname()); 193 194 exit(EXIT_FAILURE); 195 } 196