xref: /OK3568_Linux_fs/kernel/tools/usb/usbip/src/usbip.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * command structure borrowed from udev
4*4882a593Smuzhiyun  * (git://git.kernel.org/pub/scm/linux/hotplug/udev.git)
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
7*4882a593Smuzhiyun  *               2005-2007 Takahiro Hirofuchi
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <stdio.h>
11*4882a593Smuzhiyun #include <stdlib.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include <getopt.h>
14*4882a593Smuzhiyun #include <syslog.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #include "usbip_common.h"
17*4882a593Smuzhiyun #include "usbip_network.h"
18*4882a593Smuzhiyun #include "usbip.h"
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun static int usbip_help(int argc, char *argv[]);
21*4882a593Smuzhiyun static int usbip_version(int argc, char *argv[]);
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun static const char usbip_version_string[] = PACKAGE_STRING;
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun static const char usbip_usage_string[] =
26*4882a593Smuzhiyun 	"usbip [--debug] [--log] [--tcp-port PORT] [version]\n"
27*4882a593Smuzhiyun 	"             [help] <command> <args>\n";
28*4882a593Smuzhiyun 
usbip_usage(void)29*4882a593Smuzhiyun static void usbip_usage(void)
30*4882a593Smuzhiyun {
31*4882a593Smuzhiyun 	printf("usage: %s", usbip_usage_string);
32*4882a593Smuzhiyun }
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun struct command {
35*4882a593Smuzhiyun 	const char *name;
36*4882a593Smuzhiyun 	int (*fn)(int argc, char *argv[]);
37*4882a593Smuzhiyun 	const char *help;
38*4882a593Smuzhiyun 	void (*usage)(void);
39*4882a593Smuzhiyun };
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun static const struct command cmds[] = {
42*4882a593Smuzhiyun 	{
43*4882a593Smuzhiyun 		.name  = "help",
44*4882a593Smuzhiyun 		.fn    = usbip_help,
45*4882a593Smuzhiyun 		.help  = NULL,
46*4882a593Smuzhiyun 		.usage = NULL
47*4882a593Smuzhiyun 	},
48*4882a593Smuzhiyun 	{
49*4882a593Smuzhiyun 		.name  = "version",
50*4882a593Smuzhiyun 		.fn    = usbip_version,
51*4882a593Smuzhiyun 		.help  = NULL,
52*4882a593Smuzhiyun 		.usage = NULL
53*4882a593Smuzhiyun 	},
54*4882a593Smuzhiyun 	{
55*4882a593Smuzhiyun 		.name  = "attach",
56*4882a593Smuzhiyun 		.fn    = usbip_attach,
57*4882a593Smuzhiyun 		.help  = "Attach a remote USB device",
58*4882a593Smuzhiyun 		.usage = usbip_attach_usage
59*4882a593Smuzhiyun 	},
60*4882a593Smuzhiyun 	{
61*4882a593Smuzhiyun 		.name  = "detach",
62*4882a593Smuzhiyun 		.fn    = usbip_detach,
63*4882a593Smuzhiyun 		.help  = "Detach a remote USB device",
64*4882a593Smuzhiyun 		.usage = usbip_detach_usage
65*4882a593Smuzhiyun 	},
66*4882a593Smuzhiyun 	{
67*4882a593Smuzhiyun 		.name  = "list",
68*4882a593Smuzhiyun 		.fn    = usbip_list,
69*4882a593Smuzhiyun 		.help  = "List exportable or local USB devices",
70*4882a593Smuzhiyun 		.usage = usbip_list_usage
71*4882a593Smuzhiyun 	},
72*4882a593Smuzhiyun 	{
73*4882a593Smuzhiyun 		.name  = "bind",
74*4882a593Smuzhiyun 		.fn    = usbip_bind,
75*4882a593Smuzhiyun 		.help  = "Bind device to " USBIP_HOST_DRV_NAME ".ko",
76*4882a593Smuzhiyun 		.usage = usbip_bind_usage
77*4882a593Smuzhiyun 	},
78*4882a593Smuzhiyun 	{
79*4882a593Smuzhiyun 		.name  = "unbind",
80*4882a593Smuzhiyun 		.fn    = usbip_unbind,
81*4882a593Smuzhiyun 		.help  = "Unbind device from " USBIP_HOST_DRV_NAME ".ko",
82*4882a593Smuzhiyun 		.usage = usbip_unbind_usage
83*4882a593Smuzhiyun 	},
84*4882a593Smuzhiyun 	{
85*4882a593Smuzhiyun 		.name  = "port",
86*4882a593Smuzhiyun 		.fn    = usbip_port_show,
87*4882a593Smuzhiyun 		.help  = "Show imported USB devices",
88*4882a593Smuzhiyun 		.usage = NULL
89*4882a593Smuzhiyun 	},
90*4882a593Smuzhiyun 	{ NULL, NULL, NULL, NULL }
91*4882a593Smuzhiyun };
92*4882a593Smuzhiyun 
usbip_help(int argc,char * argv[])93*4882a593Smuzhiyun static int usbip_help(int argc, char *argv[])
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun 	const struct command *cmd;
96*4882a593Smuzhiyun 	int i;
97*4882a593Smuzhiyun 	int ret = 0;
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	if (argc > 1 && argv++) {
100*4882a593Smuzhiyun 		for (i = 0; cmds[i].name != NULL; i++)
101*4882a593Smuzhiyun 			if (!strcmp(cmds[i].name, argv[0]) && cmds[i].usage) {
102*4882a593Smuzhiyun 				cmds[i].usage();
103*4882a593Smuzhiyun 				goto done;
104*4882a593Smuzhiyun 			}
105*4882a593Smuzhiyun 		ret = -1;
106*4882a593Smuzhiyun 	}
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	usbip_usage();
109*4882a593Smuzhiyun 	printf("\n");
110*4882a593Smuzhiyun 	for (cmd = cmds; cmd->name != NULL; cmd++)
111*4882a593Smuzhiyun 		if (cmd->help != NULL)
112*4882a593Smuzhiyun 			printf("  %-10s %s\n", cmd->name, cmd->help);
113*4882a593Smuzhiyun 	printf("\n");
114*4882a593Smuzhiyun done:
115*4882a593Smuzhiyun 	return ret;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun 
usbip_version(int argc,char * argv[])118*4882a593Smuzhiyun static int usbip_version(int argc, char *argv[])
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun 	(void) argc;
121*4882a593Smuzhiyun 	(void) argv;
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun 	printf(PROGNAME " (%s)\n", usbip_version_string);
124*4882a593Smuzhiyun 	return 0;
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun 
run_command(const struct command * cmd,int argc,char * argv[])127*4882a593Smuzhiyun static int run_command(const struct command *cmd, int argc, char *argv[])
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun 	dbg("running command: `%s'", cmd->name);
130*4882a593Smuzhiyun 	return cmd->fn(argc, argv);
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun 
main(int argc,char * argv[])133*4882a593Smuzhiyun int main(int argc, char *argv[])
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun 	static const struct option opts[] = {
136*4882a593Smuzhiyun 		{ "debug",    no_argument,       NULL, 'd' },
137*4882a593Smuzhiyun 		{ "log",      no_argument,       NULL, 'l' },
138*4882a593Smuzhiyun 		{ "tcp-port", required_argument, NULL, 't' },
139*4882a593Smuzhiyun 		{ NULL,       0,                 NULL,  0  }
140*4882a593Smuzhiyun 	};
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	char *cmd;
143*4882a593Smuzhiyun 	int opt;
144*4882a593Smuzhiyun 	int i, rc = -1;
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	usbip_use_stderr = 1;
147*4882a593Smuzhiyun 	opterr = 0;
148*4882a593Smuzhiyun 	for (;;) {
149*4882a593Smuzhiyun 		opt = getopt_long(argc, argv, "+dlt:", opts, NULL);
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 		if (opt == -1)
152*4882a593Smuzhiyun 			break;
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 		switch (opt) {
155*4882a593Smuzhiyun 		case 'd':
156*4882a593Smuzhiyun 			usbip_use_debug = 1;
157*4882a593Smuzhiyun 			break;
158*4882a593Smuzhiyun 		case 'l':
159*4882a593Smuzhiyun 			usbip_use_syslog = 1;
160*4882a593Smuzhiyun 			openlog("", LOG_PID, LOG_USER);
161*4882a593Smuzhiyun 			break;
162*4882a593Smuzhiyun 		case 't':
163*4882a593Smuzhiyun 			usbip_setup_port_number(optarg);
164*4882a593Smuzhiyun 			break;
165*4882a593Smuzhiyun 		case '?':
166*4882a593Smuzhiyun 			printf("usbip: invalid option\n");
167*4882a593Smuzhiyun 			/* Terminate after printing error */
168*4882a593Smuzhiyun 			/* FALLTHRU */
169*4882a593Smuzhiyun 		default:
170*4882a593Smuzhiyun 			usbip_usage();
171*4882a593Smuzhiyun 			goto out;
172*4882a593Smuzhiyun 		}
173*4882a593Smuzhiyun 	}
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	cmd = argv[optind];
176*4882a593Smuzhiyun 	if (cmd) {
177*4882a593Smuzhiyun 		for (i = 0; cmds[i].name != NULL; i++)
178*4882a593Smuzhiyun 			if (!strcmp(cmds[i].name, cmd)) {
179*4882a593Smuzhiyun 				argc -= optind;
180*4882a593Smuzhiyun 				argv += optind;
181*4882a593Smuzhiyun 				optind = 0;
182*4882a593Smuzhiyun 				rc = run_command(&cmds[i], argc, argv);
183*4882a593Smuzhiyun 				goto out;
184*4882a593Smuzhiyun 			}
185*4882a593Smuzhiyun 	}
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	/* invalid command */
188*4882a593Smuzhiyun 	usbip_help(0, NULL);
189*4882a593Smuzhiyun out:
190*4882a593Smuzhiyun 	return (rc > -1 ? EXIT_SUCCESS : EXIT_FAILURE);
191*4882a593Smuzhiyun }
192