Deleted Added
full compact
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