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