wusbadm.c revision ff0e937b36dcde1a47ff7b00aa76a491c0dc07a8
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <stdio.h>
#include <stdarg.h>
#include <locale.h>
#include <dirent.h>
#include <fcntl.h>
#include <door.h>
#include <errno.h>
#include <getopt.h>
#include <assert.h>
#include "crypto_util.h"
#include "wusbd.h"
/*
* EXIT STATUS
* The following exit values are returned:
* 0 Successful operation
* 1 Error: the operation failed.
* 2 Usage error.
*/
#define WUSB_EXIT_SUCCESS 0
#define WUSB_EXIT_FAILURE 1
#define WUSB_EXIT_USAGE 2
#define ASSO_CABLE_NAME "wusb_ca"
#define WUSB_MAX_LEN 255
#define WUSB_HOSTID_LEN 2
#define WUSB_DEVID_LEN 6
/* wusba admin list options */
#define WUSB_FIELD_WIDTH 20
#define WUSB_LIST_HOST 0x01
#define WUSB_LIST_DEV 0x02
#define WUSB_LIST_ID 0x04
#define WUSB_LIST_TYPE 0x08
#define WUSB_LIST_STATE 0x10
/* cable device list */
typedef struct dev_list {
char path[MAXPATHLEN];
} dev_list_t;
/* log and debug helpers */
static void wusb_prt(const char *, ...);
static void wusb_usage(const char *, ...);
static void wusb_fail(const char *, ...);
static void wusb_opterr(int, int);
static void wusb_free_list(wusb_device_info_t *);
/* door call helpers */
static int wusb_door_req(int, door_arg_t *, char *, int);
static void wusb_door_free(door_arg_t *);
/* check auths */
static void wusb_check_auth(const char *);
/* usr input funcs */
static void user_confirm(char *);
static void user_input(char *, char *, int);
/* string translation helpers */
static void usage();
/* list */
static const struct option wusb_list_opts[] = {
{0, 0, 0, 0}
};
static const char *WUSB_LIST_HEADER[] = {
"ID", /* host-id or dev-id */
"STATE", /* host or device states */
"TYPE", /* host or deivce types */
};
static void do_list(int, char **);
static void do_list_args(int, char **, char *);
static void parse_subopts(char *, const char *);
static int parse_option(char *, const char *);
static void wusb_prt_titles(char);
static void wusb_prt_lists(char, wusb_device_info_t *);
static void parse_dev_id(const char *, wusb_dev_ctrl_t *);
static void parse_host_id(char *, uint8_t *);
/* associate */
static struct option wusb_asso_opts[] = {
{ 0, 0, 0, 0}
};
static void do_associate(int, char **);
static void do_asso_args(int, char **, wusb_asso_ctrl_t *);
static int input_host_id(uint8_t *);
static void input_dev_id(wusb_dev_ctrl_t *);
#ifdef NUMERIC_ENABLED
static int input_asso_type(uint8_t *);
#endif
static int select_cable_device(char *);
/* remove dev */
static struct option wusb_rmdev_opts[] = {
{ 0, 0, 0, 0}
};
static struct option wusb_host_opts[] = {
{ 0, 0, 0, 0}
};
static void do_host(int, char **, int);
static void do_host_args(int, char **, int, wusb_dev_ctrl_t *);
static void do_remove_host(int, char **);
static void do_enable_host(int, char **);
static void do_disable_host(int, char **);
static void do_remove_dev(int, char **);
static void do_remove_dev_args(int, char **, wusb_dev_ctrl_t *);
/* error message maps */
struct errormsgs {
int code;
char *errmsg;
} wusb_errors[] = {
{ WUSBADM_OK, "success" },
{ WUSBADM_AUTH_FAILURE, "permisson denied" },
{ WUSBADM_NO_HOST, "host does not exist" },
{ WUSBADM_NO_DEVICE, "device does not exist" },
{ WUSBADM_CCSTORE_ACC, "fail to access CC store" },
{ WUSBADM_NO_SUPPORT, "command not supported" },
{ WUSBADM_INVAL_HOSTID, "invalid host id" },
{ WUSBADM_INVAL_DEVID, "invalid device id" },
{ WUSBADM_HOST_NOT_ATTACH, "host not attached" },
{ WUSBADM_FAILURE, "unknown error"}
};
char *
wusb_strerror(int err)
{
}
}
/*
* wusbadm cmd line tool is used for used to administrate the wireless usb
* host and wireless usb devices.
* list - List the device and host status
* associated - Setup assocaition between host and devices.
* remove-dev - Remove the assocation of device
* remove-host - Remove the host information and all the devices assocaiton to
* the host
* enable-host - Enable a host to be ready to accept wireless devices
* disable-host - Disable a host, host will not accpet connections
*/
int
{
int i;
static struct {
const char *cmd;
void (*func)(int, char **);
const char *auth;
} cmd_list[] = {
};
#ifndef TEXT_DOMAIN
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
if (argc <= 1) {
usage();
}
/* start wusb damemon */
(void) daemonize();
}
/* wusbadm entry */
break;
}
}
}
return (WUSB_EXIT_SUCCESS);
}
static void
usage()
{
wusb_prt("\nUsage:\twusbadm sub-command args ...\n\n");
wusb_prt("\tlist [-h | -d] [-o field[,...]]\n");
wusb_prt("\tassociate [-h host-id] [[-c [-f]] | -n] [-o]\n");
wusb_prt("\tremove-dev [[-d dev-id] | [-h host-id]] [-f]\n");
wusb_prt("\tremove-host [-h host-id] [-f]\n");
wusb_prt("\tenable-host [-h host-id]\n");
wusb_prt("\tdisable-host [-h host-id] [-f]\n");
wusb_prt("\n");
}
/*
* list command routine.
* wusbadmin list [-h | -d] [-o field[,...]]
* 1. parse the options
* 3. print titles accoding to list options
*/
static void
{
char fields = 0x0;
int i;
/* parse the list options */
/* print list title */
/* print out the result */
for (i = 0; i < cnt; i++) {
}
}
/*
* associate command routine
* wusbadmin associate [-h host-id] [[-c [-f] | -n] [-o]
* 1. Parse the options and get user input
* 2. Send the asso infor the daemon
*/
static void
{
/* Get association options */
/* open door file */
(char *)&asso_ctrl, sizeof (wusb_asso_ctrl_t));
/* association result */
wusb_door_free(&da);
if (rval != WUSBADM_OK) {
}
}
/*
* remove-dev command routine
* remove-dev [[-d dev-id] | [-h host-id]] [-f]
* 2. send message to daemon.
* dev-id != 0 means remove one dev
* dev-id == 0 means remove all dev with a host
*/
static void
{
/* parse options */
/* send command to daemon */
(char *)&devctrl, sizeof (wusb_dev_ctrl_t));
wusb_door_free(&da);
if (rval != WUSBADM_OK) {
}
}
/*
* Send the LOAD_CC request to daemon. Daemon will allocate memory and put
* all CCs in that block of memory. We need to free the memory here.
* CCs are in data array format.
*/
static void
{
/* send command to daemon */
if (rval != WUSBADM_OK) {
wusb_door_free(&da);
}
/* number of the devinfo list */
if (num) {
wusb_door_free(&da);
wusb_fail("list: malloc buffer failed");
}
buflen);
}
/* unmap the buffer */
wusb_door_free(&da);
}
static void
{
if (cc_list) {
}
cnt = 0;
}
/*
* This is a wrapper of door call for wusb adm tool.
* Mandatory:
* cmd - wusb admin command (WUSB_DCMD_*).
* da - door call arg.
* Optional:
* databuf - data send to daemon.
* size - data buf size.
*/
static int
{
int fd = -1;
/* copy data buffer */
if (databuf) {
}
/* set rbuf to 0, unmap the data buf later */
/* open door file */
wusb_fail("daemon not started");
}
/* make door call */
}
wusb_fail("no data from daemon");
}
return (WUSBA_SUCCESS);
}
/*
* After each door call return, the first 2 bytes of the data
* returned is encoded as the door call result from daemon.
* This is a wrapper to get the door call result
*/
return (rval);
}
/*
* Unmap the buffer after door call.
* It is mandatory after any wusb_door_call since we set the rbuf to NULL
* in the wusb_door_call. So any buffer returned is from the client proces.
* See door_call(3C) for more infor
*/
static void
{
}
/*
* wusbadmin remove-host routine
* remove-host [-h host-id] [-f]
*/
static void
{
}
/*
* wusbadmin enable-host routine
* enable-host [-h host-id]
*/
static void
{
}
/*
* wusbadmin disable-host routine
* disable-host [-h host-id] [-f]
*/
static void
{
}
/*
* wusb do host routine. The wrapper for all host related
* subcommand (enable-host, disable-host, remove-host).
* 2. send wusb command to daemon
*/
static void
{
/* parse options */
/* door call to daemon */
(char *)&hostctrl, sizeof (wusb_dev_ctrl_t));
wusb_door_free(&da);
if (rval != WUSBADM_OK) {
}
}
/*
* wusb list option parser
* wusbadmin list [-h | -d] [-o field[,...]]
*/
static void
{
char fields = 0x0;
int c;
switch (c) {
case 'h':
if (fields & WUSB_LIST_HOST) {
wusb_usage("too many -h specified");
}
if (fields & WUSB_LIST_DEV) {
wusb_usage("-h and -d used together");
}
fields |= WUSB_LIST_HOST;
break;
case 'd':
if (fields & WUSB_LIST_HOST) {
wusb_usage("-h and -d used together");
}
if (fields & WUSB_LIST_DEV) {
wusb_usage("too many -d specified");
}
fields |= WUSB_LIST_DEV;
break;
case 'o':
wusb_usage("options too long");
}
break;
default:
wusb_opterr(optopt, c);
break;
}
}
}
/* if no option specified,print out all fields */
}
/*
* Print the header for list subcommand.
* Each title is right aligned with length of WUSB_FIELD_WIDTH
* The following titles will be printed if the relative tags
* marked in the fields option.
* ID STATE TYPE
*/
static void
wusb_prt_titles(char fields)
{
int i = 0;
char option;
for (option = WUSB_LIST_ID;
option <<= 1, i++) {
WUSB_LIST_HEADER[i]);
}
}
(void) putchar('\n');
}
/*
* Append the host-id / dev-id to the output buf.
* host-id - 2 digits number (XX)
* dev-id - 5 digits number (XX.XXX)
* See wusbadm (1M) for more
*/
static void
{
} else {
}
}
/*
* Append state to the output buf.
* device - connected/disconnected
* See wusbadm (1M) for more
*/
static void
{
const char *WUSB_DEV_STATE_MSG[] = {
"disconnected", /* WUSB_STATE_UNCONNTED */
"connected", /* WUSB_STATE_CONNTING */
"connected", /* WUSB_STATE_UNAUTHENTICATED */
"connected", /* WUSB_STATE_DEFAULT */
"connected", /* WUSB_STATE_ADDRESSED */
"connected", /* WUSB_STATE_CONFIGURED */
"connected", /* WUSB_STATE_SLEEPING */
"connected", /* WUSB_STATE_RECONNTING */
};
const char *WUSB_HOST_STATE_MSG[] = {
"disconnected", /* WUSB_HC_DISCONNTED */
"disabled", /* WUSB_HC_STOPPED */
"enabled", /* WUSB_HC_STARTED */
"disabled", /* WUSB_HC_CH_STOPPED */
};
/* append the state for device */
} else {
}
} else {
/* append the state for host */
} else {
}
}
}
/*
* Currently map the file name to specific types
* TODO: how to define the type
*/
static void
{
}
/*
* This is core func to print wireless device list on systems.
* Print the devinfo list entry with option field
*/
static void
{
int i = 0;
char opt = 0;
void (*append_funcs[])(char *, wusb_device_info_t *) = {
};
/* check if dev or host need to be print out */
return;
}
/* Append all the enabled fields to the output buf */
for (i = 0, opt = WUSB_LIST_ID;
opt <= WUSB_LIST_STATE;
opt <<= 1, i++) {
}
}
}
/*
* wusb association option parser
* wusbadmin association [-h host-id] [[-c [-f] | -n] [-o]
* Note:Only cable association is supported now
*/
static void
{
int c;
int force = 0;
!= -1) {
switch (c) {
case 'h':
break;
case 'c':
break;
case 'n':
break;
case 'f':
force = 1;
break;
case 'o':
break;
default:
wusb_opterr(optopt, c);
break;
}
}
}
/* TODO: support cable association */
wusb_fail("Numeric association not supported");
}
/* get user input host id */
}
/* get user input association type */
/* Todo: Will be enabled after Numberic Assocation support */
#ifdef NUMERIC_ENABLED
#endif
}
/* get user input cable device to associate */
}
/* confirm with user to continue or not */
if (!force) {
wusb_prt("Associate device (%s) with host (%02d) via cable\n",
user_confirm("Continue ");
}
}
/*
* Convert a string to an id (host-id/dev-id/cable-dev-id)
* Fail if 0 returned, since each id is indexed from 1.
* Widely used to handle user input ids.
*/
static uint32_t
{
/* check the string and generate int result */
while (*arg) {
return (0);
}
arg++;
}
return (id);
}
static void
wusb_fail("host-id should be 2 digits");
}
}
if (find_dev_id(*host, 0) < 0) {
}
return;
}
/*
* Get the host from user input.
* 1. list all the host id from the daemon
* 2. Ask user to input the host id
* 3. Check host id and return
*/
static int
{
int i = 0;
/* show avaialbe host id to usr */
for (i = 0; i < cnt; i++) {
}
/* get user input of host id */
return (WUSBA_SUCCESS);
}
static void
{
int i = 0;
/* show avaialbe host id to usr */
for (i = 0; i < cnt; i++) {
}
/* get user input of host id */
}
static int
{
int rval = WUSBA_FAILURE;
int i;
for (i = 0; i < cnt; i++) {
break;
}
}
return (rval);
}
/*
* Select assocation type.
* - Cable
* - Numeric Not supported
*/
#ifdef NUMERIC_ENABLED
static int
{
} else {
wusb_usage("invalid association type");
}
return (WUSBA_SUCCESS);
}
#endif
/*
* Create a list contains all the cable devices on the system
*/
static void
{
*num = 0;
/*
* to see if it is a cable asso filename and add it to the devinfo
* list if so
*/
if (!dirp) {
wusb_fail("cable device not available");
}
/* searching for cable node */
continue;
}
/* add the filename to the dev list */
} else {
}
/* this need to be freed */
"%s", filename);
/* increase the list number */
(*num)++;
}
}
/* Free the devlist created for cable device */
static void
{
while (head) {
}
}
/* find the cable dev with the user-inputed index */
static dev_list_t *
{
int i = 1;
i++;
}
return (dev_list);
}
/* print the cable devlist with index */
static void
{
/* show all the cable devices to user */
int index = 1;
wusb_prt("Cable devices on the system:\n");
while (dev_list) {
index++;
}
}
/*
* when doing association, all the cable devices on the system
* should be print out to the user
*/
static int
select_cable_device(char *device)
{
/* cable association */
char buf[32];
int cableid = 1;
int devnum = 0;
/* get all the cable dev on the system */
/* Get the device name as user input */
if (!head) {
wusb_fail("no cable devices found ");
}
if (devnum != 1) {
/* get the user input of the cable dev index */
wusb_fail("cable device id should be 3 digits");
}
/* check user iput */
wusb_fail("invalid cable device ");
}
} else {
/* if only one dev exist, use it without asking user */
cableid = 1;
}
/* find the device to associate */
/* free the list */
return (WUSBA_SUCCESS);
}
/*
* Parse the -o option for wusbadm list
*/
static int
{
}
}
return (WUSBA_SUCCESS);
}
/*
* wusbadmin list
* parse the sub option extracted from -o options
*/
static void
{
int i;
char opt;
break;
}
}
if (opt > WUSB_LIST_STATE) {
}
}
/*
* Device id parser for remove-dev
* dev id is 5 digits with format XX.XXX
*/
void
{
/* get host id */
*tmp = '\0';
goto fail;
}
/* get device id */
goto fail;
}
wusb_fail("dev-id does not exist: %02d.%03d ",
}
return;
fail:
}
/*
* remove-dev options parser
* remove-dev [[-d dev-id] | [-h host-id]] [-f]
*/
static void
{
int c;
int force = 0;
switch (c) {
case 'h':
wusb_usage("-h -d can not be"
"used together");
}
wusb_usage("multi -h is not allowed");
}
/* get 2 digit host id */
break;
case 'd':
wusb_usage("multi -d is not allowed");
}
wusb_usage("-h -d can not be"
"used together");
}
/* parse devid */
break;
case 'f':
force = 1;
break;
default:
wusb_opterr(optopt, c);
break;
}
}
}
}
/* confirm with user to continue or not */
if (!force) {
wusb_prt("Remove the device's association information"
" of device (%02d.%03d) from system.\nThis device"
" can not be connected with the host until it is"
" associated again.\n",
} else {
wusb_prt("Remove the information of all the devices "
"associated with host (%02d) from the system\n"
"All the devices asociated with the host can not"
" be connected with it until they are associated"
}
user_confirm("Continue ");
}
}
/*
* Confirm with user continue or not
* info: the information shown to user before input
*/
static void
user_confirm(char *info)
{
char yesorno[20];
wusb_fail("");
}
wusb_fail("");
}
return;
}
return;
}
}
/*
* Get user input
* msg(in): infor shown to user before input
* length(in): buf size to save uer input
* buf(out): user input saved in buffer
*/
static void
{
int i = 0, b;
/*CONSTCOND*/
while (1) {
if (i < length)
buf[i] = 0;
break;
}
if (i < length)
buf[i] = b;
i++;
}
if (i >= length) {
}
}
/*
* do host options parser
* remove-host [-h host-id] [-f]
* enable-host [-h host-id]
* disable-host [-h host-id] [-f]
*/
static void
{
int c;
int force = 0;
switch (c) {
case 'h':
wusb_usage("multi -h is not allowed");
}
/* 2 digits host id */
break;
case 'f':
/* enable host does not need -f */
if (cmd == WUSB_DCMD_ENABLE_HOST) {
wusb_opterr(optopt, c);
}
force = 1;
break;
default:
wusb_opterr(optopt, c);
break;
}
}
}
/*
* all the host related command can be used without a specific
* host-id, so list all the hosts avalable to users for selection
*/
}
/* confirm with user to continue or not */
switch (cmd) {
case WUSB_DCMD_DISABLE_HOST:
wusb_prt("Disable host (%02d).\nAll the"
" devices connected with the host will be"
break;
case WUSB_DCMD_REMOVE_HOST:
wusb_prt("Remove host (%02d).\nAll the"
" association with the host will be"
break;
default:
break;
}
user_confirm("Continue");
}
}
static void
wusb_check_auth(const char *auth) {
}
}
/*
* wusb exit helper funcstion
* wusb_fail or wusb_usage
*/
static void
{
}
static void
wusb_usage(const char *format, ...)
{
usage();
}
/* wusb print helper func */
static void
{
}
/* wusb option failuer func */
static void
{
switch (opterr) {
case ':':
break;
case '?':
default:
break;
}
}