Fix build break for rpm
[framework/connectivity/bluez.git] / compat / pand.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
6  *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
7  *
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #define _GNU_SOURCE
30 #include <stdio.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <syslog.h>
37 #include <signal.h>
38 #include <getopt.h>
39 #include <sys/poll.h>
40 #include <sys/stat.h>
41 #include <sys/types.h>
42 #include <sys/socket.h>
43
44 #include <bluetooth/bluetooth.h>
45 #include <bluetooth/hci.h>
46 #include <bluetooth/hci_lib.h>
47 #include <bluetooth/l2cap.h>
48 #include <bluetooth/bnep.h>
49 #include <bluetooth/hidp.h>
50
51 #include "sdp.h"
52 #include "pand.h"
53
54 #ifdef NEED_PPOLL
55 #include "ppoll.h"
56 #endif
57
58 static uint16_t role    = BNEP_SVC_PANU;        /* Local role (ie service) */
59 static uint16_t service = BNEP_SVC_NAP;         /* Remote service */
60
61 static int detach = 1;
62 static int persist;
63 static int use_sdp = 1;
64 static int use_cache;
65 static int link_mode = 0;
66 static int cleanup;
67 static int search_duration = 10;
68
69 static struct {
70         int      valid;
71         char     dst[40];
72         bdaddr_t bdaddr;
73 } cache;
74
75 static char netdev[16] = "bnep%d";
76 static char *pidfile = NULL;
77 static char *devupcmd = NULL;
78 static char *devdowncmd = NULL;
79
80 static bdaddr_t src_addr = *BDADDR_ANY;
81 static int src_dev = -1;
82
83 static volatile int terminate;
84
85 static void do_kill(char *dst);
86
87 enum {
88         NONE,
89         SHOW,
90         LISTEN,
91         CONNECT,
92         KILL
93 } modes;
94
95 struct script_arg {
96         char    dev[20];
97         char    dst[20];
98         int     sk;
99         int     nsk;
100 };
101
102 static void run_script(char *script, char *dev, char *dst, int sk, int nsk)
103 {
104         char *argv[4];
105         struct sigaction sa;
106
107         if (!script)
108                 return;
109
110         if (access(script, R_OK | X_OK))
111                 return;
112
113         if (fork())
114                 return;
115
116         if (sk >= 0)
117                 close(sk);
118
119         if (nsk >= 0)
120                 close(nsk);
121
122         memset(&sa, 0, sizeof(sa));
123         sa.sa_handler = SIG_DFL;
124         sigaction(SIGCHLD, &sa, NULL);
125         sigaction(SIGPIPE, &sa, NULL);
126
127         argv[0] = script;
128         argv[1] = dev;
129         argv[2] = dst;
130         argv[3] = NULL;
131
132         execv(script, argv);
133
134         exit(1);
135 }
136
137 /* Wait for disconnect or error condition on the socket */
138 static int w4_hup(int sk, struct script_arg *down_cmd)
139 {
140         struct pollfd pf;
141         sigset_t sigs;
142         int n;
143
144         sigfillset(&sigs);
145         sigdelset(&sigs, SIGCHLD);
146         sigdelset(&sigs, SIGPIPE);
147         sigdelset(&sigs, SIGTERM);
148         sigdelset(&sigs, SIGINT);
149         sigdelset(&sigs, SIGHUP);
150
151         while (!terminate) {
152                 pf.fd = sk;
153                 pf.events = POLLERR | POLLHUP;
154
155                 n = ppoll(&pf, 1, NULL, &sigs);
156
157                 if (n < 0) {
158                         if (errno == EINTR || errno == EAGAIN)
159                                 continue;
160
161                         syslog(LOG_ERR, "Poll failed. %s(%d)",
162                                                 strerror(errno), errno);
163
164                         return 1;
165                 }
166
167                 if (n) {
168                         int err = 0;
169                         socklen_t olen = sizeof(err);
170
171                         getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, &olen);
172
173                         syslog(LOG_INFO, "%s disconnected%s%s", netdev,
174                                 err ? " : " : "", err ? strerror(err) : "");
175
176                         if (down_cmd)
177                                 run_script(devdowncmd,
178                                                 down_cmd->dev, down_cmd->dst,
179                                                 down_cmd->sk, down_cmd->nsk);
180
181                         close(sk);
182
183                         return 0;
184                 }
185         }
186
187         return 0;
188 }
189
190 static int do_listen(void)
191 {
192         struct l2cap_options l2o;
193         struct sockaddr_l2 l2a;
194         socklen_t olen;
195         int sk, lm;
196
197         if (use_sdp)
198                 bnep_sdp_register(&src_addr, role);
199
200         /* Create L2CAP socket and bind it to PSM BNEP */
201         sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
202         if (sk < 0) {
203                 syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)",
204                                                 strerror(errno), errno);
205                 return -1;
206         }
207
208         memset(&l2a, 0, sizeof(l2a));
209         l2a.l2_family = AF_BLUETOOTH;
210         bacpy(&l2a.l2_bdaddr, &src_addr);
211         l2a.l2_psm = htobs(BNEP_PSM);
212
213         if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) {
214                 syslog(LOG_ERR, "Bind failed. %s(%d)",
215                                                 strerror(errno), errno);
216                 return -1;
217         }
218
219         /* Setup L2CAP options according to BNEP spec */
220         memset(&l2o, 0, sizeof(l2o));
221         olen = sizeof(l2o);
222         if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen) < 0) {
223                 syslog(LOG_ERR, "Failed to get L2CAP options. %s(%d)",
224                                                 strerror(errno), errno);
225                 return -1;
226         }
227
228         l2o.imtu = l2o.omtu = BNEP_MTU;
229         if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0) {
230                 syslog(LOG_ERR, "Failed to set L2CAP options. %s(%d)",
231                                                 strerror(errno), errno);
232                 return -1;
233         }
234
235         /* Set link mode */
236         lm = link_mode;
237         if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) {
238                 syslog(LOG_ERR, "Failed to set link mode. %s(%d)",
239                                                 strerror(errno), errno);
240                 return -1;
241         }
242
243         listen(sk, 10);
244
245         while (!terminate) {
246                 socklen_t alen = sizeof(l2a);
247                 char devname[16];
248                 int nsk;
249
250                 nsk = accept(sk, (struct sockaddr *) &l2a, &alen);
251                 if (nsk < 0) {
252                         syslog(LOG_ERR, "Accept failed. %s(%d)",
253                                                 strerror(errno), errno);
254                         continue;
255                 }
256
257                 switch (fork()) {
258                 case 0:
259                         break;
260                 case -1:
261                         syslog(LOG_ERR, "Fork failed. %s(%d)",
262                                                 strerror(errno), errno);
263                 default:
264                         close(nsk);
265                         continue;
266                 }
267
268                 strncpy(devname, netdev, 16);
269                 devname[15] = '\0';
270
271                 if (!bnep_accept_connection(nsk, role, devname)) {
272                         char str[40];
273                         struct script_arg down_cmd;
274
275                         ba2str(&l2a.l2_bdaddr, str);
276
277                         syslog(LOG_INFO, "New connection from %s at %s",
278                                                                 str, devname);
279
280                         run_script(devupcmd, devname, str, sk, nsk);
281
282                         memset(&down_cmd, 0, sizeof(struct script_arg));
283                         strncpy(down_cmd.dev, devname, strlen(devname) + 1);
284                         strncpy(down_cmd.dst, str, strlen(str) + 1);
285                         down_cmd.sk = sk;
286                         down_cmd.nsk = nsk;
287                         w4_hup(nsk, &down_cmd);
288                 } else {
289                         syslog(LOG_ERR, "Connection failed. %s(%d)",
290                                                 strerror(errno), errno);
291                 }
292
293                 close(nsk);
294                 exit(0);
295         }
296
297         if (use_sdp)
298                 bnep_sdp_unregister();
299
300         return 0;
301 }
302
303 /* Connect and initiate BNEP session
304  * Returns:
305  *   -1 - critical error (exit persist mode)
306  *   1  - non critical error
307  *   0  - success
308  */
309 static int create_connection(char *dst, bdaddr_t *bdaddr)
310 {
311         struct l2cap_options l2o;
312         struct sockaddr_l2 l2a;
313         socklen_t olen;
314         int sk, r = 0;
315         struct script_arg down_cmd;
316
317         syslog(LOG_INFO, "Connecting to %s", dst);
318
319         sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
320         if (sk < 0) {
321                 syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)",
322                                                 strerror(errno), errno);
323                 return -1;
324         }
325
326         /* Setup L2CAP options according to BNEP spec */
327         memset(&l2o, 0, sizeof(l2o));
328         olen = sizeof(l2o);
329         getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen);
330         l2o.imtu = l2o.omtu = BNEP_MTU;
331         setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o));
332
333         memset(&l2a, 0, sizeof(l2a));
334         l2a.l2_family = AF_BLUETOOTH;
335         bacpy(&l2a.l2_bdaddr, &src_addr);
336
337         if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a)))
338                 syslog(LOG_ERR, "Bind failed. %s(%d)",
339                                                 strerror(errno), errno);
340
341         memset(&l2a, 0, sizeof(l2a));
342         l2a.l2_family = AF_BLUETOOTH;
343         bacpy(&l2a.l2_bdaddr, bdaddr);
344         l2a.l2_psm = htobs(BNEP_PSM);
345
346         if (!connect(sk, (struct sockaddr *) &l2a, sizeof(l2a)) &&
347                         !bnep_create_connection(sk, role, service, netdev)) {
348
349                 syslog(LOG_INFO, "%s connected", netdev);
350
351                 run_script(devupcmd, netdev, dst, sk, -1);
352
353                 if (persist || devdowncmd) {
354                                 memset(&down_cmd, 0, sizeof(struct script_arg));
355                                 strncpy(down_cmd.dev, netdev, strlen(netdev) + 1);
356                                 strncpy(down_cmd.dst, dst, strlen(dst) + 1);
357                                 down_cmd.sk = sk;
358                                 down_cmd.nsk = -1;
359                                 w4_hup(sk, &down_cmd);
360
361                         if (terminate && cleanup) {
362                                 syslog(LOG_INFO, "Disconnecting from %s.", dst);
363                                 do_kill(dst);
364                         }
365                 }
366
367                 r = 0;
368         } else {
369                 syslog(LOG_ERR, "Connect to %s failed. %s(%d)",
370                                                 dst, strerror(errno), errno);
371                 r = 1;
372         }
373
374         close(sk);
375
376         if (use_cache) {
377                 if (!r) {
378                         /* Succesesful connection, validate cache */
379                         strcpy(cache.dst, dst);
380                         bacpy(&cache.bdaddr, bdaddr);
381                         cache.valid = use_cache;
382                 } else
383                         cache.valid--;
384         }
385
386         return r;
387 }
388
389 /* Search and connect
390  * Returns:
391  *   -1 - critical error (exit persist mode)
392  *   1  - non critical error
393  *   0  - success
394  */
395 static int do_connect(void)
396 {
397         inquiry_info *ii;
398         int reconnect = 0;
399         int i, n, r = 0;
400
401         do {
402                 if (reconnect)
403                         sleep(persist);
404                 reconnect = 1;
405
406                 if (cache.valid > 0) {
407                         /* Use cached bdaddr */
408                         r = create_connection(cache.dst, &cache.bdaddr);
409                         if (r < 0) {
410                                 terminate = 1;
411                                 break;
412                         }
413                         continue;
414                 }
415
416                 syslog(LOG_INFO, "Inquiring");
417
418                 /* FIXME: Should we use non general LAP here ? */
419
420                 ii = NULL;
421                 n  = hci_inquiry(src_dev, search_duration, 0, NULL, &ii, 0);
422                 if (n < 0) {
423                         syslog(LOG_ERR, "Inquiry failed. %s(%d)",
424                                                 strerror(errno), errno);
425                         continue;
426                 }
427
428                 for (i = 0; i < n; i++) {
429                         char dst[40];
430                         ba2str(&ii[i].bdaddr, dst);
431
432                         if (use_sdp) {
433                                 syslog(LOG_INFO, "Searching for %s on %s",
434                                                 bnep_svc2str(service), dst);
435
436                                 if (bnep_sdp_search(&src_addr, &ii[i].bdaddr, service) <= 0)
437                                         continue;
438                         }
439
440                         r = create_connection(dst, &ii[i].bdaddr);
441                         if (r < 0) {
442                                 terminate = 1;
443                                 break;
444                         }
445                 }
446                 bt_free(ii);
447         } while (!terminate && persist);
448
449         return r;
450 }
451
452 static void do_show(void)
453 {
454         bnep_show_connections();
455 }
456
457 static void do_kill(char *dst)
458 {
459         if (dst) {
460                 bdaddr_t *ba = strtoba(dst);
461                 bnep_kill_connection((void *) ba);
462                 free(ba);
463         } else {
464                 bnep_kill_all_connections();
465         }
466 }
467
468 static void sig_hup(int sig)
469 {
470         return;
471 }
472
473 static void sig_term(int sig)
474 {
475         terminate = 1;
476 }
477
478 static int write_pidfile(void)
479 {
480         int fd;
481         FILE *f;
482         pid_t pid;
483
484         do {
485                 fd = open(pidfile, O_WRONLY|O_TRUNC|O_CREAT|O_EXCL, 0644);
486                 if (fd == -1) {
487                         /* Try to open the file for read. */
488                         fd = open(pidfile, O_RDONLY);
489                         if (fd < 0) {
490                                 syslog(LOG_ERR, "Could not read old pidfile: %s(%d)",
491                                                         strerror(errno), errno);
492                                 return -1;
493                         }
494
495                         /* We're already running; send a SIGHUP (we presume that they
496                          * are calling ifup for a reason, so they probably want to
497                          * rescan) and then exit cleanly and let things go on in the
498                          * background.  Muck with the filename so that we don't go
499                          * deleting the pid file for the already-running instance.
500                          */
501                         f = fdopen(fd, "r");
502                         if (!f) {
503                                 syslog(LOG_ERR, "Could not fdopen old pidfile: %s(%d)",
504                                                         strerror(errno), errno);
505                                 close(fd);
506                                 return -1;
507                         }
508
509                         pid = 0;
510                         if (fscanf(f, "%d", &pid) != 1)
511                                 pid = 0;
512                         fclose(f);
513
514                         if (pid) {
515                                 /* Try to kill it. */
516                                 if (kill(pid, SIGHUP) == -1) {
517                                         /* No such pid; remove the bogus pid file. */
518                                         syslog(LOG_INFO, "Removing stale pidfile");
519                                         unlink(pidfile);
520                                         fd = -1;
521                                 } else {
522                                         /* Got it.  Don't mess with the pid file on
523                                          * our way out. */
524                                         syslog(LOG_INFO, "Signalling existing process %d and exiting\n", pid);
525                                         pidfile = NULL;
526                                         return -1;
527                                 }
528                         }
529                 }
530         } while(fd == -1);
531
532         f = fdopen(fd, "w");
533         if (!f) {
534                 syslog(LOG_ERR, "Could not fdopen new pidfile: %s(%d)",
535                                                 strerror(errno), errno);
536                 close(fd);
537                 unlink(pidfile);
538                 return -1;
539         }
540
541         fprintf(f, "%d\n", getpid());
542         fclose(f);
543
544         return 0;
545 }
546
547 static struct option main_lopts[] = {
548         { "help",     0, 0, 'h' },
549         { "listen",   0, 0, 's' },
550         { "connect",  1, 0, 'c' },
551         { "search",   2, 0, 'Q' },
552         { "kill",     1, 0, 'k' },
553         { "killall",  0, 0, 'K' },
554         { "role",     1, 0, 'r' },
555         { "service",  1, 0, 'd' },
556         { "ethernet", 1, 0, 'e' },
557         { "device",   1, 0, 'i' },
558         { "nosdp",    0, 0, 'D' },
559         { "list",     0, 0, 'l' },
560         { "show",     0, 0, 'l' },
561         { "nodetach", 0, 0, 'n' },
562         { "persist",  2, 0, 'p' },
563         { "auth",     0, 0, 'A' },
564         { "encrypt",  0, 0, 'E' },
565         { "secure",   0, 0, 'S' },
566         { "master",   0, 0, 'M' },
567         { "cache",    0, 0, 'C' },
568         { "pidfile",  1, 0, 'P' },
569         { "devup",    1, 0, 'u' },
570         { "devdown",  1, 0, 'o' },
571         { "autozap",  0, 0, 'z' },
572         { 0, 0, 0, 0 }
573 };
574
575 static const char *main_sopts = "hsc:k:Kr:d:e:i:lnp::DQ::AESMC::P:u:o:z";
576
577 static const char *main_help =
578         "Bluetooth PAN daemon version %s\n"
579         "Usage:\n"
580         "\tpand <options>\n"
581         "Options:\n"
582         "\t--show --list -l          Show active PAN connections\n"
583         "\t--listen -s               Listen for PAN connections\n"
584         "\t--connect -c <bdaddr>     Create PAN connection\n"
585         "\t--autozap -z              Disconnect automatically on exit\n"
586         "\t--search -Q[duration]     Search and connect\n"
587         "\t--kill -k <bdaddr>        Kill PAN connection\n"
588         "\t--killall -K              Kill all PAN connections\n"
589         "\t--role -r <role>          Local PAN role (PANU, NAP, GN)\n"
590         "\t--service -d <role>       Remote PAN service (PANU, NAP, GN)\n"
591         "\t--ethernet -e <name>      Network interface name\n"
592         "\t--device -i <bdaddr>      Source bdaddr\n"
593         "\t--nosdp -D                Disable SDP\n"
594         "\t--auth -A                 Enable authentication\n"
595         "\t--encrypt -E              Enable encryption\n"
596         "\t--secure -S               Secure connection\n"
597         "\t--master -M               Become the master of a piconet\n"
598         "\t--nodetach -n             Do not become a daemon\n"
599         "\t--persist -p[interval]    Persist mode\n"
600         "\t--cache -C[valid]         Cache addresses\n"
601         "\t--pidfile -P <pidfile>    Create PID file\n"
602         "\t--devup -u <script>       Script to run when interface comes up\n"
603         "\t--devdown -o <script>     Script to run when interface comes down\n";
604
605 int main(int argc, char *argv[])
606 {
607         char *dst = NULL, *src = NULL;
608         struct sigaction sa;
609         int mode = NONE;
610         int opt;
611
612         while ((opt=getopt_long(argc, argv, main_sopts, main_lopts, NULL)) != -1) {
613                 switch(opt) {
614                 case 'l':
615                         mode = SHOW;
616                         detach = 0;
617                         break;
618
619                 case 's':
620                         mode = LISTEN;
621                         break;
622
623                 case 'c':
624                         mode = CONNECT;
625                         dst  = strdup(optarg);
626                         break;
627
628                 case 'Q':
629                         mode = CONNECT;
630                         if (optarg)
631                                 search_duration = atoi(optarg);
632                         break;
633
634                 case 'k':
635                         mode = KILL;
636                         detach = 0;
637                         dst  = strdup(optarg);
638                         break;
639
640                 case 'K':
641                         mode = KILL;
642                         detach = 0;
643                         break;
644
645                 case 'i':
646                         src = strdup(optarg);
647                         break;
648
649                 case 'r':
650                         bnep_str2svc(optarg, &role);
651                         break;
652
653                 case 'd':
654                         bnep_str2svc(optarg, &service);
655                         break;
656
657                 case 'D':
658                         use_sdp = 0;
659                         break;
660
661                 case 'A':
662                         link_mode |= L2CAP_LM_AUTH;
663                         break;
664
665                 case 'E':
666                         link_mode |= L2CAP_LM_ENCRYPT;
667                         break;
668
669                 case 'S':
670                         link_mode |= L2CAP_LM_SECURE;
671                         break;
672
673                 case 'M':
674                         link_mode |= L2CAP_LM_MASTER;
675                         break;
676
677                 case 'e':
678                         strncpy(netdev, optarg, 16);
679                         netdev[15] = '\0';
680                         break;
681
682                 case 'n':
683                         detach = 0;
684                         break;
685
686                 case 'p':
687                         if (optarg)
688                                 persist = atoi(optarg);
689                         else
690                                 persist = 5;
691                         break;
692
693                 case 'C':
694                         if (optarg)
695                                 use_cache = atoi(optarg);
696                         else
697                                 use_cache = 2;
698                         break;
699
700                 case 'P':
701                         pidfile = strdup(optarg);
702                         break;
703
704                 case 'u':
705                         devupcmd = strdup(optarg);
706                         break;
707
708                 case 'o':
709                         devdowncmd = strdup(optarg);
710                         break;
711
712                 case 'z':
713                         cleanup = 1;
714                         break;
715
716                 case 'h':
717                 default:
718                         printf(main_help, VERSION);
719                         exit(0);
720                 }
721         }
722
723         argc -= optind;
724         argv += optind;
725         optind = 0;
726
727         if (bnep_init()) {
728                 free(dst);
729                 return -1;
730         }
731
732         /* Check non daemon modes first */
733         switch (mode) {
734         case SHOW:
735                 do_show();
736                 free(dst);
737                 return 0;
738
739         case KILL:
740                 do_kill(dst);
741                 free(dst);
742                 return 0;
743
744         case NONE:
745                 printf(main_help, VERSION);
746                 free(dst);
747                 return 0;
748         }
749
750         /* Initialize signals */
751         memset(&sa, 0, sizeof(sa));
752         sa.sa_flags   = SA_NOCLDSTOP;
753         sa.sa_handler = SIG_IGN;
754         sigaction(SIGCHLD, &sa, NULL);
755         sigaction(SIGPIPE, &sa, NULL);
756
757         sa.sa_handler = sig_hup;
758         sigaction(SIGHUP, &sa, NULL);
759
760         sa.sa_handler = sig_term;
761         sigaction(SIGTERM, &sa, NULL);
762         sigaction(SIGINT,  &sa, NULL);
763
764         if (detach && daemon(0, 0)) {
765                 perror("Can't start daemon");
766                 exit(1);
767         }
768
769         openlog("pand", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
770         syslog(LOG_INFO, "Bluetooth PAN daemon version %s", VERSION);
771
772         if (src) {
773                 src_dev = hci_devid(src);
774                 if (src_dev < 0 || hci_devba(src_dev, &src_addr) < 0) {
775                         syslog(LOG_ERR, "Invalid source. %s(%d)",
776                                                 strerror(errno), errno);
777                         free(dst);
778                         return -1;
779                 }
780         }
781
782         if (pidfile && write_pidfile()) {
783                 free(dst);
784                 return -1;
785         }
786
787         if (dst) {
788                 /* Disable cache invalidation */
789                 use_cache = 0;
790
791                 strncpy(cache.dst, dst, sizeof(cache.dst) - 1);
792                 str2ba(dst, &cache.bdaddr);
793                 cache.valid = 1;
794                 free(dst);
795         }
796
797         switch (mode) {
798         case CONNECT:
799                 do_connect();
800                 break;
801
802         case LISTEN:
803                 do_listen();
804                 break;
805         }
806
807         if (pidfile)
808                 unlink(pidfile);
809
810         return 0;
811 }