Path: blob/main/usr.sbin/bluetooth/sdpcontrol/sdpcontrol.c
103478 views
/*-1* sdpcontrol.c2*3* SPDX-License-Identifier: BSD-2-Clause4*5* Copyright (c) 2001-2003 Maksim Yevmenkin <[email protected]>6* All rights reserved.7*8* Redistribution and use in source and binary forms, with or without9* modification, are permitted provided that the following conditions10* are met:11* 1. Redistributions of source code must retain the above copyright12* notice, this list of conditions and the following disclaimer.13* 2. Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in the15* documentation and/or other materials provided with the distribution.16*17* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND18* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE21* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL22* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS23* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)24* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT25* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY26* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF27* SUCH DAMAGE.28*29* $Id: sdpcontrol.c,v 1.1 2003/09/08 02:27:27 max Exp $30*/3132#include <assert.h>33#define L2CAP_SOCKET_CHECKED34#include <bluetooth.h>35#include <err.h>36#include <errno.h>37#include <sdp.h>38#include <stdio.h>39#include <stdlib.h>40#include <string.h>41#include <unistd.h>42#include "sdpcontrol.h"4344/* Prototypes */45static int do_sdp_command (bdaddr_p, char const *, int,46int, char **);47static struct sdp_command * find_sdp_command (char const *,48struct sdp_command *);49static void print_sdp_command (struct sdp_command *);50static void usage (void);5152/* Main */53int54main(int argc, char *argv[])55{56char const *control = SDP_LOCAL_PATH;57int n, local;58bdaddr_t bdaddr;5960memset(&bdaddr, 0, sizeof(bdaddr));61local = 0;6263/* Process command line arguments */64while ((n = getopt(argc, argv, "a:c:lh")) != -1) {65switch (n) {66case 'a': /* bdaddr */67if (!bt_aton(optarg, &bdaddr)) {68struct hostent *he = NULL;6970if ((he = bt_gethostbyname(optarg)) == NULL)71errx(1, "%s: %s", optarg, hstrerror(h_errno));7273memcpy(&bdaddr, he->h_addr, sizeof(bdaddr));74}75break;7677case 'c': /* control socket */78control = optarg;79break;8081case 'l': /* local sdpd */82local = 1;83break;8485case 'h':86default:87usage();88/* NOT REACHED */89}90}9192argc -= optind;93argv += optind;9495if (*argv == NULL)96usage();9798return (do_sdp_command(&bdaddr, control, local, argc, argv));99}100101/* Execute commands */102static int103do_sdp_command(bdaddr_p bdaddr, char const *control, int local,104int argc, char **argv)105{106char *cmd = argv[0];107struct sdp_command *c = NULL;108void *xs = NULL;109int e, help;110111help = 0;112if (strcasecmp(cmd, "help") == 0) {113argc --;114argv ++;115116if (argc <= 0) {117fprintf(stdout, "Supported commands:\n");118print_sdp_command(sdp_commands);119fprintf(stdout, "\nFor more information use " \120"'help command'\n");121122return (OK);123}124125help = 1;126cmd = argv[0];127}128129c = find_sdp_command(cmd, sdp_commands);130if (c == NULL) {131fprintf(stdout, "Unknown command: \"%s\"\n", cmd);132return (ERROR);133}134135if (!help) {136if (!local) {137if (memcmp(bdaddr, NG_HCI_BDADDR_ANY, sizeof(*bdaddr)) == 0)138usage();139140xs = sdp_open(NG_HCI_BDADDR_ANY, bdaddr);141} else142xs = sdp_open_local(control);143144if (xs == NULL)145errx(1, "Could not create SDP session object");146if (sdp_error(xs) == 0)147e = (c->handler)(xs, -- argc, ++ argv);148else149e = ERROR;150} else151e = USAGE;152153switch (e) {154case OK:155case FAILED:156break;157158case ERROR:159fprintf(stdout, "Could not execute command \"%s\". %s\n",160cmd, strerror(sdp_error(xs)));161break;162163case USAGE:164fprintf(stdout, "Usage: %s\n%s\n", c->command, c->description);165break;166167default: assert(0); break;168}169170sdp_close(xs);171172return (e);173} /* do_sdp_command */174175/* Try to find command in specified category */176static struct sdp_command *177find_sdp_command(char const *command, struct sdp_command *category)178{179struct sdp_command *c = NULL;180181for (c = category; c->command != NULL; c++) {182char *c_end = strchr(c->command, ' ');183184if (c_end != NULL) {185int len = c_end - c->command;186187if (strncasecmp(command, c->command, len) == 0)188return (c);189} else if (strcasecmp(command, c->command) == 0)190return (c);191}192193return (NULL);194} /* find_sdp_command */195196/* Print commands in specified category */197static void198print_sdp_command(struct sdp_command *category)199{200struct sdp_command *c = NULL;201202for (c = category; c->command != NULL; c++)203fprintf(stdout, "\t%s\n", c->command);204} /* print_sdp_command */205206/* Usage */207static void208usage(void)209{210fprintf(stderr,211"Usage: sdpcontrol options command\n" \212"Where options are:\n"213" -a address address to connect to\n" \214" -c path path to the control socket (default is %s)\n" \215" -h display usage and quit\n" \216" -l connect to the local SDP server via control socket\n" \217" command one of the supported commands\n", SDP_LOCAL_PATH);218exit(255);219} /* usage */220221222223