1 /* $NetBSD: bthcid.c,v 1.5 2009/10/05 12:34:26 plunky 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.5 2009/10/05 12:34:26 plunky 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 const char *device; 66 int ch; 67 mode_t mode; 68 69 device = NULL; 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 device = optarg; 76 break; 77 78 case 'f': 79 detach = 0; 80 break; 81 82 case 'm': 83 mode = atoi(optarg); 84 break; 85 86 case 'n': 87 socket_name = NULL; 88 break; 89 90 case 's': 91 socket_name = optarg; 92 break; 93 94 case 'h': 95 default: 96 usage(); 97 /* NOT REACHED */ 98 } 99 } 100 101 if (getuid() != 0) 102 errx(EXIT_FAILURE, 103 "** ERROR: You should run %s as privileged user!", 104 getprogname()); 105 106 if (detach) 107 if (daemon(0, 0) < 0) 108 err(EXIT_FAILURE, "Could not daemon()ize"); 109 110 openlog(getprogname(), LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_DAEMON); 111 112 event_init(); 113 114 signal_set(&sigterm_ev, SIGTERM, process_signal, NULL); 115 if (signal_add(&sigterm_ev, NULL) < 0) { 116 syslog(LOG_ERR, "signal_add(sigterm_ev)"); 117 exit(EXIT_FAILURE); 118 } 119 120 signal_set(&sigint_ev, SIGINT, process_signal, NULL); 121 if (signal_add(&sigint_ev, NULL) < 0) { 122 syslog(LOG_ERR, "signal_add(sigint_ev)"); 123 exit(EXIT_FAILURE); 124 } 125 126 signal_set(&sighup_ev, SIGHUP, process_signal, NULL); 127 if (signal_add(&sighup_ev, NULL) < 0) { 128 syslog(LOG_ERR, "signal_add(sighup_ev)"); 129 exit(EXIT_FAILURE); 130 } 131 132 if (init_hci(device) < 0) { 133 syslog(LOG_ERR, "init_hci(%s)", device); 134 exit(EXIT_FAILURE); 135 } 136 137 if (init_control(socket_name, mode) < 0) { 138 syslog(LOG_ERR, "init_control(%s)", socket_name); 139 exit(EXIT_FAILURE); 140 } 141 142 if (detach && pidfile(NULL) < 0) { 143 syslog(LOG_ERR, "Could not create PID file: %m"); 144 exit(EXIT_FAILURE); 145 } 146 147 event_dispatch(); 148 149 /* NOTREACHED */ 150 /* gcc fodder */ 151 exit(EXIT_FAILURE); 152 } 153 154 static void 155 process_signal(int s, short e, void *arg) 156 { 157 158 syslog(LOG_DEBUG, "Exiting on signal %d", s); 159 160 if (socket_name) 161 unlink(socket_name); 162 163 closelog(); 164 exit(EXIT_FAILURE); 165 166 } 167 168 /* Display usage and exit */ 169 static void 170 usage(void) 171 { 172 173 fprintf(stderr, 174 "Usage: %s [-fhn] [-c config] [-d device] [-m mode] [-s path]\n" 175 "Where:\n" 176 "\t-c config specify config filename\n" 177 "\t-d device specify device address\n" 178 "\t-f run in foreground\n" 179 "\t-m mode specify socket permissions\n" 180 "\t-n do not listen for clients\n" 181 "\t-s path specify client socket pathname\n" 182 "\t-h display this message\n", 183 getprogname()); 184 185 exit(EXIT_FAILURE); 186 } 187