| // 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); | |
| } |