diff options
Diffstat (limited to 'tools/usb/usbip/src/usbip.c')
-rw-r--r-- | tools/usb/usbip/src/usbip.c | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c new file mode 100644 index 000000000..f7c7220d9 --- /dev/null +++ b/tools/usb/usbip/src/usbip.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * command structure borrowed from udev + * (git://git.kernel.org/pub/scm/linux/hotplug/udev.git) + * + * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> + * 2005-2007 Takahiro Hirofuchi + */ + +#include <stdio.h> +#include <stdlib.h> + +#include <getopt.h> +#include <syslog.h> + +#include "usbip_common.h" +#include "usbip_network.h" +#include "usbip.h" + +static int usbip_help(int argc, char *argv[]); +static int usbip_version(int argc, char *argv[]); + +static const char usbip_version_string[] = PACKAGE_STRING; + +static const char usbip_usage_string[] = + "usbip [--debug] [--log] [--tcp-port PORT] [version]\n" + " [help] <command> <args>\n"; + +static void usbip_usage(void) +{ + printf("usage: %s", usbip_usage_string); +} + +struct command { + const char *name; + int (*fn)(int argc, char *argv[]); + const char *help; + void (*usage)(void); +}; + +static const struct command cmds[] = { + { + .name = "help", + .fn = usbip_help, + .help = NULL, + .usage = NULL + }, + { + .name = "version", + .fn = usbip_version, + .help = NULL, + .usage = NULL + }, + { + .name = "attach", + .fn = usbip_attach, + .help = "Attach a remote USB device", + .usage = usbip_attach_usage + }, + { + .name = "detach", + .fn = usbip_detach, + .help = "Detach a remote USB device", + .usage = usbip_detach_usage + }, + { + .name = "list", + .fn = usbip_list, + .help = "List exportable or local USB devices", + .usage = usbip_list_usage + }, + { + .name = "bind", + .fn = usbip_bind, + .help = "Bind device to " USBIP_HOST_DRV_NAME ".ko", + .usage = usbip_bind_usage + }, + { + .name = "unbind", + .fn = usbip_unbind, + .help = "Unbind device from " USBIP_HOST_DRV_NAME ".ko", + .usage = usbip_unbind_usage + }, + { + .name = "port", + .fn = usbip_port_show, + .help = "Show imported USB devices", + .usage = NULL + }, + { NULL, NULL, NULL, NULL } +}; + +static int usbip_help(int argc, char *argv[]) +{ + const struct command *cmd; + int i; + int ret = 0; + + if (argc > 1 && argv++) { + for (i = 0; cmds[i].name != NULL; i++) + if (!strcmp(cmds[i].name, argv[0]) && cmds[i].usage) { + cmds[i].usage(); + goto done; + } + ret = -1; + } + + usbip_usage(); + printf("\n"); + for (cmd = cmds; cmd->name != NULL; cmd++) + if (cmd->help != NULL) + printf(" %-10s %s\n", cmd->name, cmd->help); + printf("\n"); +done: + return ret; +} + +static int usbip_version(int argc, char *argv[]) +{ + (void) argc; + (void) argv; + + printf(PROGNAME " (%s)\n", usbip_version_string); + return 0; +} + +static int run_command(const struct command *cmd, int argc, char *argv[]) +{ + dbg("running command: `%s'", cmd->name); + return cmd->fn(argc, argv); +} + +int main(int argc, char *argv[]) +{ + static const struct option opts[] = { + { "debug", no_argument, NULL, 'd' }, + { "log", no_argument, NULL, 'l' }, + { "tcp-port", required_argument, NULL, 't' }, + { NULL, 0, NULL, 0 } + }; + + char *cmd; + int opt; + int i, rc = -1; + + usbip_use_stderr = 1; + opterr = 0; + for (;;) { + opt = getopt_long(argc, argv, "+dlt:", opts, NULL); + + if (opt == -1) + break; + + switch (opt) { + case 'd': + usbip_use_debug = 1; + break; + case 'l': + usbip_use_syslog = 1; + openlog("", LOG_PID, LOG_USER); + break; + case 't': + usbip_setup_port_number(optarg); + break; + case '?': + printf("usbip: invalid option\n"); + /* Terminate after printing error */ + /* FALLTHRU */ + default: + usbip_usage(); + goto out; + } + } + + cmd = argv[optind]; + if (cmd) { + for (i = 0; cmds[i].name != NULL; i++) + if (!strcmp(cmds[i].name, cmd)) { + argc -= optind; + argv += optind; + optind = 0; + rc = run_command(&cmds[i], argc, argv); + goto out; + } + } + + /* invalid command */ + usbip_help(0, NULL); +out: + return (rc > -1 ? EXIT_SUCCESS : EXIT_FAILURE); +} |