bthidd.c (156713) | bthidd.c (162128) |
---|---|
1/* 2 * bthidd.c | 1/* 2 * bthidd.c |
3 * 4 * Copyright (c) 2004 Maksim Yevmenkin <m_evmenkin@yahoo.com> | 3 */ 4 5/*- 6 * Copyright (c) 2006 Maksim Yevmenkin <m_evmenkin@yahoo.com> |
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 --- 7 unchanged lines hidden (view full) --- 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * | 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright --- 7 unchanged lines hidden (view full) --- 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * |
28 * $Id: bthidd.c,v 1.7 2004/11/17 21:59:42 max Exp $ 29 * $FreeBSD: head/usr.sbin/bluetooth/bthidd/bthidd.c 156713 2006-03-14 19:29:40Z emax $ | 30 * $Id: bthidd.c,v 1.8 2006/09/07 21:06:53 max Exp $ 31 * $FreeBSD: head/usr.sbin/bluetooth/bthidd/bthidd.c 162128 2006-09-07 21:47:49Z emax $ |
30 */ 31 32#include <sys/time.h> 33#include <sys/queue.h> 34#include <assert.h> 35#include <bluetooth.h> 36#include <err.h> 37#include <errno.h> 38#include <signal.h> 39#include <stdio.h> 40#include <stdlib.h> 41#include <string.h> 42#include <syslog.h> 43#include <unistd.h> 44#include <usbhid.h> | 32 */ 33 34#include <sys/time.h> 35#include <sys/queue.h> 36#include <assert.h> 37#include <bluetooth.h> 38#include <err.h> 39#include <errno.h> 40#include <signal.h> 41#include <stdio.h> 42#include <stdlib.h> 43#include <string.h> 44#include <syslog.h> 45#include <unistd.h> 46#include <usbhid.h> |
45#include "bthidd.h" | |
46#include "bthid_config.h" | 47#include "bthid_config.h" |
48#include "bthidd.h" |
|
47 | 49 |
48static int write_pid_file (char const *file); 49static int remove_pid_file (char const *file); 50static int elapsed (int tval); 51static void sighandler (int s); 52static void sighup (int s); | 50static int32_t write_pid_file (char const *file); 51static int32_t remove_pid_file (char const *file); 52static int32_t elapsed (int32_t tval); 53static void sighandler (int32_t s); |
53static void usage (void); 54 55/* 56 * bthidd 57 */ 58 | 54static void usage (void); 55 56/* 57 * bthidd 58 */ 59 |
59static int done = 0; /* are we done? */ 60static int reload = 0; /* reload config file */ | 60static int32_t done = 0; /* are we done? */ |
61 | 61 |
62int 63main(int argc, char *argv[]) | 62int32_t 63main(int32_t argc, char *argv[]) |
64{ 65 struct bthid_server srv; 66 struct sigaction sa; | 64{ 65 struct bthid_server srv; 66 struct sigaction sa; |
67 char const *pid_file = BTHIDD_PIDFILE, *ep = NULL; 68 int opt, detach, tval; | 67 char const *pid_file = BTHIDD_PIDFILE; 68 char *ep; 69 int32_t opt, detach, tval; |
69 70 memset(&srv, 0, sizeof(srv)); | 70 71 memset(&srv, 0, sizeof(srv)); |
71 memcpy(&srv.bdaddr, NG_HCI_BDADDR_ANY, sizeof(srv.bdaddr)); 72 srv.windex = -1; | 72 memset(&srv.bdaddr, 0, sizeof(srv.bdaddr)); |
73 detach = 1; 74 tval = 10; /* sec */ 75 | 73 detach = 1; 74 tval = 10; /* sec */ 75 |
76 while ((opt = getopt(argc, argv, "a:c:dH:hp:s:t:")) != -1) { | 76 while ((opt = getopt(argc, argv, "a:c:dH:hp:t:")) != -1) { |
77 switch (opt) { 78 case 'a': /* BDADDR */ 79 if (!bt_aton(optarg, &srv.bdaddr)) { | 77 switch (opt) { 78 case 'a': /* BDADDR */ 79 if (!bt_aton(optarg, &srv.bdaddr)) { |
80 struct hostent *he = NULL; | 80 struct hostent *he; |
81 82 if ((he = bt_gethostbyname(optarg)) == NULL) 83 errx(1, "%s: %s", optarg, hstrerror(h_errno)); 84 85 memcpy(&srv.bdaddr, he->h_addr, sizeof(srv.bdaddr)); 86 } 87 break; 88 --- 8 unchanged lines hidden (view full) --- 97 case 'H': /* hids file */ 98 hids_file = optarg; 99 break; 100 101 case 'p': /* pid file */ 102 pid_file = optarg; 103 break; 104 | 81 82 if ((he = bt_gethostbyname(optarg)) == NULL) 83 errx(1, "%s: %s", optarg, hstrerror(h_errno)); 84 85 memcpy(&srv.bdaddr, he->h_addr, sizeof(srv.bdaddr)); 86 } 87 break; 88 --- 8 unchanged lines hidden (view full) --- 97 case 'H': /* hids file */ 98 hids_file = optarg; 99 break; 100 101 case 'p': /* pid file */ 102 pid_file = optarg; 103 break; 104 |
105 case 's': /* switch script */ 106 srv.script = optarg; 107 break; 108 | |
109 case 't': /* rescan interval */ 110 tval = strtol(optarg, (char **) &ep, 10); 111 if (*ep != '\0' || tval <= 0) 112 usage(); 113 break; 114 | 105 case 't': /* rescan interval */ 106 tval = strtol(optarg, (char **) &ep, 10); 107 if (*ep != '\0' || tval <= 0) 108 usage(); 109 break; 110 |
115 case 'u': /* wired keyboard index */ 116 srv.windex = strtol(optarg, (char **) &ep, 10); 117 if (*ep != '\0' || srv.windex < 0) 118 usage(); 119 break; 120 | |
121 case 'h': 122 default: 123 usage(); 124 /* NOT REACHED */ 125 } 126 } 127 128 openlog(BTHIDD_IDENT, LOG_PID|LOG_PERROR|LOG_NDELAY, LOG_USER); --- 5 unchanged lines hidden (view full) --- 134 exit(1); 135 } 136 137 /* Install signal handler */ 138 memset(&sa, 0, sizeof(sa)); 139 sa.sa_handler = sighandler; 140 141 if (sigaction(SIGTERM, &sa, NULL) < 0 || | 111 case 'h': 112 default: 113 usage(); 114 /* NOT REACHED */ 115 } 116 } 117 118 openlog(BTHIDD_IDENT, LOG_PID|LOG_PERROR|LOG_NDELAY, LOG_USER); --- 5 unchanged lines hidden (view full) --- 124 exit(1); 125 } 126 127 /* Install signal handler */ 128 memset(&sa, 0, sizeof(sa)); 129 sa.sa_handler = sighandler; 130 131 if (sigaction(SIGTERM, &sa, NULL) < 0 || |
132 sigaction(SIGHUP, &sa, NULL) < 0 || |
|
142 sigaction(SIGINT, &sa, NULL) < 0) { 143 syslog(LOG_CRIT, "Could not install signal handlers. %s (%d)", 144 strerror(errno), errno); 145 exit(1); 146 } 147 | 133 sigaction(SIGINT, &sa, NULL) < 0) { 134 syslog(LOG_CRIT, "Could not install signal handlers. %s (%d)", 135 strerror(errno), errno); 136 exit(1); 137 } 138 |
148 sa.sa_handler = sighup; 149 if (sigaction(SIGHUP, &sa, NULL) < 0) { 150 syslog(LOG_CRIT, "Could not install signal handlers. %s (%d)", 151 strerror(errno), errno); 152 exit(1); 153 } 154 | |
155 sa.sa_handler = SIG_IGN; 156 if (sigaction(SIGPIPE, &sa, NULL) < 0) { 157 syslog(LOG_CRIT, "Could not install signal handlers. %s (%d)", 158 strerror(errno), errno); 159 exit(1); 160 } 161 162 sa.sa_handler = SIG_IGN; --- 9 unchanged lines hidden (view full) --- 172 exit(1); 173 174 for (done = 0; !done; ) { 175 if (elapsed(tval)) 176 client_rescan(&srv); 177 178 if (server_do(&srv) < 0) 179 break; | 139 sa.sa_handler = SIG_IGN; 140 if (sigaction(SIGPIPE, &sa, NULL) < 0) { 141 syslog(LOG_CRIT, "Could not install signal handlers. %s (%d)", 142 strerror(errno), errno); 143 exit(1); 144 } 145 146 sa.sa_handler = SIG_IGN; --- 9 unchanged lines hidden (view full) --- 156 exit(1); 157 158 for (done = 0; !done; ) { 159 if (elapsed(tval)) 160 client_rescan(&srv); 161 162 if (server_do(&srv) < 0) 163 break; |
180 181 if (reload) { 182 if (write_hids_file() < 0 || 183 read_config_file() < 0 || 184 read_hids_file() < 0) 185 break; 186 187 reload = 0; 188 } | |
189 } 190 191 server_shutdown(&srv); 192 remove_pid_file(pid_file); 193 clean_config(); 194 closelog(); 195 196 return (0); 197} 198 199/* 200 * Write pid file 201 */ 202 | 164 } 165 166 server_shutdown(&srv); 167 remove_pid_file(pid_file); 168 clean_config(); 169 closelog(); 170 171 return (0); 172} 173 174/* 175 * Write pid file 176 */ 177 |
203static int | 178static int32_t |
204write_pid_file(char const *file) 205{ | 179write_pid_file(char const *file) 180{ |
206 FILE *pid = NULL; | 181 FILE *pid; |
207 208 assert(file != NULL); 209 210 if ((pid = fopen(file, "w")) == NULL) { 211 syslog(LOG_ERR, "Could not open file %s. %s (%d)", 212 file, strerror(errno), errno); 213 return (-1); 214 } 215 216 fprintf(pid, "%d", getpid()); 217 fclose(pid); 218 219 return (0); 220} 221 222/* 223 * Remote pid file 224 */ 225 | 182 183 assert(file != NULL); 184 185 if ((pid = fopen(file, "w")) == NULL) { 186 syslog(LOG_ERR, "Could not open file %s. %s (%d)", 187 file, strerror(errno), errno); 188 return (-1); 189 } 190 191 fprintf(pid, "%d", getpid()); 192 fclose(pid); 193 194 return (0); 195} 196 197/* 198 * Remote pid file 199 */ 200 |
226static int | 201static int32_t |
227remove_pid_file(char const *file) 228{ 229 assert(file != NULL); 230 231 if (unlink(file) < 0) { 232 syslog(LOG_ERR, "Could not unlink file %s. %s (%d)", 233 file, strerror(errno), errno); 234 return (-1); 235 } 236 237 return (0); 238} 239 240/* 241 * Returns true if desired time interval has elapsed 242 */ 243 | 202remove_pid_file(char const *file) 203{ 204 assert(file != NULL); 205 206 if (unlink(file) < 0) { 207 syslog(LOG_ERR, "Could not unlink file %s. %s (%d)", 208 file, strerror(errno), errno); 209 return (-1); 210 } 211 212 return (0); 213} 214 215/* 216 * Returns true if desired time interval has elapsed 217 */ 218 |
244static int 245elapsed(int tval) | 219static int32_t 220elapsed(int32_t tval) |
246{ | 221{ |
247 static struct timeval last = { 0, }; | 222 static struct timeval last = { 0, 0 }; |
248 struct timeval now; 249 250 gettimeofday(&now, NULL); 251 252 if (now.tv_sec - last.tv_sec >= tval) { 253 last = now; 254 return (1); 255 } 256 257 return (0); 258} 259 260/* | 223 struct timeval now; 224 225 gettimeofday(&now, NULL); 226 227 if (now.tv_sec - last.tv_sec >= tval) { 228 last = now; 229 return (1); 230 } 231 232 return (0); 233} 234 235/* |
261 * Signal handlers | 236 * Signal handler |
262 */ 263 264static void | 237 */ 238 239static void |
265sighandler(int s) | 240sighandler(int32_t s) |
266{ 267 syslog(LOG_NOTICE, "Got signal %d, total number of signals %d", 268 s, ++ done); 269} 270 | 241{ 242 syslog(LOG_NOTICE, "Got signal %d, total number of signals %d", 243 s, ++ done); 244} 245 |
271static void 272sighup(int s) 273{ 274 syslog(LOG_NOTICE, "Got SIGHUP: reload config"); 275 reload = 1; 276} 277 | |
278/* 279 * Display usage and exit 280 */ 281 282static void 283usage(void) 284{ 285 fprintf(stderr, 286"Usage: %s [options]\n" \ 287"Where options are:\n" \ 288" -a address specify address to listen on (default ANY)\n" \ 289" -c file specify config file name\n" \ 290" -d run in foreground\n" \ 291" -H file specify known HIDs file name\n" \ 292" -h display this message\n" \ 293" -p file specify PID file name\n" \ | 246/* 247 * Display usage and exit 248 */ 249 250static void 251usage(void) 252{ 253 fprintf(stderr, 254"Usage: %s [options]\n" \ 255"Where options are:\n" \ 256" -a address specify address to listen on (default ANY)\n" \ 257" -c file specify config file name\n" \ 258" -d run in foreground\n" \ 259" -H file specify known HIDs file name\n" \ 260" -h display this message\n" \ 261" -p file specify PID file name\n" \ |
294" -s script specify keyboard switching script\n" \ | |
295" -t tval specify client rescan interval (sec)\n" \ | 262" -t tval specify client rescan interval (sec)\n" \ |
296" -u unit specify wired keyboard unit\n" \ | |
297"", BTHIDD_IDENT); 298 exit(255); 299} 300 | 263"", BTHIDD_IDENT); 264 exit(255); 265} 266 |