1*1ccea77eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2588b48caSValentina Manea /*
3588b48caSValentina Manea * command structure borrowed from udev
4588b48caSValentina Manea * (git://git.kernel.org/pub/scm/linux/hotplug/udev.git)
5588b48caSValentina Manea *
6588b48caSValentina Manea * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
7588b48caSValentina Manea * 2005-2007 Takahiro Hirofuchi
8588b48caSValentina Manea */
9588b48caSValentina Manea
10588b48caSValentina Manea #include <stdio.h>
11588b48caSValentina Manea #include <stdlib.h>
12588b48caSValentina Manea
13588b48caSValentina Manea #include <getopt.h>
14588b48caSValentina Manea #include <syslog.h>
15588b48caSValentina Manea
16588b48caSValentina Manea #include "usbip_common.h"
17588b48caSValentina Manea #include "usbip_network.h"
18588b48caSValentina Manea #include "usbip.h"
19588b48caSValentina Manea
20588b48caSValentina Manea static int usbip_help(int argc, char *argv[]);
21588b48caSValentina Manea static int usbip_version(int argc, char *argv[]);
22588b48caSValentina Manea
23588b48caSValentina Manea static const char usbip_version_string[] = PACKAGE_STRING;
24588b48caSValentina Manea
25588b48caSValentina Manea static const char usbip_usage_string[] =
26588b48caSValentina Manea "usbip [--debug] [--log] [--tcp-port PORT] [version]\n"
27588b48caSValentina Manea " [help] <command> <args>\n";
28588b48caSValentina Manea
usbip_usage(void)29588b48caSValentina Manea static void usbip_usage(void)
30588b48caSValentina Manea {
31588b48caSValentina Manea printf("usage: %s", usbip_usage_string);
32588b48caSValentina Manea }
33588b48caSValentina Manea
34588b48caSValentina Manea struct command {
35588b48caSValentina Manea const char *name;
36588b48caSValentina Manea int (*fn)(int argc, char *argv[]);
37588b48caSValentina Manea const char *help;
38588b48caSValentina Manea void (*usage)(void);
39588b48caSValentina Manea };
40588b48caSValentina Manea
41588b48caSValentina Manea static const struct command cmds[] = {
42588b48caSValentina Manea {
43588b48caSValentina Manea .name = "help",
44588b48caSValentina Manea .fn = usbip_help,
45588b48caSValentina Manea .help = NULL,
46588b48caSValentina Manea .usage = NULL
47588b48caSValentina Manea },
48588b48caSValentina Manea {
49588b48caSValentina Manea .name = "version",
50588b48caSValentina Manea .fn = usbip_version,
51588b48caSValentina Manea .help = NULL,
52588b48caSValentina Manea .usage = NULL
53588b48caSValentina Manea },
54588b48caSValentina Manea {
55588b48caSValentina Manea .name = "attach",
56588b48caSValentina Manea .fn = usbip_attach,
57588b48caSValentina Manea .help = "Attach a remote USB device",
58588b48caSValentina Manea .usage = usbip_attach_usage
59588b48caSValentina Manea },
60588b48caSValentina Manea {
61588b48caSValentina Manea .name = "detach",
62588b48caSValentina Manea .fn = usbip_detach,
63588b48caSValentina Manea .help = "Detach a remote USB device",
64588b48caSValentina Manea .usage = usbip_detach_usage
65588b48caSValentina Manea },
66588b48caSValentina Manea {
67588b48caSValentina Manea .name = "list",
68588b48caSValentina Manea .fn = usbip_list,
69588b48caSValentina Manea .help = "List exportable or local USB devices",
70588b48caSValentina Manea .usage = usbip_list_usage
71588b48caSValentina Manea },
72588b48caSValentina Manea {
73588b48caSValentina Manea .name = "bind",
74588b48caSValentina Manea .fn = usbip_bind,
75588b48caSValentina Manea .help = "Bind device to " USBIP_HOST_DRV_NAME ".ko",
76588b48caSValentina Manea .usage = usbip_bind_usage
77588b48caSValentina Manea },
78588b48caSValentina Manea {
79588b48caSValentina Manea .name = "unbind",
80588b48caSValentina Manea .fn = usbip_unbind,
81588b48caSValentina Manea .help = "Unbind device from " USBIP_HOST_DRV_NAME ".ko",
82588b48caSValentina Manea .usage = usbip_unbind_usage
83588b48caSValentina Manea },
84588b48caSValentina Manea {
85588b48caSValentina Manea .name = "port",
86588b48caSValentina Manea .fn = usbip_port_show,
87588b48caSValentina Manea .help = "Show imported USB devices",
88588b48caSValentina Manea .usage = NULL
89588b48caSValentina Manea },
90588b48caSValentina Manea { NULL, NULL, NULL, NULL }
91588b48caSValentina Manea };
92588b48caSValentina Manea
usbip_help(int argc,char * argv[])93588b48caSValentina Manea static int usbip_help(int argc, char *argv[])
94588b48caSValentina Manea {
95588b48caSValentina Manea const struct command *cmd;
96588b48caSValentina Manea int i;
97588b48caSValentina Manea int ret = 0;
98588b48caSValentina Manea
99588b48caSValentina Manea if (argc > 1 && argv++) {
100588b48caSValentina Manea for (i = 0; cmds[i].name != NULL; i++)
101588b48caSValentina Manea if (!strcmp(cmds[i].name, argv[0]) && cmds[i].usage) {
102588b48caSValentina Manea cmds[i].usage();
103588b48caSValentina Manea goto done;
104588b48caSValentina Manea }
105588b48caSValentina Manea ret = -1;
106588b48caSValentina Manea }
107588b48caSValentina Manea
108588b48caSValentina Manea usbip_usage();
109588b48caSValentina Manea printf("\n");
110588b48caSValentina Manea for (cmd = cmds; cmd->name != NULL; cmd++)
111588b48caSValentina Manea if (cmd->help != NULL)
112588b48caSValentina Manea printf(" %-10s %s\n", cmd->name, cmd->help);
113588b48caSValentina Manea printf("\n");
114588b48caSValentina Manea done:
115588b48caSValentina Manea return ret;
116588b48caSValentina Manea }
117588b48caSValentina Manea
usbip_version(int argc,char * argv[])118588b48caSValentina Manea static int usbip_version(int argc, char *argv[])
119588b48caSValentina Manea {
120588b48caSValentina Manea (void) argc;
121588b48caSValentina Manea (void) argv;
122588b48caSValentina Manea
123588b48caSValentina Manea printf(PROGNAME " (%s)\n", usbip_version_string);
124588b48caSValentina Manea return 0;
125588b48caSValentina Manea }
126588b48caSValentina Manea
run_command(const struct command * cmd,int argc,char * argv[])127588b48caSValentina Manea static int run_command(const struct command *cmd, int argc, char *argv[])
128588b48caSValentina Manea {
129588b48caSValentina Manea dbg("running command: `%s'", cmd->name);
130588b48caSValentina Manea return cmd->fn(argc, argv);
131588b48caSValentina Manea }
132588b48caSValentina Manea
main(int argc,char * argv[])133588b48caSValentina Manea int main(int argc, char *argv[])
134588b48caSValentina Manea {
135588b48caSValentina Manea static const struct option opts[] = {
136588b48caSValentina Manea { "debug", no_argument, NULL, 'd' },
137588b48caSValentina Manea { "log", no_argument, NULL, 'l' },
138588b48caSValentina Manea { "tcp-port", required_argument, NULL, 't' },
139588b48caSValentina Manea { NULL, 0, NULL, 0 }
140588b48caSValentina Manea };
141588b48caSValentina Manea
142588b48caSValentina Manea char *cmd;
143588b48caSValentina Manea int opt;
144588b48caSValentina Manea int i, rc = -1;
145588b48caSValentina Manea
146588b48caSValentina Manea usbip_use_stderr = 1;
147588b48caSValentina Manea opterr = 0;
148588b48caSValentina Manea for (;;) {
149588b48caSValentina Manea opt = getopt_long(argc, argv, "+dlt:", opts, NULL);
150588b48caSValentina Manea
151588b48caSValentina Manea if (opt == -1)
152588b48caSValentina Manea break;
153588b48caSValentina Manea
154588b48caSValentina Manea switch (opt) {
155588b48caSValentina Manea case 'd':
156588b48caSValentina Manea usbip_use_debug = 1;
157588b48caSValentina Manea break;
158588b48caSValentina Manea case 'l':
159588b48caSValentina Manea usbip_use_syslog = 1;
160588b48caSValentina Manea openlog("", LOG_PID, LOG_USER);
161588b48caSValentina Manea break;
162588b48caSValentina Manea case 't':
163588b48caSValentina Manea usbip_setup_port_number(optarg);
164588b48caSValentina Manea break;
165588b48caSValentina Manea case '?':
166588b48caSValentina Manea printf("usbip: invalid option\n");
167cfd6ed45SJonathan Dieter /* Terminate after printing error */
168cfd6ed45SJonathan Dieter /* FALLTHRU */
169588b48caSValentina Manea default:
170588b48caSValentina Manea usbip_usage();
171588b48caSValentina Manea goto out;
172588b48caSValentina Manea }
173588b48caSValentina Manea }
174588b48caSValentina Manea
175588b48caSValentina Manea cmd = argv[optind];
176588b48caSValentina Manea if (cmd) {
177588b48caSValentina Manea for (i = 0; cmds[i].name != NULL; i++)
178588b48caSValentina Manea if (!strcmp(cmds[i].name, cmd)) {
179588b48caSValentina Manea argc -= optind;
180588b48caSValentina Manea argv += optind;
181588b48caSValentina Manea optind = 0;
182588b48caSValentina Manea rc = run_command(&cmds[i], argc, argv);
183588b48caSValentina Manea goto out;
184588b48caSValentina Manea }
185588b48caSValentina Manea }
186588b48caSValentina Manea
187588b48caSValentina Manea /* invalid command */
188588b48caSValentina Manea usbip_help(0, NULL);
189588b48caSValentina Manea out:
190588b48caSValentina Manea return (rc > -1 ? EXIT_SUCCESS : EXIT_FAILURE);
191588b48caSValentina Manea }
192